OSDN Git Service

[DebugInfo] Avoid register coalesing unsoundly changing DBG_VALUE locations
[android-x86/external-llvm.git] / test / DebugInfo / MIR / X86 / regcoalescing-clears-dead-dbgvals.mir
1 # RUN: llc %s -o - -run-pass=simple-register-coalescing | FileCheck %s
2 # PR40010: DBG_VALUEs do not contribute to the liveness of virtual registers,
3 # and the register coalescer would merge new live values on top of DBG_VALUEs,
4 # leading to them presenting new (wrong) values to the debugger. Test that
5 # when out of liveness, coalescing will mark DBG_VALUEs in non-live locations
6 # as undef.
7 --- |
8   ; ModuleID = './test.ll'
9   source_filename = "./test.ll"
10   target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
11
12   ; Function Attrs: nounwind readnone speculatable
13   declare void @llvm.dbg.value(metadata, metadata, metadata) #0
14
15   ; Original IR source here:
16   define i32 @test(i32* %pin) {
17   entry:
18     br label %start.test1
19
20   start.test1:                                       ; preds = %start, %entry
21     %foo = phi i32 [ 0, %entry ], [ %bar, %start.test1 ]
22     %baz = load i32, i32* %pin, align 1
23     %qux = xor i32 %baz, 1234
24     %bar = add i32 %qux, %foo
25     call void @llvm.dbg.value(metadata i32 %foo, metadata !3, metadata !DIExpression()), !dbg !5
26     %cmp = icmp ugt i32 %bar, 1000000
27     br i1 %cmp, label %leave, label %start.test1
28
29   leave:                                            ; preds = %start
30     ret i32 %bar
31   }
32
33   ; Stubs to appease the MIR parser
34   define i32 @test2(i32* %pin) {
35   entry:
36     ret i32 0
37   start.test2:
38     ret i32 0
39   leave:
40     ret i32 0
41   }
42
43   define i32 @test3(i32* %pin) {
44   entry:
45     ret i32 0
46   start.test3:
47     ret i32 0
48   leave:
49     ret i32 0
50   }
51
52   define i32 @test4(i32* %pin) {
53   entry:
54     ret i32 0
55   start.test4:
56     ret i32 0
57   leave:
58     ret i32 0
59   }
60
61   ; Function Attrs: nounwind
62   declare void @llvm.stackprotector(i8*, i8**) #1
63
64   attributes #0 = { nounwind readnone speculatable }
65   attributes #1 = { nounwind }
66
67   !llvm.module.flags = !{!0}
68   !llvm.dbg.cu = !{!1}
69
70   !0 = !{i32 2, !"Debug Info Version", i32 3}
71   !1 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !2, producer: "beards", isOptimized: true, runtimeVersion: 4, emissionKind: FullDebug)
72   !2 = !DIFile(filename: "bees.cpp", directory: "")
73   !3 = !DILocalVariable(name: "bees", scope: !4)
74   !4 = distinct !DISubprogram(name: "nope", scope: !1, file: !2, line: 1, spFlags: DISPFlagDefinition, unit: !1)
75   !5 = !DILocation(line: 0, scope: !4)
76
77 ...
78 ---
79 name:            test
80 tracksRegLiveness: true
81 body:             |
82   bb.0.entry:
83     successors: %bb.1(0x80000000)
84     liveins: $rdi
85
86     %2:gr64 = COPY killed $rdi
87     %3:gr32 = MOV32r0 implicit-def dead $eflags
88     %4:gr32 = MOV32ri 1234
89     %7:gr32 = COPY killed %3
90
91   bb.1.start.test1:
92     successors: %bb.2(0x04000000), %bb.1(0x7c000000)
93
94     ; CHECK-LABEL: name: test
95     ;
96     ; We currently expect %1 and %0 to merge into %7
97     ;
98     ; CHECK: %[[REG1:[0-9]+]]:gr32 = MOV32rm
99     ; CHECK-NEXT: %[[REG2:[0-9]+]]:gr32 = XOR32rr %[[REG1]]
100     ; CHECK-NEXT: %[[REG3:[0-9]+]]:gr32 = ADD32rr %[[REG3]], %[[REG2]]
101     ; CHECK-NEXT: DBG_VALUE $noreg
102
103     %0:gr32 = COPY killed %7
104     %8:gr32 = MOV32rm %2, 1, $noreg, 0, $noreg :: (load 4 from %ir.pin, align 1)
105     %5:gr32 = COPY killed %8
106     %5:gr32 = XOR32rr %5, %4, implicit-def dead $eflags
107     %1:gr32 = COPY killed %0
108     %1:gr32 = ADD32rr %1, killed %5, implicit-def dead $eflags
109     DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
110     CMP32ri %1, 1000001, implicit-def $eflags
111     %7:gr32 = COPY %1
112     JCC_1 %bb.1, 2, implicit killed $eflags
113     JMP_1 %bb.2
114
115   bb.2.leave:
116     $eax = COPY killed %1
117     RET 0, killed $eax
118
119 ...
120 ---
121 name:            test2
122 tracksRegLiveness: true
123 body:             |
124   bb.0.entry:
125     successors: %bb.1(0x80000000)
126     liveins: $rdi
127
128     %2:gr64 = COPY killed $rdi
129     %3:gr32 = MOV32r0 implicit-def dead $eflags
130     %4:gr32 = MOV32ri 1234
131     %7:gr32 = COPY killed %3
132
133   bb.1.start.test2:
134     successors: %bb.2(0x04000000), %bb.1(0x7c000000)
135
136     ; CHECK-LABEL: name: test2
137     ;
138     ; %0 should be merged into %7, but as %0 is live at this location the
139     ; DBG_VALUE should be preserved and point at the operand of ADD32rr.
140     ;
141     ; CHECK: %[[REG11:[0-9]+]]:gr32 = MOV32rm
142     ; CHECK-NEXT: %[[REG12:[0-9]+]]:gr32 = XOR32rr %[[REG11]]
143     ; CHECK-NEXT: DBG_VALUE %[[REG13:[0-9]+]]
144     ; CHECK-NEXT: %[[REG13]]:gr32 = ADD32rr %[[REG13]], %[[REG12]]
145
146     %0:gr32 = COPY killed %7
147     %8:gr32 = MOV32rm %2, 1, $noreg, 0, $noreg :: (load 4 from %ir.pin, align 1)
148     %5:gr32 = COPY killed %8
149     %5:gr32 = XOR32rr %5, %4, implicit-def dead $eflags
150     DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
151     %1:gr32 = COPY killed %0
152     %1:gr32 = ADD32rr %1, killed %5, implicit-def dead $eflags
153     CMP32ri %1, 1000001, implicit-def $eflags
154     %7:gr32 = COPY %1
155     JCC_1 %bb.1, 2, implicit killed $eflags
156     JMP_1 %bb.2
157
158   bb.2.leave:
159     $eax = COPY killed %1
160     RET 0, killed $eax
161
162 ...
163 ---
164 name:            test3
165 tracksRegLiveness: true
166 body:             |
167   bb.0.entry:
168     successors: %bb.1(0x80000000)
169     liveins: $rdi
170
171     %2:gr64 = COPY killed $rdi
172     %3:gr32 = MOV32r0 implicit-def dead $eflags
173     %4:gr32 = MOV32ri 1234
174     %7:gr32 = COPY killed %3
175
176   bb.1.start.test3:
177     successors: %bb.2(0x04000000), %bb.1(0x7c000000)
178
179     ; CHECK-LABEL: name: test3
180     ;
181     ; This is a use-before-def, merging new registers into %0 could unsoundly
182     ; make it live again, on merge mark it undef.
183     ;
184     ; CHECK: DBG_VALUE $noreg
185
186     DBG_VALUE %0, $noreg, !3, !DIExpression(), debug-location !5
187     %0:gr32 = COPY killed %7
188     %8:gr32 = MOV32rm %2, 1, $noreg, 0, $noreg :: (load 4 from %ir.pin, align 1)
189     %5:gr32 = COPY killed %8
190     %5:gr32 = XOR32rr %5, %4, implicit-def dead $eflags
191     %1:gr32 = COPY killed %0
192     %1:gr32 = ADD32rr %1, killed %5, implicit-def dead $eflags
193     CMP32ri %1, 1000001, implicit-def $eflags
194     %7:gr32 = COPY %1
195     JCC_1 %bb.1, 2, implicit killed $eflags
196     JMP_1 %bb.2
197
198   bb.2.leave:
199     $eax = COPY killed %1
200     RET 0, killed $eax
201
202 ...
203 ---
204 name:            test4
205 tracksRegLiveness: true
206 body:             |
207   bb.0.entry:
208     successors: %bb.1(0x80000000)
209     liveins: $rdi
210
211     %2:gr64 = COPY killed $rdi
212     %3:gr32 = MOV32r0 implicit-def dead $eflags
213     %4:gr32 = MOV32ri 1234
214     %7:gr32 = COPY killed %3
215
216   bb.1.start.test4:
217     successors: %bb.2(0x04000000), %bb.1(0x7c000000)
218
219     ; CHECK-LABEL: name: test4
220     ;
221     ; Using a dead register, even if we coalesce it to the right value, should
222     ; be marked undef. The coalescer can't prove it's correct without
223     ; considering control flow in the general case.
224     ;
225     ; CHECK: DBG_VALUE $noreg
226
227     %0:gr32 = COPY killed %7
228     DBG_VALUE %7, $noreg, !3, !DIExpression(), debug-location !5
229     %8:gr32 = MOV32rm %2, 1, $noreg, 0, $noreg :: (load 4 from %ir.pin, align 1)
230     %5:gr32 = COPY killed %8
231     %5:gr32 = XOR32rr %5, %4, implicit-def dead $eflags
232     %1:gr32 = COPY killed %0
233     %1:gr32 = ADD32rr %1, killed %5, implicit-def dead $eflags
234     CMP32ri %1, 1000001, implicit-def $eflags
235     %7:gr32 = COPY %1
236     JCC_1 %bb.1, 2, implicit killed $eflags
237     JMP_1 %bb.2
238
239   bb.2.leave:
240     $eax = COPY killed %1
241     RET 0, killed $eax
242
243 ...