llvm.org GIT mirror llvm / 30b21c3
[MemDep] DBG intrinsics don't impact abort limit for call site dependence analysis Summary: Memory dependence analysis no longer counts DbgInfoIntrinsics towards the limit where to abort the analysis. Before, a bunch of calls to dbg.value could affect the generated code, meaning that with -g we could generate different code than without. Reviewers: chandlerc, Prazek, davide, efriedma Reviewed By: efriedma Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39181 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316551 91177308-0d34-0410-b5e6-96231b3b80d8 Mikael Holmen 1 year, 10 months ago
2 changed file(s) with 77 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
195195
196196 // Walk backwards through the block, looking for dependencies.
197197 while (ScanIt != BB->begin()) {
198 Instruction *Inst = &*--ScanIt;
199 // Debug intrinsics don't cause dependences and should not affect Limit
200 if (isa(Inst))
201 continue;
202
198203 // Limit the amount of scanning we do so we don't end up with quadratic
199204 // running time on extreme testcases.
200205 --Limit;
201206 if (!Limit)
202207 return MemDepResult::getUnknown();
203
204 Instruction *Inst = &*--ScanIt;
205208
206209 // If this inst is a memory op, get the pointer it accessed
207210 MemoryLocation Loc;
214217 }
215218
216219 if (auto InstCS = CallSite(Inst)) {
217 // Debug intrinsics don't cause dependences.
218 if (isa(Inst))
219 continue;
220220 // If these two calls do not interfere, look past it.
221221 switch (AA.getModRefInfo(CS, InstCS)) {
222222 case MRI_NoModRef:
0 ; RUN: opt -S -dse -memdep-block-scan-limit=3 < %s | FileCheck %s
1 ; RUN: opt -S -strip-debug -dse -memdep-block-scan-limit=3 < %s | FileCheck %s
2
3 ; Test case to check that the memory dependency analysis gets the same
4 ; result even if we have a dbg value between the memcpy and
5 ; store. The memory dependency is then used by DSE to remove the store.
6
7 ; We use -memdep-block-scan-limit=3 to be able to create a small test case.
8 ; Without it, we would need to squeeze in 100 instructions since the default
9 ; limit is 100.
10
11 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
12 target triple = "x86_64-unknown-linux-gnu"
13
14 @g = common global [1 x i8] zeroinitializer, align 1, !dbg !0
15
16 ; Function Attrs: noinline nounwind uwtable
17 define void @foo() #0 !dbg !14 {
18 entry:
19 %i = alloca i8, align 1
20 store i8 1, i8* %i, align 1, !dbg !19
21 call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !17, metadata !DIExpression()), !dbg !18
22 %0 = bitcast [1 x i8]* @g to i8*
23 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %i, i8* %0, i64 1, i32 1, i1 false), !dbg !20
24 br label %bb2
25
26 bb2: ; preds = %0
27 ret void, !dbg !21
28 }
29
30 ; Function Attrs: nounwind readnone speculatable
31 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #1
32
33 ; Function Attrs: argmemonly nounwind
34 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1) #2
35
36 attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
37 attributes #1 = { nounwind readnone speculatable }
38 attributes #2 = { argmemonly nounwind }
39
40 !llvm.dbg.cu = !{!2}
41 !llvm.module.flags = !{!10, !11, !12}
42 !llvm.ident = !{!13}
43
44 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
45 !1 = distinct !DIGlobalVariable(name: "g", scope: !2, file: !3, line: 3, type: !6, isLocal: false, isDefinition: true)
46 !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 6.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5)
47 !3 = !DIFile(filename: "foo.c", directory: "/bar")
48 !4 = !{}
49 !5 = !{!0}
50 !6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 8, elements: !8)
51 !7 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
52 !8 = !{!9}
53 !9 = !DISubrange(count: 1)
54 !10 = !{i32 2, !"Dwarf Version", i32 4}
55 !11 = !{i32 2, !"Debug Info Version", i32 3}
56 !12 = !{i32 1, !"wchar_size", i32 4}
57 !13 = !{!"clang version 6.0.0"}
58 !14 = distinct !DISubprogram(name: "foo", scope: !3, file: !3, line: 5, type: !15, isLocal: false, isDefinition: true, scopeLine: 6, isOptimized: false, unit: !2, variables: !4)
59 !15 = !DISubroutineType(types: !16)
60 !16 = !{null}
61 !17 = !DILocalVariable(name: "i", scope: !14, file: !3, line: 7, type: !7)
62 !18 = !DILocation(line: 7, column: 10, scope: !14)
63 !19 = !DILocation(line: 8, column: 7, scope: !14)
64 !20 = !DILocation(line: 9, column: 5, scope: !14)
65 !21 = !DILocation(line: 10, column: 1, scope: !14)
66
67 ; Check that the store is removed and that the memcpy is still there
68 ; CHECK-LABEL: foo
69 ; CHECK-NOT: store i8
70 ; CHECK: call void @llvm.memcpy
71 ; CHECK: ret void