1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
2 # RUN: llc -mtriple=x86_64 -run-pass x86-flags-copy-lowering -verify-machineinstrs -o - %s | FileCheck %s
3 # Lower various interesting copy patterns of EFLAGS without using LAHF/SAHF.
9 ; CHECK-LABEL: name: test_branch
11 ; CHECK-NEXT: successors: %bb.1(0x2aaaaaab), %bb.4(0x55555556)
12 ; CHECK-NEXT: liveins: $rdi, $rsi
14 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
15 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
16 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
17 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
18 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
19 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
20 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
21 ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags
24 ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
26 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
27 ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags
28 ; CHECK-NEXT: JMP_1 %bb.3
31 ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
32 ; CHECK-NEXT: $eax = COPY [[MOV32ri]]
33 ; CHECK-NEXT: RET 0, $eax
36 ; CHECK-NEXT: [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 43
37 ; CHECK-NEXT: $eax = COPY [[MOV32ri1]]
38 ; CHECK-NEXT: RET 0, $eax
41 ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags
42 ; CHECK-NEXT: $eax = COPY [[MOV32r0_]]
43 ; CHECK-NEXT: RET 0, $eax
45 successors: %bb.1, %bb.2, %bb.3
50 CMP64rr %0, %1, implicit-def $eflags
51 %2:gr64 = COPY $eflags
53 INLINEASM &nop, 1, 12, implicit-def dead $eflags
56 JCC_1 %bb.1, 7, implicit $eflags
57 JCC_1 %bb.2, 2, implicit $eflags
71 %5:gr32 = MOV32r0 implicit-def dead $eflags
77 name: test_branch_fallthrough
79 ; CHECK-LABEL: name: test_branch_fallthrough
81 ; CHECK-NEXT: successors: %bb.4(0x55555556), %bb.2(0x2aaaaaab)
82 ; CHECK-NEXT: liveins: $rdi, $rsi
84 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
85 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
86 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
87 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
88 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
89 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
90 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
91 ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags
94 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000)
96 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
97 ; CHECK-NEXT: JCC_1 %bb.3, 5, implicit killed $eflags
100 ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags
101 ; CHECK-NEXT: $eax = COPY [[MOV32r0_]]
102 ; CHECK-NEXT: RET 0, $eax
105 ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
106 ; CHECK-NEXT: $eax = COPY [[MOV32ri]]
107 ; CHECK-NEXT: RET 0, $eax
110 ; CHECK-NEXT: [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 43
111 ; CHECK-NEXT: $eax = COPY [[MOV32ri1]]
112 ; CHECK-NEXT: RET 0, $eax
114 successors: %bb.1, %bb.2, %bb.3
119 CMP64rr %0, %1, implicit-def $eflags
120 %2:gr64 = COPY $eflags
122 INLINEASM &nop, 1, 12, implicit-def dead $eflags
125 JCC_1 %bb.2, 7, implicit $eflags
126 JCC_1 %bb.3, 2, implicit $eflags
129 %5:gr32 = MOV32r0 implicit-def dead $eflags
150 ; CHECK-LABEL: name: test_setcc
151 ; CHECK: liveins: $rdi, $rsi
153 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
154 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
155 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
156 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
157 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
158 ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
159 ; CHECK-NEXT: [[SETCCr3:%[0-9]+]]:gr8 = SETCCr 5, implicit $eflags
160 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
161 ; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, [[SETCCr3]]
162 ; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, [[SETCCr]]
163 ; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, [[SETCCr1]]
164 ; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, [[SETCCr2]]
168 CMP64rr %0, %1, implicit-def $eflags
169 %2:gr64 = COPY $eflags
171 INLINEASM &nop, 1, 12, implicit-def dead $eflags
174 %3:gr8 = SETCCr 7, implicit $eflags
175 %4:gr8 = SETCCr 2, implicit $eflags
176 %5:gr8 = SETCCr 4, implicit $eflags
177 SETCCm $rsp, 1, $noreg, -16, $noreg, 5, implicit killed $eflags
178 MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %3
179 MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %4
180 MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %5
191 ; CHECK-LABEL: name: test_cmov
192 ; CHECK: liveins: $rdi, $rsi
194 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
195 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
196 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
197 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
198 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
199 ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
200 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
201 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
202 ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
203 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
204 ; CHECK-NEXT: [[CMOV64rr1:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
205 ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags
206 ; CHECK-NEXT: [[CMOV64rr2:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
207 ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags
208 ; CHECK-NEXT: [[CMOV64rr3:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 4, implicit killed $eflags
209 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr]]
210 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr1]]
211 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr2]]
212 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr3]]
216 CMP64rr %0, %1, implicit-def $eflags
217 %2:gr64 = COPY $eflags
219 INLINEASM &nop, 1, 12, implicit-def dead $eflags
222 %3:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
223 %4:gr64 = CMOV64rr %0, %1, 2, implicit $eflags
224 %5:gr64 = CMOV64rr %0, %1, 4, implicit $eflags
225 %6:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
226 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3
227 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
228 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
229 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %6
240 ; CHECK-LABEL: name: test_adc
241 ; CHECK: liveins: $rdi, $rsi
243 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
244 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
245 ; CHECK-NEXT: [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[COPY]], [[COPY1]], implicit-def $eflags
246 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
247 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
248 ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags
249 ; CHECK-NEXT: [[ADC64ri32_:%[0-9]+]]:gr64 = ADC64ri32 [[ADD64rr]], 42, implicit-def $eflags, implicit killed $eflags
250 ; CHECK-NEXT: [[ADC64ri32_1:%[0-9]+]]:gr64 = ADC64ri32 [[ADC64ri32_]], 42, implicit-def $eflags, implicit $eflags
251 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[ADC64ri32_1]]
255 %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
256 %3:gr64 = COPY $eflags
258 INLINEASM &nop, 1, 12, implicit-def dead $eflags
261 %4:gr64 = ADC64ri32 %2:gr64, 42, implicit-def $eflags, implicit $eflags
262 %5:gr64 = ADC64ri32 %4:gr64, 42, implicit-def $eflags, implicit $eflags
263 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
274 ; CHECK-LABEL: name: test_sbb
275 ; CHECK: liveins: $rdi, $rsi
277 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
278 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
279 ; CHECK-NEXT: [[SUB64rr:%[0-9]+]]:gr64 = SUB64rr [[COPY]], [[COPY1]], implicit-def $eflags
280 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
281 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
282 ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags
283 ; CHECK-NEXT: [[SBB64ri32_:%[0-9]+]]:gr64 = SBB64ri32 [[SUB64rr]], 42, implicit-def $eflags, implicit killed $eflags
284 ; CHECK-NEXT: [[SBB64ri32_1:%[0-9]+]]:gr64 = SBB64ri32 [[SBB64ri32_]], 42, implicit-def dead $eflags, implicit killed $eflags
285 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[SBB64ri32_1]]
289 %2:gr64 = SUB64rr %0, %1, implicit-def $eflags
290 %3:gr64 = COPY killed $eflags
292 INLINEASM &nop, 1, 12, implicit-def dead $eflags
295 %4:gr64 = SBB64ri32 %2:gr64, 42, implicit-def $eflags, implicit killed $eflags
296 %5:gr64 = SBB64ri32 %4:gr64, 42, implicit-def dead $eflags, implicit killed $eflags
297 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
308 ; CHECK-LABEL: name: test_rcl
309 ; CHECK: liveins: $rdi, $rsi
311 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
312 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
313 ; CHECK-NEXT: [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[COPY]], [[COPY1]], implicit-def $eflags
314 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
315 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
316 ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags
317 ; CHECK-NEXT: [[RCL64r1_:%[0-9]+]]:gr64 = RCL64r1 [[ADD64rr]], implicit-def $eflags, implicit killed $eflags
318 ; CHECK-NEXT: [[RCL64r1_1:%[0-9]+]]:gr64 = RCL64r1 [[RCL64r1_]], implicit-def $eflags, implicit $eflags
319 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[RCL64r1_1]]
323 %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
324 %3:gr64 = COPY $eflags
326 INLINEASM &nop, 1, 12, implicit-def dead $eflags
329 %4:gr64 = RCL64r1 %2:gr64, implicit-def $eflags, implicit $eflags
330 %5:gr64 = RCL64r1 %4:gr64, implicit-def $eflags, implicit $eflags
331 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
342 ; CHECK-LABEL: name: test_rcr
343 ; CHECK: liveins: $rdi, $rsi
345 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
346 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
347 ; CHECK-NEXT: [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[COPY]], [[COPY1]], implicit-def $eflags
348 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
349 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
350 ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags
351 ; CHECK-NEXT: [[RCR64r1_:%[0-9]+]]:gr64 = RCR64r1 [[ADD64rr]], implicit-def $eflags, implicit killed $eflags
352 ; CHECK-NEXT: [[RCR64r1_1:%[0-9]+]]:gr64 = RCR64r1 [[RCR64r1_]], implicit-def $eflags, implicit $eflags
353 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[RCR64r1_1]]
357 %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
358 %3:gr64 = COPY $eflags
360 INLINEASM &nop, 1, 12, implicit-def dead $eflags
363 %4:gr64 = RCR64r1 %2:gr64, implicit-def $eflags, implicit $eflags
364 %5:gr64 = RCR64r1 %4:gr64, implicit-def $eflags, implicit $eflags
365 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
376 ; CHECK-LABEL: name: test_setb_c
377 ; CHECK: liveins: $rdi, $rsi
379 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
380 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
381 ; CHECK-NEXT: [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[COPY]], [[COPY1]], implicit-def $eflags
382 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
383 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
384 ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags
385 ; CHECK-NEXT: [[SETB_C32r:%[0-9]+]]:gr32 = SETB_C32r implicit-def $eflags, implicit killed $eflags
386 ; CHECK-NEXT: MOV32mr $rsp, 1, $noreg, -16, $noreg, killed [[SETB_C32r]]
387 ; CHECK-NEXT: dead [[ADD8ri1:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags
388 ; CHECK-NEXT: [[SETB_C64r:%[0-9]+]]:gr64 = SETB_C64r implicit-def $eflags, implicit killed $eflags
389 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[SETB_C64r]]
393 %2:gr64 = ADD64rr %0, %1, implicit-def $eflags
394 %3:gr64 = COPY $eflags
396 INLINEASM &nop, 1, 12, implicit-def dead $eflags
399 %4:gr32 = SETB_C32r implicit-def $eflags, implicit $eflags
400 MOV32mr $rsp, 1, $noreg, -16, $noreg, killed %4
403 %5:gr64 = SETB_C64r implicit-def $eflags, implicit $eflags
404 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
410 name: test_branch_with_livein_and_kill
412 ; CHECK-LABEL: name: test_branch_with_livein_and_kill
414 ; CHECK-NEXT: successors: %bb.1(0x2aaaaaab), %bb.4(0x55555556)
415 ; CHECK-NEXT: liveins: $rdi, $rsi
417 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
418 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
419 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
420 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 8, implicit $eflags
421 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 5, implicit $eflags
422 ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
423 ; CHECK-NEXT: [[SETCCr3:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
424 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
425 ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags
426 ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags
429 ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
431 ; CHECK-NEXT: TEST8rr [[SETCCr3]], [[SETCCr3]], implicit-def $eflags
432 ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags
433 ; CHECK-NEXT: JMP_1 %bb.3
436 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
437 ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 4, implicit killed $eflags
438 ; CHECK-NEXT: $rax = COPY [[CMOV64rr]]
439 ; CHECK-NEXT: RET 0, $rax
442 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
443 ; CHECK-NEXT: [[CMOV64rr1:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
444 ; CHECK-NEXT: $rax = COPY [[CMOV64rr1]]
445 ; CHECK-NEXT: RET 0, $rax
448 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
449 ; CHECK-NEXT: [[CMOV64rr2:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
450 ; CHECK-NEXT: $rax = COPY [[CMOV64rr2]]
451 ; CHECK-NEXT: RET 0, $rax
453 successors: %bb.1, %bb.2, %bb.3
458 CMP64rr %0, %1, implicit-def $eflags
459 %2:gr64 = COPY $eflags
461 INLINEASM &nop, 1, 12, implicit-def dead $eflags
464 JCC_1 %bb.1, 7, implicit $eflags
465 JCC_1 %bb.2, 2, implicit $eflags
471 %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
478 %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags
485 %5:gr64 = CMOV64rr %0, %1, 8, implicit killed $eflags
491 name: test_branch_with_interleaved_livein_and_kill
493 ; CHECK-LABEL: name: test_branch_with_interleaved_livein_and_kill
495 ; CHECK-NEXT: successors: %bb.1(0x2aaaaaab), %bb.6(0x55555556)
496 ; CHECK-NEXT: liveins: $rdi, $rsi
498 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
499 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
500 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
501 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 8, implicit $eflags
502 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 10, implicit $eflags
503 ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 5, implicit $eflags
504 ; CHECK-NEXT: [[SETCCr3:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
505 ; CHECK-NEXT: [[SETCCr4:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
506 ; CHECK-NEXT: [[SETCCr5:%[0-9]+]]:gr8 = SETCCr 0, implicit $eflags
507 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
508 ; CHECK-NEXT: TEST8rr [[SETCCr3]], [[SETCCr3]], implicit-def $eflags
509 ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags
512 ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.5(0x40000000)
514 ; CHECK-NEXT: TEST8rr [[SETCCr4]], [[SETCCr4]], implicit-def $eflags
515 ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags
516 ; CHECK-NEXT: JMP_1 %bb.5
519 ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags
520 ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 4, implicit killed $eflags
521 ; CHECK-NEXT: $rax = COPY [[CMOV64rr]]
522 ; CHECK-NEXT: RET 0, $rax
525 ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.4(0x40000000)
527 ; CHECK-NEXT: TEST8rr [[SETCCr5]], [[SETCCr5]], implicit-def $eflags
528 ; CHECK-NEXT: JCC_1 %bb.3, 5, implicit killed $eflags
529 ; CHECK-NEXT: JMP_1 %bb.4
532 ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags
533 ; CHECK-NEXT: [[CMOV64rr1:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
534 ; CHECK-NEXT: $rax = COPY [[CMOV64rr1]]
535 ; CHECK-NEXT: RET 0, $rax
538 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
539 ; CHECK-NEXT: [[CMOV64rr2:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
540 ; CHECK-NEXT: $rax = COPY [[CMOV64rr2]]
541 ; CHECK-NEXT: RET 0, $rax
544 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
545 ; CHECK-NEXT: [[CMOV64rr3:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
546 ; CHECK-NEXT: $rax = COPY [[CMOV64rr3]]
547 ; CHECK-NEXT: RET 0, $rax
549 successors: %bb.1, %bb.2, %bb.5
554 CMP64rr %0, %1, implicit-def $eflags
555 %2:gr64 = COPY $eflags
557 INLINEASM &nop, 1, 12, implicit-def dead $eflags
560 JCC_1 %bb.1, 7, implicit $eflags
561 JCC_1 %bb.2, 2, implicit $eflags
567 %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
572 successors: %bb.3, %bb.4
575 JCC_1 %bb.3, 0, implicit $eflags
581 %4:gr64 = CMOV64rr %0, %1, 5, implicit $eflags
588 %5:gr64 = CMOV64rr %0, %1, 10, implicit $eflags
595 %6:gr64 = CMOV64rr %0, %1, 8, implicit killed $eflags
601 # This test case is designed to exercise a particularly challenging situation:
602 # when the flags are copied and restored *inside* of a complex and cyclic CFG
603 # all of which have live-in flags. To correctly handle this case we have to walk
604 # up the dominator tree and locate a viable reaching definition location,
605 # checking for clobbers along any path. The CFG for this function looks like the
606 # following diagram, control flowing out the bottom of blocks and in the top:
609 # | __________________
622 # | ________/ \____/ |
625 # |\__________________/
629 # We set EFLAGS in bb.0, clobber them in bb.3, and copy them in bb.2 and bb.6.
630 # Because of the cycles this requires hoisting the `SETcc` instructions to
631 # capture the flags for the bb.6 copy to bb.1 and using them for the copy in
632 # `bb.2` as well despite the clobber in `bb.3`. The clobber in `bb.3` also
633 # prevents hoisting the `SETcc`s up to `bb.0`.
635 # Throughout the test we use branch instructions that are totally bogus (as the
636 # flags are obviously not changing!) but this is just to allow us to send
637 # a small but complex CFG structure through the backend and force it to choose
638 # plausible lowering decisions based on the core CFG presented, regardless of
639 # the futility of the actual branches.
640 name: test_mid_cycle_copies
642 ; CHECK-LABEL: name: test_mid_cycle_copies
644 ; CHECK-NEXT: successors: %bb.1(0x80000000)
645 ; CHECK-NEXT: liveins: $rdi, $rsi
647 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
648 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
649 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
650 ; CHECK-NEXT: JMP_1 %bb.1
653 ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.4(0x40000000)
654 ; CHECK-NEXT: liveins: $eflags
656 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
657 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
658 ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags
659 ; CHECK-NEXT: JCC_1 %bb.2, 4, implicit $eflags
660 ; CHECK-NEXT: JMP_1 %bb.4
663 ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
665 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
666 ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags
667 ; CHECK-NEXT: JMP_1 %bb.3
670 ; CHECK-NEXT: successors: %bb.8(0x80000000)
672 ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr2]], 255, implicit-def $eflags
673 ; CHECK-NEXT: [[ADC64ri32_:%[0-9]+]]:gr64 = ADC64ri32 [[COPY]], 42, implicit-def dead $eflags, implicit killed $eflags
674 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[ADC64ri32_]]
675 ; CHECK-NEXT: JMP_1 %bb.8
678 ; CHECK-NEXT: successors: %bb.5(0x40000000), %bb.6(0x40000000)
680 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
681 ; CHECK-NEXT: JCC_1 %bb.5, 5, implicit killed $eflags
682 ; CHECK-NEXT: JMP_1 %bb.6
685 ; CHECK-NEXT: successors: %bb.7(0x80000000)
687 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
688 ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
689 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr]]
690 ; CHECK-NEXT: JMP_1 %bb.7
693 ; CHECK-NEXT: successors: %bb.7(0x80000000)
695 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
696 ; CHECK-NEXT: [[CMOV64rr1:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
697 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr1]]
698 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
699 ; CHECK-NEXT: [[CMOV64rr2:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags
700 ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr2]]
701 ; CHECK-NEXT: JMP_1 %bb.7
704 ; CHECK-NEXT: successors: %bb.4(0x40000000), %bb.8(0x40000000)
706 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
707 ; CHECK-NEXT: JCC_1 %bb.4, 5, implicit killed $eflags
708 ; CHECK-NEXT: JMP_1 %bb.8
711 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.9(0x40000000)
713 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
714 ; CHECK-NEXT: JCC_1 %bb.1, 4, implicit $eflags
715 ; CHECK-NEXT: JMP_1 %bb.9
718 ; CHECK-NEXT: liveins: $eflags
720 ; CHECK-NEXT: [[CMOV64rr3:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 4, implicit killed $eflags
721 ; CHECK-NEXT: $rax = COPY [[CMOV64rr3]]
722 ; CHECK-NEXT: RET 0, $rax
729 CMP64rr %0, %1, implicit-def $eflags
733 successors: %bb.2, %bb.4
736 JCC_1 %bb.2, 4, implicit $eflags
740 successors: %bb.2, %bb.3
743 %2:gr64 = COPY $eflags
745 JCC_1 %bb.2, 4, implicit $eflags
752 %3:gr64 = ADC64ri32 %0, 42, implicit-def dead $eflags, implicit $eflags
753 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3
757 successors: %bb.5, %bb.6
760 JCC_1 %bb.5, 4, implicit $eflags
767 %4:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
768 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4
775 %5:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
776 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5
778 %6:gr64 = COPY $eflags
779 $eflags = COPY %6:gr64
781 %7:gr64 = CMOV64rr %0, %1, 7, implicit $eflags
782 MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %7
786 successors: %bb.4, %bb.8
789 JCC_1 %bb.4, 4, implicit $eflags
793 successors: %bb.1, %bb.9
795 CMP64rr %0, %1, implicit-def $eflags
796 JCC_1 %bb.1, 4, implicit $eflags
802 %8:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags
808 name: test_existing_setcc
810 ; CHECK-LABEL: name: test_existing_setcc
812 ; CHECK-NEXT: successors: %bb.1(0x2aaaaaab), %bb.4(0x55555556)
813 ; CHECK-NEXT: liveins: $rdi, $rsi
815 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
816 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
817 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
818 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags
819 ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 3, implicit $eflags
820 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
821 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
822 ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags
825 ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
827 ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags
828 ; CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags
829 ; CHECK-NEXT: JMP_1 %bb.3
832 ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
833 ; CHECK-NEXT: $eax = COPY [[MOV32ri]]
834 ; CHECK-NEXT: RET 0, $eax
837 ; CHECK-NEXT: [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 43
838 ; CHECK-NEXT: $eax = COPY [[MOV32ri1]]
839 ; CHECK-NEXT: RET 0, $eax
842 ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags
843 ; CHECK-NEXT: $eax = COPY [[MOV32r0_]]
844 ; CHECK-NEXT: RET 0, $eax
846 successors: %bb.1, %bb.2, %bb.3
851 CMP64rr %0, %1, implicit-def $eflags
852 %2:gr8 = SETCCr 7, implicit $eflags
853 %3:gr8 = SETCCr 3, implicit $eflags
854 %4:gr64 = COPY $eflags
856 INLINEASM &nop, 1, 12, implicit-def dead $eflags
859 JCC_1 %bb.1, 7, implicit $eflags
860 JCC_1 %bb.2, 2, implicit $eflags
874 %7:gr32 = MOV32r0 implicit-def dead $eflags
880 # We cannot reuse this SETE because it stores the flag directly to memory,
881 # so we have two SETEs here. FIXME: It'd be great if something could fold
882 # these automatically. If not, maybe we want to unfold SETcc instructions
883 # writing to memory so we can reuse them.
885 name: test_existing_setcc_memory
887 ; CHECK-LABEL: name: test_existing_setcc_memory
889 ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
890 ; CHECK-NEXT: liveins: $rdi, $rsi
892 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi
893 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi
894 ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags
895 ; CHECK-NEXT: SETCCm [[COPY]], 1, $noreg, -16, $noreg, 4, implicit $eflags
896 ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
897 ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags
898 ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags
899 ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags
900 ; CHECK-NEXT: JMP_1 %bb.2
903 ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42
904 ; CHECK-NEXT: $eax = COPY [[MOV32ri]]
905 ; CHECK-NEXT: RET 0, $eax
908 ; CHECK-NEXT: [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 43
909 ; CHECK-NEXT: $eax = COPY [[MOV32ri1]]
910 ; CHECK-NEXT: RET 0, $eax
912 successors: %bb.1, %bb.2
917 CMP64rr %0, %1, implicit-def $eflags
918 SETCCm %0, 1, $noreg, -16, $noreg, 4, implicit $eflags
919 %2:gr64 = COPY $eflags
921 INLINEASM &nop, 1, 12, implicit-def dead $eflags
924 JCC_1 %bb.1, 4, implicit $eflags