1# RUN: llc -run-pass x86-flags-copy-lowering -verify-machineinstrs -o - %s | FileCheck %s
2#
3# Lower various interesting copy patterns of EFLAGS without using LAHF/SAHF.
4
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  }
15
16  define i32 @test_branch_fallthrough(i64 %a, i64 %b) {
17  entry:
18    call void @foo()
19    ret i32 0
20  }
21
22  define void @test_setcc(i64 %a, i64 %b) {
23  entry:
24    call void @foo()
25    ret void
26  }
27
28  define void @test_cmov(i64 %a, i64 %b) {
29  entry:
30    call void @foo()
31    ret void
32  }
33
34  define void @test_adc(i64 %a, i64 %b) {
35  entry:
36    call void @foo()
37    ret void
38  }
39
40  define void @test_sbb(i64 %a, i64 %b) {
41  entry:
42    call void @foo()
43    ret void
44  }
45
46  define void @test_adcx(i64 %a, i64 %b) {
47  entry:
48    call void @foo()
49    ret void
50  }
51
52  define void @test_adox(i64 %a, i64 %b) {
53  entry:
54    call void @foo()
55    ret void
56  }
57
58  define void @test_rcl(i64 %a, i64 %b) {
59  entry:
60    call void @foo()
61    ret void
62  }
63
64  define void @test_rcr(i64 %a, i64 %b) {
65  entry:
66    call void @foo()
67    ret void
68  }
69
70  define void @test_setb_c(i64 %a, i64 %b) {
71  entry:
72    call void @foo()
73    ret void
74  }
75
76  define i64 @test_branch_with_livein_and_kill(i64 %a, i64 %b) {
77  entry:
78    call void @foo()
79    ret i64 0
80  }
81
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  }
87
88  define i64 @test_mid_cycle_copies(i64 %a, i64 %b) {
89  entry:
90    call void @foo()
91    ret i64 0
92  }
93
94  define i32 @test_existing_setcc(i64 %a, i64 %b) {
95  entry:
96    call void @foo()
97    ret i32 0
98  }
99
100  define i32 @test_existing_setcc_memory(i64 %a, i64 %b) {
101  entry:
102    call void @foo()
103    ret i32 0
104  }
105...
106---
107name:            test_branch
108# CHECK-LABEL: name: test_branch
109liveins:
110  - { reg: '$rdi', virtual-reg: '%0' }
111  - { reg: '$rsi', virtual-reg: '%1' }
112body:             |
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
125
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
129
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
160
161...
162---
163name:            test_branch_fallthrough
164# CHECK-LABEL: name: test_branch_fallthrough
165liveins:
166  - { reg: '$rdi', virtual-reg: '%0' }
167  - { reg: '$rsi', virtual-reg: '%1' }
168body:             |
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
181
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
185
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:
201
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
217...
218---
219name:            test_setcc
220# CHECK-LABEL: name: test_setcc
221liveins:
222  - { reg: '$rdi', virtual-reg: '%0' }
223  - { reg: '$rsi', virtual-reg: '%1' }
224body:             |
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
238
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
242
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]]
257
258    RET 0
259
260...
261---
262name:            test_cmov
263# CHECK-LABEL: name: test_cmov
264liveins:
265  - { reg: '$rdi', virtual-reg: '%0' }
266  - { reg: '$rsi', virtual-reg: '%1' }
267body:             |
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
280
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
284
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
303
304    RET 0
305
306...
307---
308name:            test_adc
309# CHECK-LABEL: name: test_adc
310liveins:
311  - { reg: '$rdi', virtual-reg: '%0' }
312  - { reg: '$rsi', virtual-reg: '%1' }
313body:             |
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
324
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
328
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
337
338    RET 0
339
340...
341---
342name:            test_sbb
343# CHECK-LABEL: name: test_sbb
344liveins:
345  - { reg: '$rdi', virtual-reg: '%0' }
346  - { reg: '$rsi', virtual-reg: '%1' }
347body:             |
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
358
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
362
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
371
372    RET 0
373
374...
375---
376name:            test_adcx
377# CHECK-LABEL: name: test_adcx
378liveins:
379  - { reg: '$rdi', virtual-reg: '%0' }
380  - { reg: '$rsi', virtual-reg: '%1' }
381body:             |
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
393
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
397
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
410
411    RET 0
412
413...
414---
415name:            test_adox
416# CHECK-LABEL: name: test_adox
417liveins:
418  - { reg: '$rdi', virtual-reg: '%0' }
419  - { reg: '$rsi', virtual-reg: '%1' }
420body:             |
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
432
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
436
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
449
450    RET 0
451
452...
453---
454name:            test_rcl
455# CHECK-LABEL: name: test_rcl
456liveins:
457  - { reg: '$rdi', virtual-reg: '%0' }
458  - { reg: '$rsi', virtual-reg: '%1' }
459body:             |
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
470
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
474
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
483
484    RET 0
485
486...
487---
488name:            test_rcr
489# CHECK-LABEL: name: test_rcr
490liveins:
491  - { reg: '$rdi', virtual-reg: '%0' }
492  - { reg: '$rsi', virtual-reg: '%1' }
493body:             |
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
504
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
508
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
517
518    RET 0
519
520...
521---
522name:            test_setb_c
523# CHECK-LABEL: name: test_setb_c
524liveins:
525  - { reg: '$rdi', virtual-reg: '%0' }
526  - { reg: '$rsi', virtual-reg: '%1' }
527body:             |
528  bb.0:
529    liveins: $rdi, $rsi
530
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
538
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
542
543    $eflags = COPY %3
544    %4:gr32 = SETB_C32r implicit-def $eflags, implicit $eflags
545    MOV32mr $rsp, 1, $noreg, -16, $noreg, killed %4
546  ; CHECK-NOT:     $eflags =
547  ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
548  ; CHECK-NEXT:    %[[SETB:[^:]*]]:gr32 = SETB_C32r implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
549  ; CHECK-NEXT:    MOV32mr $rsp, 1, $noreg, -16, $noreg, killed %[[SETB]]
550
551    $eflags = COPY %3
552    %5:gr64 = SETB_C64r implicit-def $eflags, implicit $eflags
553    MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
554  ; CHECK-NOT:     $eflags =
555  ; CHECK:         dead %{{[^:]*}}:gr8 = ADD8ri %[[CF_REG]], 255, implicit-def $eflags
556  ; CHECK-NEXT:    %[[SETB:[^:]*]]:gr64 = SETB_C64r implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
557  ; CHECK-NEXT:    MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %[[SETB]]
558
559    RET 0
560
561...
562---
563name:            test_branch_with_livein_and_kill
564# CHECK-LABEL: name: test_branch_with_livein_and_kill
565liveins:
566  - { reg: '$rdi', virtual-reg: '%0' }
567  - { reg: '$rsi', virtual-reg: '%1' }
568body:             |
569  bb.0:
570    successors: %bb.1, %bb.2, %bb.3
571    liveins: $rdi, $rsi
572
573    %0:gr64 = COPY $rdi
574    %1:gr64 = COPY $rsi
575    CMP64rr %0, %1, implicit-def $eflags
576    %2:gr64 = COPY $eflags
577  ; CHECK-NOT:  COPY{{( killed)?}} $eflags
578  ; CHECK:      %[[S_REG:[^:]*]]:gr8 = SETCCr 8, implicit $eflags
579  ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETCCr 5, implicit $eflags
580  ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
581  ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
582  ; CHECK-NOT:  COPY{{( killed)?}} $eflags
583
584    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
585    CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
586    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
587
588    $eflags = COPY %2
589    JCC_1 %bb.1, 7, implicit $eflags
590    JCC_1 %bb.2, 2, implicit $eflags
591    JMP_1 %bb.3
592  ; CHECK-NOT: $eflags =
593  ;
594  ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
595  ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
596  ; CHECK-SAME: {{$[[:space:]]}}
597  ; CHECK-NEXT: bb.4:
598  ; CHECK-NEXT:   successors: {{.*$}}
599  ; CHECK-SAME: {{$[[:space:]]}}
600  ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
601  ; CHECK-NEXT:   JCC_1 %bb.2, 5, implicit killed $eflags
602  ; CHECK-NEXT:   JMP_1 %bb.3
603
604  bb.1:
605    liveins: $eflags
606
607    %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
608  ; CHECK-NOT:     $eflags =
609  ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
610  ; CHECK-NEXT:    %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
611    $rax = COPY %3
612    RET 0, $rax
613
614  bb.2:
615    liveins: $eflags
616
617    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
618  ; CHECK-NOT:     $eflags =
619  ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
620  ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
621    $rax = COPY %4
622    RET 0, $rax
623
624  bb.3:
625    liveins: $eflags
626
627    %5:gr64 = CMOV64rr %0, %1, 8, implicit killed $eflags
628  ; CHECK-NOT:     $eflags =
629  ; CHECK:         TEST8rr %[[S_REG]], %[[S_REG]], implicit-def $eflags
630  ; CHECK-NEXT:    %5:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
631    $rax = COPY %5
632    RET 0, $rax
633
634...
635---
636name:            test_branch_with_interleaved_livein_and_kill
637# CHECK-LABEL: name: test_branch_with_interleaved_livein_and_kill
638liveins:
639  - { reg: '$rdi', virtual-reg: '%0' }
640  - { reg: '$rsi', virtual-reg: '%1' }
641body:             |
642  bb.0:
643    successors: %bb.1, %bb.2, %bb.5
644    liveins: $rdi, $rsi
645
646    %0:gr64 = COPY $rdi
647    %1:gr64 = COPY $rsi
648    CMP64rr %0, %1, implicit-def $eflags
649    %2:gr64 = COPY $eflags
650  ; CHECK-NOT:  COPY{{( killed)?}} $eflags
651  ; CHECK:      %[[S_REG:[^:]*]]:gr8 = SETCCr 8, implicit $eflags
652  ; CHECK-NEXT: %[[P_REG:[^:]*]]:gr8 = SETCCr 10, implicit $eflags
653  ; CHECK-NEXT: %[[NE_REG:[^:]*]]:gr8 = SETCCr 5, implicit $eflags
654  ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
655  ; CHECK-NEXT: %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
656  ; CHECK-NEXT: %[[O_REG:[^:]*]]:gr8 = SETCCr 0, implicit $eflags
657  ; CHECK-NOT:  COPY{{( killed)?}} $eflags
658
659    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
660    CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
661    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
662
663    $eflags = COPY %2
664    JCC_1 %bb.1, 7, implicit $eflags
665    JCC_1 %bb.2, 2, implicit $eflags
666    JMP_1 %bb.5
667  ; CHECK-NOT: $eflags =
668  ;
669  ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
670  ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
671  ; CHECK-SAME: {{$[[:space:]]}}
672  ; CHECK-NEXT: bb.6:
673  ; CHECK-NEXT:   successors: {{.*$}}
674  ; CHECK-SAME: {{$[[:space:]]}}
675  ; CHECK-NEXT:   TEST8rr %[[B_REG]], %[[B_REG]], implicit-def $eflags
676  ; CHECK-NEXT:   JCC_1 %bb.2, 5, implicit killed $eflags
677  ; CHECK-NEXT:   JMP_1 %bb.5
678
679  bb.1:
680    liveins: $eflags
681
682    %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
683  ; CHECK-NOT:     $eflags =
684  ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
685  ; CHECK-NEXT:    %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
686    $rax = COPY %3
687    RET 0, $rax
688
689  bb.2:
690    ; The goal is to have another batch of successors discovered in a block
691    ; between two successors which kill $eflags. This ensures that neither of
692    ; the surrounding kills impact recursing through this block.
693    successors: %bb.3, %bb.4
694    liveins: $eflags
695
696    JCC_1 %bb.3, 0, implicit $eflags
697    JMP_1 %bb.4
698  ; CHECK-NOT: $eflags =
699  ;
700  ; CHECK:        TEST8rr %[[O_REG]], %[[O_REG]], implicit-def $eflags
701  ; CHECK-NEXT:   JCC_1 %bb.3, 5, implicit killed $eflags
702  ; CHECK-NEXT:   JMP_1 %bb.4
703
704  bb.3:
705    liveins: $eflags
706
707    %4:gr64 = CMOV64rr %0, %1, 5, implicit $eflags
708  ; CHECK-NOT:     $eflags =
709  ; CHECK:         TEST8rr %[[NE_REG]], %[[NE_REG]], implicit-def $eflags
710  ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
711    $rax = COPY %4
712    RET 0, $rax
713
714  bb.4:
715    liveins: $eflags
716
717    %5:gr64 = CMOV64rr %0, %1, 10, implicit $eflags
718  ; CHECK-NOT:     $eflags =
719  ; CHECK:         TEST8rr %[[P_REG]], %[[P_REG]], implicit-def $eflags
720  ; CHECK-NEXT:    %5:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
721    $rax = COPY %5
722    RET 0, $rax
723
724  bb.5:
725    liveins: $eflags
726
727    %6:gr64 = CMOV64rr %0, %1, 8, implicit killed $eflags
728  ; CHECK-NOT:     $eflags =
729  ; CHECK:         TEST8rr %[[S_REG]], %[[S_REG]], implicit-def $eflags
730  ; CHECK-NEXT:    %6:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
731    $rax = COPY %6
732    RET 0, $rax
733
734...
735---
736# This test case is designed to exercise a particularly challenging situation:
737# when the flags are copied and restored *inside* of a complex and cyclic CFG
738# all of which have live-in flags. To correctly handle this case we have to walk
739# up the dominator tree and locate a viable reaching definition location,
740# checking for clobbers along any path. The CFG for this function looks like the
741# following diagram, control flowing out the bottom of blocks and in the top:
742#
743#  bb.0
744#   | __________________
745#   |/                  \
746#  bb.1                  |
747#   |\_________          |
748#   | __       \ ____    |
749#   |/  \      |/    \   |
750#  bb.2  |    bb.4    |  |
751#   |\__/     / \     |  |
752#   |        /   \    |  |
753#  bb.3    bb.5  bb.6 |  |
754#   |        \   /    |  |
755#   |         \ /     |  |
756#   |         bb.7    |  |
757#   | ________/ \____/   |
758#   |/                   |
759#  bb.8                  |
760#   |\__________________/
761#   |
762#  bb.9
763#
764# We set EFLAGS in bb.0, clobber them in bb.3, and copy them in bb.2 and bb.6.
765# Because of the cycles this requires hoisting the `SETcc` instructions to
766# capture the flags for the bb.6 copy to bb.1 and using them for the copy in
767# `bb.2` as well despite the clobber in `bb.3`. The clobber in `bb.3` also
768# prevents hoisting the `SETcc`s up to `bb.0`.
769#
770# Throughout the test we use branch instructions that are totally bogus (as the
771# flags are obviously not changing!) but this is just to allow us to send
772# a small but complex CFG structure through the backend and force it to choose
773# plausible lowering decisions based on the core CFG presented, regardless of
774# the futility of the actual branches.
775name:            test_mid_cycle_copies
776# CHECK-LABEL: name: test_mid_cycle_copies
777liveins:
778  - { reg: '$rdi', virtual-reg: '%0' }
779  - { reg: '$rsi', virtual-reg: '%1' }
780body:             |
781  bb.0:
782    successors: %bb.1
783    liveins: $rdi, $rsi
784
785    %0:gr64 = COPY $rdi
786    %1:gr64 = COPY $rsi
787    CMP64rr %0, %1, implicit-def $eflags
788  ; CHECK:      bb.0:
789  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
790  ; CHECK:        CMP64rr %0, %1, implicit-def $eflags
791  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
792    JMP_1 %bb.1
793
794  bb.1:
795    successors: %bb.2, %bb.4
796    liveins: $eflags
797
798    ; Outer loop header, target for one set of hoisting.
799    JCC_1 %bb.2, 4, implicit $eflags
800    JMP_1 %bb.4
801  ; CHECK:      bb.1:
802  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
803  ; CHECK:        %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
804  ; CHECK-NEXT:   %[[E_REG:[^:]*]]:gr8 = SETCCr 4, implicit $eflags
805  ; CHECK-NEXT:   %[[B_REG:[^:]*]]:gr8 = SETCCr 2, implicit $eflags
806  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
807
808  bb.2:
809    successors: %bb.2, %bb.3
810    liveins: $eflags
811
812    ; Inner loop with a local copy. We should eliminate this but can't hoist.
813    %2:gr64 = COPY $eflags
814    $eflags = COPY %2
815    JCC_1 %bb.2, 4, implicit $eflags
816    JMP_1 %bb.3
817  ; CHECK:      bb.2:
818  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
819  ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
820  ; CHECK-NEXT:   JCC_1 %bb.2, 5, implicit killed $eflags
821  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
822
823  bb.3:
824    successors: %bb.8
825    liveins: $eflags
826
827    ; Use and then clobber $eflags. Then hop to the outer loop latch.
828    %3:gr64 = ADC64ri32 %0, 42, implicit-def dead $eflags, implicit $eflags
829  ; CHECK:      bb.3:
830  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
831  ; CHECK:        dead %{{[^:]*}}:gr8 = ADD8ri %[[B_REG]], 255, implicit-def $eflags
832  ; CHECK-NEXT:   %3:gr64 = ADC64ri32 %0, 42, implicit-def{{( dead)?}} $eflags, implicit{{( killed)?}} $eflags
833  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
834    MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3
835    JMP_1 %bb.8
836
837  bb.4:
838    successors: %bb.5, %bb.6
839    liveins: $eflags
840
841    ; Another inner loop, this one with a diamond.
842    JCC_1 %bb.5, 4, implicit $eflags
843    JMP_1 %bb.6
844  ; CHECK:      bb.4:
845  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
846  ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
847  ; CHECK-NEXT:   JCC_1 %bb.5, 5, implicit killed $eflags
848  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
849
850  bb.5:
851    successors: %bb.7
852    liveins: $eflags
853
854    ; Just use $eflags on this side of the diamond.
855    %4:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
856  ; CHECK:      bb.5:
857  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
858  ; CHECK:         TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
859  ; CHECK-NEXT:    %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
860  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
861    MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
862    JMP_1 %bb.7
863
864  bb.6:
865    successors: %bb.7
866    liveins: $eflags
867
868    ; Use, copy, and then use $eflags again.
869    %5:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
870  ; CHECK:      bb.6:
871  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
872  ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
873  ; CHECK-NEXT:   %5:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
874  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
875    MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
876
877    %6:gr64 = COPY $eflags
878    $eflags = COPY %6:gr64
879
880    %7:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
881  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
882  ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
883  ; CHECK-NEXT:   %7:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
884  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
885    MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %7
886    JMP_1 %bb.7
887
888  bb.7:
889    successors: %bb.4, %bb.8
890    liveins: $eflags
891
892    ; Inner loop latch.
893    JCC_1 %bb.4, 4, implicit $eflags
894    JMP_1 %bb.8
895  ; CHECK:      bb.7:
896  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
897  ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
898  ; CHECK-NEXT:   JCC_1 %bb.4, 5, implicit killed $eflags
899  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
900
901  bb.8:
902    successors: %bb.1, %bb.9
903
904    ; Outer loop latch. Note that we cannot have EFLAGS live-in here as that
905    ; immediately require PHIs.
906    CMP64rr %0, %1, implicit-def $eflags
907    JCC_1 %bb.1, 4, implicit $eflags
908    JMP_1 %bb.9
909  ; CHECK:      bb.8:
910  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
911  ; CHECK:        CMP64rr %0, %1, implicit-def $eflags
912  ; CHECK-NEXT:   JCC_1 %bb.1, 4, implicit $eflags
913  ; CHECK-NOT:    COPY{{( killed)?}} $eflags
914
915  bb.9:
916    liveins: $eflags
917
918    ; And we're done.
919    %8:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
920    $rax = COPY %8
921    RET 0, $rax
922  ; CHECK:      bb.9:
923  ; CHECK-NOT:     $eflags
924  ; CHECK:         %8:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
925
926...
927---
928name:            test_existing_setcc
929# CHECK-LABEL: name: test_existing_setcc
930liveins:
931  - { reg: '$rdi', virtual-reg: '%0' }
932  - { reg: '$rsi', virtual-reg: '%1' }
933body:             |
934  bb.0:
935    successors: %bb.1, %bb.2, %bb.3
936    liveins: $rdi, $rsi
937
938    %0:gr64 = COPY $rdi
939    %1:gr64 = COPY $rsi
940    CMP64rr %0, %1, implicit-def $eflags
941    %2:gr8 = SETCCr 7, implicit $eflags
942    %3:gr8 = SETCCr 3, implicit $eflags
943    %4:gr64 = COPY $eflags
944  ; CHECK:      CMP64rr %0, %1, implicit-def $eflags
945  ; CHECK-NEXT: %[[A_REG:[^:]*]]:gr8 = SETCCr 7, implicit $eflags
946  ; CHECK-NEXT: %[[AE_REG:[^:]*]]:gr8 = SETCCr 3, implicit $eflags
947  ; CHECK-NOT:  COPY{{( killed)?}} $eflags
948
949    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
950    CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
951    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
952
953    $eflags = COPY %4
954    JCC_1 %bb.1, 7, implicit $eflags
955    JCC_1 %bb.2, 2, implicit $eflags
956    JMP_1 %bb.3
957  ; CHECK-NOT: $eflags =
958  ;
959  ; CHECK:        TEST8rr %[[A_REG]], %[[A_REG]], implicit-def $eflags
960  ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
961  ; CHECK-SAME: {{$[[:space:]]}}
962  ; CHECK-NEXT: bb.4:
963  ; CHECK-NEXT:   successors: {{.*$}}
964  ; CHECK-SAME: {{$[[:space:]]}}
965  ; CHECK-NEXT:   TEST8rr %[[AE_REG]], %[[AE_REG]], implicit-def $eflags
966  ; CHECK-NEXT:   JCC_1 %bb.2, 4, implicit killed $eflags
967  ; CHECK-NEXT:   JMP_1 %bb.3
968
969  bb.1:
970    %5:gr32 = MOV32ri 42
971    $eax = COPY %5
972    RET 0, $eax
973
974  bb.2:
975    %6:gr32 = MOV32ri 43
976    $eax = COPY %6
977    RET 0, $eax
978
979  bb.3:
980    %7:gr32 = MOV32r0 implicit-def dead $eflags
981    $eax = COPY %7
982    RET 0, $eax
983
984...
985---
986name:            test_existing_setcc_memory
987# CHECK-LABEL: name: test_existing_setcc_memory
988liveins:
989  - { reg: '$rdi', virtual-reg: '%0' }
990  - { reg: '$rsi', virtual-reg: '%1' }
991body:             |
992  bb.0:
993    successors: %bb.1, %bb.2
994    liveins: $rdi, $rsi
995
996    %0:gr64 = COPY $rdi
997    %1:gr64 = COPY $rsi
998    CMP64rr %0, %1, implicit-def $eflags
999    SETCCm %0, 1, $noreg, -16, $noreg, 4, implicit $eflags
1000    %2:gr64 = COPY $eflags
1001  ; CHECK:      CMP64rr %0, %1, implicit-def $eflags
1002  ; We cannot reuse this SETE because it stores the flag directly to memory,
1003  ; so we have two SETEs here. FIXME: It'd be great if something could fold
1004  ; these automatically. If not, maybe we want to unfold SETcc instructions
1005  ; writing to memory so we can reuse them.
1006  ; CHECK-NEXT: SETCCm {{.*}} 4, implicit $eflags
1007  ; CHECK-NEXT: %[[E_REG:[^:]*]]:gr8 = SETCCr 4, implicit $eflags
1008  ; CHECK-NOT:  COPY{{( killed)?}} $eflags
1009
1010    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
1011    CALL64pcrel32 @foo, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
1012    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
1013
1014    $eflags = COPY %2
1015    JCC_1 %bb.1, 4, implicit $eflags
1016    JMP_1 %bb.2
1017  ; CHECK-NOT: $eflags =
1018  ;
1019  ; CHECK:        TEST8rr %[[E_REG]], %[[E_REG]], implicit-def $eflags
1020  ; CHECK-NEXT:   JCC_1 %bb.1, 5, implicit killed $eflags
1021  ; CHECK-NEXT:   JMP_1 %bb.2
1022
1023  bb.1:
1024    %3:gr32 = MOV32ri 42
1025    $eax = COPY %3
1026    RET 0, $eax
1027
1028  bb.2:
1029    %4:gr32 = MOV32ri 43
1030    $eax = COPY %4
1031    RET 0, $eax
1032
1033...
1034