[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / X86 / flags-copy-lowering.mir
blobf8bf3837bdae90ff3c105f4fa1db4b425a49184b
1 # RUN: llc -run-pass x86-flags-copy-lowering -verify-machineinstrs -o - %s | FileCheck %s
3 # Lower various interesting copy patterns of EFLAGS without using LAHF/SAHF.
5 --- |
6   target triple = "x86_64-unknown-unknown"
7   
8   declare void @foo()
9   
10   define i32 @test_branch(i64 %a, i64 %b) {
11   entry:
12     call void @foo()
13     ret i32 0
14   }
16   define i32 @test_branch_fallthrough(i64 %a, i64 %b) {
17   entry:
18     call void @foo()
19     ret i32 0
20   }
22   define void @test_setcc(i64 %a, i64 %b) {
23   entry:
24     call void @foo()
25     ret void
26   }
28   define void @test_cmov(i64 %a, i64 %b) {
29   entry:
30     call void @foo()
31     ret void
32   }
34   define void @test_adc(i64 %a, i64 %b) {
35   entry:
36     call void @foo()
37     ret void
38   }
40   define void @test_sbb(i64 %a, i64 %b) {
41   entry:
42     call void @foo()
43     ret void
44   }
46   define void @test_adcx(i64 %a, i64 %b) {
47   entry:
48     call void @foo()
49     ret void
50   }
52   define void @test_adox(i64 %a, i64 %b) {
53   entry:
54     call void @foo()
55     ret void
56   }
58   define void @test_rcl(i64 %a, i64 %b) {
59   entry:
60     call void @foo()
61     ret void
62   }
64   define void @test_rcr(i64 %a, i64 %b) {
65   entry:
66     call void @foo()
67     ret void
68   }
70   define void @test_setb_c(i64 %a, i64 %b) {
71   entry:
72     call void @foo()
73     ret void
74   }
76   define i64 @test_branch_with_livein_and_kill(i64 %a, i64 %b) {
77   entry:
78     call void @foo()
79     ret i64 0
80   }
82   define i64 @test_branch_with_interleaved_livein_and_kill(i64 %a, i64 %b) {
83   entry:
84     call void @foo()
85     ret i64 0
86   }
88   define i64 @test_mid_cycle_copies(i64 %a, i64 %b) {
89   entry:
90     call void @foo()
91     ret i64 0
92   }
94   define i32 @test_existing_setcc(i64 %a, i64 %b) {
95   entry:
96     call void @foo()
97     ret i32 0
98   }
100   define i32 @test_existing_setcc_memory(i64 %a, i64 %b) {
101   entry:
102     call void @foo()
103     ret i32 0
104   }
107 name:            test_branch
108 # CHECK-LABEL: name: test_branch
109 liveins:         
110   - { reg: '$rdi', virtual-reg: '%0' }
111   - { reg: '$rsi', virtual-reg: '%1' }
112 body:             |
113   bb.0:
114     successors: %bb.1, %bb.2, %bb.3
115     liveins: $rdi, $rsi
116   
117     %0:gr64 = COPY $rdi
118     %1:gr64 = COPY $rsi
119     CMP64rr %0, %1, implicit-def $eflags
120     %2:gr64 = COPY $eflags
121   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
122   ; CHECK:      %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
123   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
124   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
126     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
127     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
128     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
130     $eflags = COPY %2
131     JCC_1 %bb.1, 7, implicit $eflags
132     JCC_1 %bb.2, 2, implicit $eflags
133     JMP_1 %bb.3
134   ; CHECK-NOT: $eflags =
135   ;
136   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
137   ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
138   ; CHECK-SAME: {{$[[:space:]]}}
139   ; CHECK-NEXT: bb.4:
140   ; CHECK-NEXT:   successors: {{.*$}}
141   ; CHECK-SAME: {{$[[:space:]]}}
142   ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
143   ; CHECK-NEXT:   JCC_1 %bb.2, 5, implicit killed $eflags
144   ; CHECK-NEXT:   JMP_1 %bb.3
145   
146   bb.1:
147     %3:gr32 = MOV32ri 42
148     $eax = COPY %3
149     RET 0, $eax
150   
151   bb.2:
152     %4:gr32 = MOV32ri 43
153     $eax = COPY %4
154     RET 0, $eax
155   
156   bb.3:
157     %5:gr32 = MOV32r0 implicit-def dead $eflags
158     $eax = COPY %5
159     RET 0, $eax
163 name:            test_branch_fallthrough
164 # CHECK-LABEL: name: test_branch_fallthrough
165 liveins:         
166   - { reg: '$rdi', virtual-reg: '%0' }
167   - { reg: '$rsi', virtual-reg: '%1' }
168 body:             |
169   bb.0:
170     successors: %bb.1, %bb.2, %bb.3
171     liveins: $rdi, $rsi
172   
173     %0:gr64 = COPY $rdi
174     %1:gr64 = COPY $rsi
175     CMP64rr %0, %1, implicit-def $eflags
176     %2:gr64 = COPY $eflags
177   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
178   ; CHECK:      %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
179   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
180   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
182     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
183     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
184     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
186     $eflags = COPY %2
187     JCC_1 %bb.2, 7, implicit $eflags
188     JCC_1 %bb.3, 2, implicit $eflags
189   ; CHECK-NOT: $eflags =
190   ;
191   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
192   ; CHECK-NEXT:   JCC_1 %bb.2, 5, implicit killed $eflags
193   ; CHECK-SAME: {{$[[:space:]]}}
194   ; CHECK-NEXT: bb.4:
195   ; CHECK-NEXT:   successors: {{.*$}}
196   ; CHECK-SAME: {{$[[:space:]]}}
197   ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
198   ; CHECK-NEXT:   JCC_1 %bb.3, 5, implicit killed $eflags
199   ; CHECK-SAME: {{$[[:space:]]}}
200   ; CHECK-NEXT:   bb.1:
202   bb.1:
203     %5:gr32 = MOV32r0 implicit-def dead $eflags
204     $eax = COPY %5
205     RET 0, $eax
206   
207   bb.2:
208     %3:gr32 = MOV32ri 42
209     $eax = COPY %3
210     RET 0, $eax
211   
212   bb.3:
213     %4:gr32 = MOV32ri 43
214     $eax = COPY %4
215     RET 0, $eax
216   
219 name:            test_setcc
220 # CHECK-LABEL: name: test_setcc
221 liveins:         
222   - { reg: '$rdi', virtual-reg: '%0' }
223   - { reg: '$rsi', virtual-reg: '%1' }
224 body:             |
225   bb.0:
226     liveins: $rdi, $rsi
227   
228     %0:gr64 = COPY $rdi
229     %1:gr64 = COPY $rsi
230     CMP64rr %0, %1, implicit-def $eflags
231     %2:gr64 = COPY $eflags
232   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
233   ; CHECK:      %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
234   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
235   ; CHECK-NEXT: %[[E_REG:[^:]*]]:gr8 = SETCCr 4, implicit $eflags
236   ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETCCr 5, implicit $eflags
237   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
239     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
240     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
241     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
243     $eflags = COPY %2
244     %3:gr8 = SETCCr 7, implicit $eflags
245     %4:gr8 = SETCCr 2, implicit $eflags
246     %5:gr8 = SETCCr 4, implicit $eflags
247     SETCCm $rsp, 1, $noreg, -16, $noreg, 5, implicit killed $eflags
248     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %3
249     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %4
250     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %5
251   ; CHECK-NOT:     $eflags =
252   ; CHECK-NOT:             = SET{{.*}}
253   ; CHECK:         MOV8mr {{.*}}, killed %[[A_REG]]
254   ; CHECK-NEXT:    MOV8mr {{.*}}, killed %[[B_REG]]
255   ; CHECK-NEXT:    MOV8mr {{.*}}, killed %[[E_REG]]
256   ; CHECK-NOT:     MOV8mr {{.*}}, killed %[[NE_REG]]
258     RET 0
262 name:            test_cmov
263 # CHECK-LABEL: name: test_cmov
264 liveins:         
265   - { reg: '$rdi', virtual-reg: '%0' }
266   - { reg: '$rsi', virtual-reg: '%1' }
267 body:             |
268   bb.0:
269     liveins: $rdi, $rsi
270   
271     %0:gr64 = COPY $rdi
272     %1:gr64 = COPY $rsi
273     CMP64rr %0, %1, implicit-def $eflags
274     %2:gr64 = COPY $eflags
275   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
276   ; CHECK:      %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
277   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
278   ; CHECK-NEXT: %[[E_REG:[^:]*]]:gr8 = SETCCr 4, implicit $eflags
279   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
281     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
282     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
283     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
285     $eflags = COPY %2
286     %3:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
287     %4:gr64 = CMOV64rr %0, %1, 2, implicit $eflags
288     %5:gr64 = CMOV64rr %0, %1, 4, implicit $eflags
289     %6:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
290   ; CHECK-NOT:     $eflags =
291   ; CHECK:         TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
292   ; CHECK-NEXT:    %3:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
293   ; CHECK-NEXT:    TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
294   ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
295   ; CHECK-NEXT:    TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
296   ; CHECK-NEXT:    %5:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
297   ; CHECK-NEXT:    TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
298   ; CHECK-NEXT:    %6:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
299     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3
300     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
301     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
302     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %6
304     RET 0
308 name:            test_adc
309 # CHECK-LABEL: name: test_adc
310 liveins:         
311   - { reg: '$rdi', virtual-reg: '%0' }
312   - { reg: '$rsi', virtual-reg: '%1' }
313 body:             |
314   bb.0:
315     liveins: $rdi, $rsi
316   
317     %0:gr64 = COPY $rdi
318     %1:gr64 = COPY $rsi
319     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
320     %3:gr64 = COPY $eflags
321   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
322   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
323   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
325     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
326     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
327     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
329     $eflags = COPY %3
330     %4:gr64 = ADC64ri32 %2:gr64, 42, implicit-def $eflags, implicit $eflags
331     %5:gr64 = ADC64ri32 %4:gr64, 42, implicit-def $eflags, implicit $eflags
332   ; CHECK-NOT:     $eflags =
333   ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
334   ; CHECK-NEXT:    %4:gr64 = ADC64ri32 %2, 42, implicit-def $eflags, implicit killed $eflags
335   ; CHECK-NEXT:    %5:gr64 = ADC64ri32 %4, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
336     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
338     RET 0
342 name:            test_sbb
343 # CHECK-LABEL: name: test_sbb
344 liveins:         
345   - { reg: '$rdi', virtual-reg: '%0' }
346   - { reg: '$rsi', virtual-reg: '%1' }
347 body:             |
348   bb.0:
349     liveins: $rdi, $rsi
350   
351     %0:gr64 = COPY $rdi
352     %1:gr64 = COPY $rsi
353     %2:gr64 = SUB64rr %0, %1, implicit-def $eflags
354     %3:gr64 = COPY killed $eflags
355   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
356   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
357   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
359     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
360     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
361     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
363     $eflags = COPY %3
364     %4:gr64 = SBB64ri32 %2:gr64, 42, implicit-def $eflags, implicit killed $eflags
365     %5:gr64 = SBB64ri32 %4:gr64, 42, implicit-def dead $eflags, implicit killed $eflags
366   ; CHECK-NOT:     $eflags =
367   ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
368   ; CHECK-NEXT:    %4:gr64 = SBB64ri32 %2, 42, implicit-def $eflags, implicit killed $eflags
369   ; CHECK-NEXT:    %5:gr64 = SBB64ri32 %4, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
370     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
372     RET 0
376 name:            test_adcx
377 # CHECK-LABEL: name: test_adcx
378 liveins:         
379   - { reg: '$rdi', virtual-reg: '%0' }
380   - { reg: '$rsi', virtual-reg: '%1' }
381 body:             |
382   bb.0:
383     liveins: $rdi, $rsi
384   
385     %0:gr64 = COPY $rdi
386     %1:gr64 = COPY $rsi
387     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
388     %3:gr64 = COPY $eflags
389   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
390   ; CHECK:        %[[E_REG:[^:]*]]:gr8 = SETCCr 4, implicit $eflags
391   ; CHECK-NEXT:   %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
392   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
394     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
395     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
396     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
398     $eflags = COPY %3
399     %4:gr64 = CMOV64rr %0, %1, 4, implicit $eflags
400     %5:gr64 = MOV64ri32 42
401     %6:gr64 = ADCX64rr %2, %5, implicit-def $eflags, implicit $eflags
402   ; CHECK-NOT:     $eflags =
403   ; CHECK:         TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
404   ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
405   ; CHECK-NEXT:    %5:gr64 = MOV64ri32 42
406   ; CHECK-NEXT:    dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
407   ; CHECK-NEXT:    %6:gr64 = ADCX64rr %2, %5, implicit-def{{( dead)?}} $eflags, implicit killed $eflags
408     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
409     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %6
411     RET 0
415 name:            test_adox
416 # CHECK-LABEL: name: test_adox
417 liveins:         
418   - { reg: '$rdi', virtual-reg: '%0' }
419   - { reg: '$rsi', virtual-reg: '%1' }
420 body:             |
421   bb.0:
422     liveins: $rdi, $rsi
423   
424     %0:gr64 = COPY $rdi
425     %1:gr64 = COPY $rsi
426     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
427     %3:gr64 = COPY $eflags
428   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
429   ; CHECK:        %[[E_REG:[^:]*]]:gr8 = SETCCr 4, implicit $eflags
430   ; CHECK-NEXT:   %[[OF_REG:[^:]*]]:gr8 = SETCCr 0, implicit $eflags
431   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
433     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
434     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
435     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
437     $eflags = COPY %3
438     %4:gr64 = CMOV64rr %0, %1, 4, implicit $eflags
439     %5:gr64 = MOV64ri32 42
440     %6:gr64 = ADOX64rr %2, %5, implicit-def $eflags, implicit $eflags
441   ; CHECK-NOT:     $eflags =
442   ; CHECK:         TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
443   ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
444   ; CHECK-NEXT:    %5:gr64 = MOV64ri32 42
445   ; CHECK-NEXT:    dead %{{[^:]*}}:gr8 = ADD8ri %[[OF_REG]], 127, implicit-def $eflags
446   ; CHECK-NEXT:    %6:gr64 = ADOX64rr %2, %5, implicit-def{{( dead)?}} $eflags, implicit killed $eflags
447     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
448     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %6
450     RET 0
454 name:            test_rcl
455 # CHECK-LABEL: name: test_rcl
456 liveins:         
457   - { reg: '$rdi', virtual-reg: '%0' }
458   - { reg: '$rsi', virtual-reg: '%1' }
459 body:             |
460   bb.0:
461     liveins: $rdi, $rsi
462   
463     %0:gr64 = COPY $rdi
464     %1:gr64 = COPY $rsi
465     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
466     %3:gr64 = COPY $eflags
467   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
468   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
469   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
471     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
472     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
473     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
475     $eflags = COPY %3
476     %4:gr64 = RCL64r1 %2:gr64, implicit-def $eflags, implicit $eflags
477     %5:gr64 = RCL64r1 %4:gr64, implicit-def $eflags, implicit $eflags
478   ; CHECK-NOT:     $eflags =
479   ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
480   ; CHECK-NEXT:    %4:gr64 = RCL64r1 %2, implicit-def $eflags, implicit killed $eflags
481   ; CHECK-NEXT:    %5:gr64 = RCL64r1 %4, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
482     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
484     RET 0
488 name:            test_rcr
489 # CHECK-LABEL: name: test_rcr
490 liveins:         
491   - { reg: '$rdi', virtual-reg: '%0' }
492   - { reg: '$rsi', virtual-reg: '%1' }
493 body:             |
494   bb.0:
495     liveins: $rdi, $rsi
496   
497     %0:gr64 = COPY $rdi
498     %1:gr64 = COPY $rsi
499     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
500     %3:gr64 = COPY $eflags
501   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
502   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
503   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
505     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
506     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
507     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
509     $eflags = COPY %3
510     %4:gr64 = RCR64r1 %2:gr64, implicit-def $eflags, implicit $eflags
511     %5:gr64 = RCR64r1 %4:gr64, implicit-def $eflags, implicit $eflags
512   ; CHECK-NOT:     $eflags =
513   ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
514   ; CHECK-NEXT:    %4:gr64 = RCR64r1 %2, implicit-def $eflags, implicit killed $eflags
515   ; CHECK-NEXT:    %5:gr64 = RCR64r1 %4, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
516     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
518     RET 0
522 name:            test_setb_c
523 # CHECK-LABEL: name: test_setb_c
524 liveins:
525   - { reg: '$rdi', virtual-reg: '%0' }
526   - { reg: '$rsi', virtual-reg: '%1' }
527 body:             |
528   bb.0:
529     liveins: $rdi, $rsi
531     %0:gr64 = COPY $rdi
532     %1:gr64 = COPY $rsi
533     %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
534     %3:gr64 = COPY $eflags
535   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
536   ; CHECK:      %[[CF_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
537   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
539     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
540     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
541     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
543     $eflags = COPY %3
544     %4:gr8 = SETB_C8r implicit-def $eflags, implicit $eflags
545     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %4
546   ; CHECK-NOT:     $eflags =
547   ; CHECK:         %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
548   ; CHECK-NEXT:    %[[ZERO_SUBREG:[^:]*]]:gr8 = COPY %[[ZERO]].sub_8bit
549   ; CHECK-NEXT:    %[[REPLACEMENT:[^:]*]]:gr8 = SUB8rr %[[ZERO_SUBREG]], %[[CF_REG]]
550   ; CHECK-NEXT:    MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
552     $eflags = COPY %3
553     %5:gr16 = SETB_C16r implicit-def $eflags, implicit $eflags
554     MOV16mr $rsp, 1, $noreg, -16, $noreg, killed %5
555   ; CHECK-NOT:     $eflags =
556   ; CHECK:         %[[CF_EXT:[^:]*]]:gr32 = MOVZX32rr8 %[[CF_REG]]
557   ; CHECK-NEXT:    %[[CF_TRUNC:[^:]*]]:gr16 = COPY %[[CF_EXT]].sub_16bit
558   ; CHECK-NEXT:    %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
559   ; CHECK-NEXT:    %[[ZERO_SUBREG:[^:]*]]:gr16 = COPY %[[ZERO]].sub_16bit
560   ; CHECK-NEXT:    %[[REPLACEMENT:[^:]*]]:gr16 = SUB16rr %[[ZERO_SUBREG]], %[[CF_TRUNC]]
561   ; CHECK-NEXT:    MOV16mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
563     $eflags = COPY %3
564     %6:gr32 = SETB_C32r implicit-def $eflags, implicit $eflags
565     MOV32mr $rsp, 1, $noreg, -16, $noreg, killed %6
566   ; CHECK-NOT:     $eflags =
567   ; CHECK:         %[[CF_EXT:[^:]*]]:gr32 = MOVZX32rr8 %[[CF_REG]]
568   ; CHECK-NEXT:    %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
569   ; CHECK-NEXT:    %[[REPLACEMENT:[^:]*]]:gr32 = SUB32rr %[[ZERO]], %[[CF_EXT]]
570   ; CHECK-NEXT:    MOV32mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
572     $eflags = COPY %3
573     %7:gr64 = SETB_C64r implicit-def $eflags, implicit $eflags
574     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %7
575   ; CHECK-NOT:     $eflags =
576   ; CHECK:         %[[CF_EXT1:[^:]*]]:gr32 = MOVZX32rr8 %[[CF_REG]]
577   ; CHECK-NEXT:    %[[CF_EXT2:[^:]*]]:gr64 = SUBREG_TO_REG 0, %[[CF_EXT1]], %subreg.sub_32bit
578   ; CHECK-NEXT:    %[[ZERO:[^:]*]]:gr32 = MOV32r0 implicit-def $eflags
579   ; CHECK-NEXT:    %[[ZERO_EXT:[^:]*]]:gr64 = SUBREG_TO_REG 0, %[[ZERO]], %subreg.sub_32bit
580   ; CHECK-NEXT:    %[[REPLACEMENT:[^:]*]]:gr64 = SUB64rr %[[ZERO_EXT]], %[[CF_EXT2]]
581   ; CHECK-NEXT:    MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %[[REPLACEMENT]]
583     RET 0
587 name:            test_branch_with_livein_and_kill
588 # CHECK-LABEL: name: test_branch_with_livein_and_kill
589 liveins:
590   - { reg: '$rdi', virtual-reg: '%0' }
591   - { reg: '$rsi', virtual-reg: '%1' }
592 body:             |
593   bb.0:
594     successors: %bb.1, %bb.2, %bb.3
595     liveins: $rdi, $rsi
597     %0:gr64 = COPY $rdi
598     %1:gr64 = COPY $rsi
599     CMP64rr %0, %1, implicit-def $eflags
600     %2:gr64 = COPY $eflags
601   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
602   ; CHECK:      %[[S_REG:[^:]*]]:gr8 = SETCCr 8, implicit $eflags
603   ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETCCr 5, implicit $eflags
604   ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
605   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
606   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
608     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
609     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
610     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
612     $eflags = COPY %2
613     JCC_1 %bb.1, 7, implicit $eflags
614     JCC_1 %bb.2, 2, implicit $eflags
615     JMP_1 %bb.3
616   ; CHECK-NOT: $eflags =
617   ;
618   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
619   ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
620   ; CHECK-SAME: {{$[[:space:]]}}
621   ; CHECK-NEXT: bb.4:
622   ; CHECK-NEXT:   successors: {{.*$}}
623   ; CHECK-SAME: {{$[[:space:]]}}
624   ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
625   ; CHECK-NEXT:   JCC_1 %bb.2, 5, implicit killed $eflags
626   ; CHECK-NEXT:   JMP_1 %bb.3
628   bb.1:
629     liveins: $eflags
631     %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
632   ; CHECK-NOT:     $eflags =
633   ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
634   ; CHECK-NEXT:    %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
635     $rax = COPY %3
636     RET 0, $rax
638   bb.2:
639     liveins: $eflags
641     %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
642   ; CHECK-NOT:     $eflags =
643   ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
644   ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
645     $rax = COPY %4
646     RET 0, $rax
648   bb.3:
649     liveins: $eflags
651     %5:gr64 = CMOV64rr %0, %1, 8, implicit killed $eflags
652   ; CHECK-NOT:     $eflags =
653   ; CHECK:         TEST8rr %[[S_REG]], %[[S_REG]], implicit-def $eflags
654   ; CHECK-NEXT:    %5:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
655     $rax = COPY %5
656     RET 0, $rax
660 name:            test_branch_with_interleaved_livein_and_kill
661 # CHECK-LABEL: name: test_branch_with_interleaved_livein_and_kill
662 liveins:
663   - { reg: '$rdi', virtual-reg: '%0' }
664   - { reg: '$rsi', virtual-reg: '%1' }
665 body:             |
666   bb.0:
667     successors: %bb.1, %bb.2, %bb.5
668     liveins: $rdi, $rsi
670     %0:gr64 = COPY $rdi
671     %1:gr64 = COPY $rsi
672     CMP64rr %0, %1, implicit-def $eflags
673     %2:gr64 = COPY $eflags
674   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
675   ; CHECK:      %[[S_REG:[^:]*]]:gr8 = SETCCr 8, implicit $eflags
676   ; CHECK-NEXT: %[[P_REG:[^:]*]]:gr8 = SETCCr 10, implicit $eflags
677   ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETCCr 5, implicit $eflags
678   ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
679   ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
680   ; CHECK-NEXT: %[[O_REG:[^:]*]]:gr8 = SETCCr 0, implicit $eflags
681   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
683     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
684     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
685     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
687     $eflags = COPY %2
688     JCC_1 %bb.1, 7, implicit $eflags
689     JCC_1 %bb.2, 2, implicit $eflags
690     JMP_1 %bb.5
691   ; CHECK-NOT: $eflags =
692   ;
693   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
694   ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
695   ; CHECK-SAME: {{$[[:space:]]}}
696   ; CHECK-NEXT: bb.6:
697   ; CHECK-NEXT:   successors: {{.*$}}
698   ; CHECK-SAME: {{$[[:space:]]}}
699   ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
700   ; CHECK-NEXT:   JCC_1 %bb.2, 5, implicit killed $eflags
701   ; CHECK-NEXT:   JMP_1 %bb.5
703   bb.1:
704     liveins: $eflags
706     %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
707   ; CHECK-NOT:     $eflags =
708   ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
709   ; CHECK-NEXT:    %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
710     $rax = COPY %3
711     RET 0, $rax
713   bb.2:
714     ; The goal is to have another batch of successors discovered in a block
715     ; between two successors which kill $eflags. This ensures that neither of
716     ; the surrounding kills impact recursing through this block.
717     successors: %bb.3, %bb.4
718     liveins: $eflags
720     JCC_1 %bb.3, 0, implicit $eflags
721     JMP_1 %bb.4
722   ; CHECK-NOT: $eflags =
723   ;
724   ; CHECK:        TEST8rr %[[O_REG]], %[[O_REG]], implicit-def $eflags
725   ; CHECK-NEXT:   JCC_1 %bb.3, 5, implicit killed $eflags
726   ; CHECK-NEXT:   JMP_1 %bb.4
728   bb.3:
729     liveins: $eflags
731     %4:gr64 = CMOV64rr %0, %1, 5, implicit $eflags
732   ; CHECK-NOT:     $eflags =
733   ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
734   ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
735     $rax = COPY %4
736     RET 0, $rax
738   bb.4:
739     liveins: $eflags
741     %5:gr64 = CMOV64rr %0, %1, 10, implicit $eflags
742   ; CHECK-NOT:     $eflags =
743   ; CHECK:         TEST8rr %[[P_REG]], %[[P_REG]], implicit-def $eflags
744   ; CHECK-NEXT:    %5:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
745     $rax = COPY %5
746     RET 0, $rax
748   bb.5:
749     liveins: $eflags
751     %6:gr64 = CMOV64rr %0, %1, 8, implicit killed $eflags
752   ; CHECK-NOT:     $eflags =
753   ; CHECK:         TEST8rr %[[S_REG]], %[[S_REG]], implicit-def $eflags
754   ; CHECK-NEXT:    %6:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
755     $rax = COPY %6
756     RET 0, $rax
760 # This test case is designed to exercise a particularly challenging situation:
761 # when the flags are copied and restored *inside* of a complex and cyclic CFG
762 # all of which have live-in flags. To correctly handle this case we have to walk
763 # up the dominator tree and locate a viable reaching definition location,
764 # checking for clobbers along any path. The CFG for this function looks like the
765 # following diagram, control flowing out the bottom of blocks and in the top:
767 #  bb.0
768 #   | __________________
769 #   |/                  \
770 #  bb.1                  |
771 #   |\_________          |
772 #   | __       \ ____    |
773 #   |/  \      |/    \   |
774 #  bb.2  |    bb.4    |  |
775 #   |\__/     / \     |  |
776 #   |        /   \    |  |
777 #  bb.3    bb.5  bb.6 |  |
778 #   |        \   /    |  |
779 #   |         \ /     |  |
780 #   |         bb.7    |  |
781 #   | ________/ \____/   |
782 #   |/                   |
783 #  bb.8                  |
784 #   |\__________________/
785 #   |
786 #  bb.9
788 # We set EFLAGS in bb.0, clobber them in bb.3, and copy them in bb.2 and bb.6.
789 # Because of the cycles this requires hoisting the `SETcc` instructions to
790 # capture the flags for the bb.6 copy to bb.1 and using them for the copy in
791 # `bb.2` as well despite the clobber in `bb.3`. The clobber in `bb.3` also
792 # prevents hoisting the `SETcc`s up to `bb.0`.
794 # Throughout the test we use branch instructions that are totally bogus (as the
795 # flags are obviously not changing!) but this is just to allow us to send
796 # a small but complex CFG structure through the backend and force it to choose
797 # plausible lowering decisions based on the core CFG presented, regardless of
798 # the futility of the actual branches.
799 name:            test_mid_cycle_copies
800 # CHECK-LABEL: name: test_mid_cycle_copies
801 liveins:
802   - { reg: '$rdi', virtual-reg: '%0' }
803   - { reg: '$rsi', virtual-reg: '%1' }
804 body:             |
805   bb.0:
806     successors: %bb.1
807     liveins: $rdi, $rsi
809     %0:gr64 = COPY $rdi
810     %1:gr64 = COPY $rsi
811     CMP64rr %0, %1, implicit-def $eflags
812   ; CHECK:      bb.0:
813   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
814   ; CHECK:        CMP64rr %0, %1, implicit-def $eflags
815   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
816     JMP_1 %bb.1
818   bb.1:
819     successors: %bb.2, %bb.4
820     liveins: $eflags
822     ; Outer loop header, target for one set of hoisting.
823     JCC_1 %bb.2, 4, implicit $eflags
824     JMP_1 %bb.4
825   ; CHECK:      bb.1:
826   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
827   ; CHECK:        %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
828   ; CHECK-NEXT:   %[[E_REG:[^:]*]]:gr8 = SETCCr 4, implicit $eflags
829   ; CHECK-NEXT:   %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
830   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
832   bb.2:
833     successors: %bb.2, %bb.3
834     liveins: $eflags
836     ; Inner loop with a local copy. We should eliminate this but can't hoist.
837     %2:gr64 = COPY $eflags
838     $eflags = COPY %2
839     JCC_1 %bb.2, 4, implicit $eflags
840     JMP_1 %bb.3
841   ; CHECK:      bb.2:
842   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
843   ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
844   ; CHECK-NEXT:   JCC_1 %bb.2, 5, implicit killed $eflags
845   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
847   bb.3:
848     successors: %bb.8
849     liveins: $eflags
851     ; Use and then clobber $eflags. Then hop to the outer loop latch.
852     %3:gr64 = ADC64ri32 %0, 42, implicit-def dead $eflags, implicit $eflags
853   ; CHECK:      bb.3:
854   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
855   ; CHECK:        dead %{{[^:]*}}:gr8 = ADD8ri %[[B_REG]], 255, implicit-def $eflags
856   ; CHECK-NEXT:   %3:gr64 = ADC64ri32 %0, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
857   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
858     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3
859     JMP_1 %bb.8
861   bb.4:
862     successors: %bb.5, %bb.6
863     liveins: $eflags
865     ; Another inner loop, this one with a diamond.
866     JCC_1 %bb.5, 4, implicit $eflags
867     JMP_1 %bb.6
868   ; CHECK:      bb.4:
869   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
870   ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
871   ; CHECK-NEXT:   JCC_1 %bb.5, 5, implicit killed $eflags
872   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
874   bb.5:
875     successors: %bb.7
876     liveins: $eflags
878     ; Just use $eflags on this side of the diamond.
879     %4:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
880   ; CHECK:      bb.5:
881   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
882   ; CHECK:         TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
883   ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
884   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
885     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
886     JMP_1 %bb.7
888   bb.6:
889     successors: %bb.7
890     liveins: $eflags
892     ; Use, copy, and then use $eflags again.
893     %5:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
894   ; CHECK:      bb.6:
895   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
896   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
897   ; CHECK-NEXT:   %5:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
898   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
899     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
901     %6:gr64 = COPY $eflags
902     $eflags = COPY %6:gr64
904     %7:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
905   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
906   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
907   ; CHECK-NEXT:   %7:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
908   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
909     MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %7
910     JMP_1 %bb.7
912   bb.7:
913     successors: %bb.4, %bb.8
914     liveins: $eflags
916     ; Inner loop latch.
917     JCC_1 %bb.4, 4, implicit $eflags
918     JMP_1 %bb.8
919   ; CHECK:      bb.7:
920   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
921   ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
922   ; CHECK-NEXT:   JCC_1 %bb.4, 5, implicit killed $eflags
923   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
925   bb.8:
926     successors: %bb.1, %bb.9
928     ; Outer loop latch. Note that we cannot have EFLAGS live-in here as that
929     ; immediately require PHIs.
930     CMP64rr %0, %1, implicit-def $eflags
931     JCC_1 %bb.1, 4, implicit $eflags
932     JMP_1 %bb.9
933   ; CHECK:      bb.8:
934   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
935   ; CHECK:        CMP64rr %0, %1, implicit-def $eflags
936   ; CHECK-NEXT:   JCC_1 %bb.1, 4, implicit $eflags
937   ; CHECK-NOT:    COPY{{( killed)?}} $eflags
939   bb.9:
940     liveins: $eflags
942     ; And we're done.
943     %8:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
944     $rax = COPY %8
945     RET 0, $rax
946   ; CHECK:      bb.9:
947   ; CHECK-NOT:     $eflags
948   ; CHECK:         %8:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
952 name:            test_existing_setcc
953 # CHECK-LABEL: name: test_existing_setcc
954 liveins:
955   - { reg: '$rdi', virtual-reg: '%0' }
956   - { reg: '$rsi', virtual-reg: '%1' }
957 body:             |
958   bb.0:
959     successors: %bb.1, %bb.2, %bb.3
960     liveins: $rdi, $rsi
962     %0:gr64 = COPY $rdi
963     %1:gr64 = COPY $rsi
964     CMP64rr %0, %1, implicit-def $eflags
965     %2:gr8 = SETCCr 7, implicit $eflags
966     %3:gr8 = SETCCr 3, implicit $eflags
967     %4:gr64 = COPY $eflags
968   ; CHECK:      CMP64rr %0, %1, implicit-def $eflags
969   ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
970   ; CHECK-NEXT: %[[AE_REG:[^:]*]]:gr8 = SETCCr 3, implicit $eflags
971   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
973     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
974     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
975     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
977     $eflags = COPY %4
978     JCC_1 %bb.1, 7, implicit $eflags
979     JCC_1 %bb.2, 2, implicit $eflags
980     JMP_1 %bb.3
981   ; CHECK-NOT: $eflags =
982   ;
983   ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
984   ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
985   ; CHECK-SAME: {{$[[:space:]]}}
986   ; CHECK-NEXT: bb.4:
987   ; CHECK-NEXT:   successors: {{.*$}}
988   ; CHECK-SAME: {{$[[:space:]]}}
989   ; CHECK-NEXT:   TEST8rr %[[AE_REG]], %[[AE_REG]], implicit-def $eflags
990   ; CHECK-NEXT:   JCC_1 %bb.2, 4, implicit killed $eflags
991   ; CHECK-NEXT:   JMP_1 %bb.3
993   bb.1:
994     %5:gr32 = MOV32ri 42
995     $eax = COPY %5
996     RET 0, $eax
998   bb.2:
999     %6:gr32 = MOV32ri 43
1000     $eax = COPY %6
1001     RET 0, $eax
1003   bb.3:
1004     %7:gr32 = MOV32r0 implicit-def dead $eflags
1005     $eax = COPY %7
1006     RET 0, $eax
1010 name:            test_existing_setcc_memory
1011 # CHECK-LABEL: name: test_existing_setcc_memory
1012 liveins:
1013   - { reg: '$rdi', virtual-reg: '%0' }
1014   - { reg: '$rsi', virtual-reg: '%1' }
1015 body:             |
1016   bb.0:
1017     successors: %bb.1, %bb.2
1018     liveins: $rdi, $rsi
1020     %0:gr64 = COPY $rdi
1021     %1:gr64 = COPY $rsi
1022     CMP64rr %0, %1, implicit-def $eflags
1023     SETCCm %0, 1, $noreg, -16, $noreg, 4, implicit $eflags
1024     %2:gr64 = COPY $eflags
1025   ; CHECK:      CMP64rr %0, %1, implicit-def $eflags
1026   ; We cannot reuse this SETE because it stores the flag directly to memory,
1027   ; so we have two SETEs here. FIXME: It'd be great if something could fold
1028   ; these automatically. If not, maybe we want to unfold SETcc instructions
1029   ; writing to memory so we can reuse them.
1030   ; CHECK-NEXT: SETCCm {{.*}} 4, implicit $eflags
1031   ; CHECK-NEXT: %[[E_REG:[^:]*]]:gr8 = SETCCr 4, implicit $eflags
1032   ; CHECK-NOT:  COPY{{( killed)?}} $eflags
1034     ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
1035     CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
1036     ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
1038     $eflags = COPY %2
1039     JCC_1 %bb.1, 4, implicit $eflags
1040     JMP_1 %bb.2
1041   ; CHECK-NOT: $eflags =
1042   ;
1043   ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
1044   ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
1045   ; CHECK-NEXT:   JMP_1 %bb.2
1047   bb.1:
1048     %3:gr32 = MOV32ri 42
1049     $eax = COPY %3
1050     RET 0, $eax
1052   bb.2:
1053     %4:gr32 = MOV32ri 43
1054     $eax = COPY %4
1055     RET 0, $eax