| # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5 |
| # RUN: llc -mtriple=x86_64 -run-pass x86-flags-copy-lowering -verify-machineinstrs -o - %s | FileCheck %s |
| # Lower various interesting copy patterns of EFLAGS without using LAHF/SAHF. |
| |
| ... |
| --- |
| name: test_branch |
| body: | |
| ; CHECK-LABEL: name: test_branch |
| ; CHECK: bb.0: |
| ; CHECK-NEXT: successors: %bb.1(0x2aaaaaab), %bb.4(0x55555556) |
| ; CHECK-NEXT: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.4: |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.3 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.1: |
| ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42 |
| ; CHECK-NEXT: $eax = COPY [[MOV32ri]] |
| ; CHECK-NEXT: RET 0, $eax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.2: |
| ; CHECK-NEXT: [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 43 |
| ; CHECK-NEXT: $eax = COPY [[MOV32ri1]] |
| ; CHECK-NEXT: RET 0, $eax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.3: |
| ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags |
| ; CHECK-NEXT: $eax = COPY [[MOV32r0_]] |
| ; CHECK-NEXT: RET 0, $eax |
| bb.0: |
| successors: %bb.1, %bb.2, %bb.3 |
| liveins: $rdi, $rsi |
| |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| %2:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %2 |
| JCC_1 %bb.1, 7, implicit $eflags |
| JCC_1 %bb.2, 2, implicit $eflags |
| JMP_1 %bb.3 |
| |
| bb.1: |
| %3:gr32 = MOV32ri 42 |
| $eax = COPY %3 |
| RET 0, $eax |
| |
| bb.2: |
| %4:gr32 = MOV32ri 43 |
| $eax = COPY %4 |
| RET 0, $eax |
| |
| bb.3: |
| %5:gr32 = MOV32r0 implicit-def dead $eflags |
| $eax = COPY %5 |
| RET 0, $eax |
| |
| ... |
| --- |
| name: test_branch_fallthrough |
| body: | |
| ; CHECK-LABEL: name: test_branch_fallthrough |
| ; CHECK: bb.0: |
| ; CHECK-NEXT: successors: %bb.4(0x55555556), %bb.2(0x2aaaaaab) |
| ; CHECK-NEXT: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.4: |
| ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.3, 5, implicit killed $eflags |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.1: |
| ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags |
| ; CHECK-NEXT: $eax = COPY [[MOV32r0_]] |
| ; CHECK-NEXT: RET 0, $eax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.2: |
| ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42 |
| ; CHECK-NEXT: $eax = COPY [[MOV32ri]] |
| ; CHECK-NEXT: RET 0, $eax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.3: |
| ; CHECK-NEXT: [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 43 |
| ; CHECK-NEXT: $eax = COPY [[MOV32ri1]] |
| ; CHECK-NEXT: RET 0, $eax |
| bb.0: |
| successors: %bb.1, %bb.2, %bb.3 |
| liveins: $rdi, $rsi |
| |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| %2:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %2 |
| JCC_1 %bb.2, 7, implicit $eflags |
| JCC_1 %bb.3, 2, implicit $eflags |
| |
| bb.1: |
| %5:gr32 = MOV32r0 implicit-def dead $eflags |
| $eax = COPY %5 |
| RET 0, $eax |
| |
| bb.2: |
| %3:gr32 = MOV32ri 42 |
| $eax = COPY %3 |
| RET 0, $eax |
| |
| bb.3: |
| %4:gr32 = MOV32ri 43 |
| $eax = COPY %4 |
| RET 0, $eax |
| |
| ... |
| --- |
| name: test_setcc |
| body: | |
| bb.0: |
| liveins: $rdi, $rsi |
| |
| ; CHECK-LABEL: name: test_setcc |
| ; CHECK: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr3:%[0-9]+]]:gr8 = SETCCr 5, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, [[SETCCr3]] |
| ; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, [[SETCCr]] |
| ; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, [[SETCCr1]] |
| ; CHECK-NEXT: MOV8mr $rsp, 1, $noreg, -16, $noreg, [[SETCCr2]] |
| ; CHECK-NEXT: RET 0 |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| %2:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %2 |
| %3:gr8 = SETCCr 7, implicit $eflags |
| %4:gr8 = SETCCr 2, implicit $eflags |
| %5:gr8 = SETCCr 4, implicit $eflags |
| SETCCm $rsp, 1, $noreg, -16, $noreg, 5, implicit killed $eflags |
| MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %3 |
| MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %4 |
| MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %5 |
| |
| RET 0 |
| |
| ... |
| --- |
| name: test_cmov |
| body: | |
| bb.0: |
| liveins: $rdi, $rsi |
| |
| ; CHECK-LABEL: name: test_cmov |
| ; CHECK: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr1:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr2:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr3:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 4, implicit killed $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr]] |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr1]] |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr2]] |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr3]] |
| ; CHECK-NEXT: RET 0 |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| %2:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %2 |
| %3:gr64 = CMOV64rr %0, %1, 7, implicit $eflags |
| %4:gr64 = CMOV64rr %0, %1, 2, implicit $eflags |
| %5:gr64 = CMOV64rr %0, %1, 4, implicit $eflags |
| %6:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3 |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4 |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5 |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %6 |
| |
| RET 0 |
| |
| ... |
| --- |
| name: test_adc |
| body: | |
| bb.0: |
| liveins: $rdi, $rsi |
| |
| ; CHECK-LABEL: name: test_adc |
| ; CHECK: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags |
| ; CHECK-NEXT: [[ADC64ri32_:%[0-9]+]]:gr64 = ADC64ri32 [[ADD64rr]], 42, implicit-def $eflags, implicit killed $eflags |
| ; CHECK-NEXT: [[ADC64ri32_1:%[0-9]+]]:gr64 = ADC64ri32 [[ADC64ri32_]], 42, implicit-def $eflags, implicit $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[ADC64ri32_1]] |
| ; CHECK-NEXT: RET 0 |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| %2:gr64 = ADD64rr %0, %1, implicit-def $eflags |
| %3:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %3 |
| %4:gr64 = ADC64ri32 %2:gr64, 42, implicit-def $eflags, implicit $eflags |
| %5:gr64 = ADC64ri32 %4:gr64, 42, implicit-def $eflags, implicit $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5 |
| |
| RET 0 |
| |
| ... |
| --- |
| name: test_sbb |
| body: | |
| bb.0: |
| liveins: $rdi, $rsi |
| |
| ; CHECK-LABEL: name: test_sbb |
| ; CHECK: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: [[SUB64rr:%[0-9]+]]:gr64 = SUB64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags |
| ; CHECK-NEXT: [[SBB64ri32_:%[0-9]+]]:gr64 = SBB64ri32 [[SUB64rr]], 42, implicit-def $eflags, implicit killed $eflags |
| ; CHECK-NEXT: [[SBB64ri32_1:%[0-9]+]]:gr64 = SBB64ri32 [[SBB64ri32_]], 42, implicit-def dead $eflags, implicit killed $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[SBB64ri32_1]] |
| ; CHECK-NEXT: RET 0 |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| %2:gr64 = SUB64rr %0, %1, implicit-def $eflags |
| %3:gr64 = COPY killed $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %3 |
| %4:gr64 = SBB64ri32 %2:gr64, 42, implicit-def $eflags, implicit killed $eflags |
| %5:gr64 = SBB64ri32 %4:gr64, 42, implicit-def dead $eflags, implicit killed $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5 |
| |
| RET 0 |
| |
| ... |
| --- |
| name: test_rcl |
| body: | |
| bb.0: |
| liveins: $rdi, $rsi |
| |
| ; CHECK-LABEL: name: test_rcl |
| ; CHECK: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags |
| ; CHECK-NEXT: [[RCL64r1_:%[0-9]+]]:gr64 = RCL64r1 [[ADD64rr]], implicit-def $eflags, implicit killed $eflags |
| ; CHECK-NEXT: [[RCL64r1_1:%[0-9]+]]:gr64 = RCL64r1 [[RCL64r1_]], implicit-def $eflags, implicit $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[RCL64r1_1]] |
| ; CHECK-NEXT: RET 0 |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| %2:gr64 = ADD64rr %0, %1, implicit-def $eflags |
| %3:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %3 |
| %4:gr64 = RCL64r1 %2:gr64, implicit-def $eflags, implicit $eflags |
| %5:gr64 = RCL64r1 %4:gr64, implicit-def $eflags, implicit $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5 |
| |
| RET 0 |
| |
| ... |
| --- |
| name: test_rcr |
| body: | |
| bb.0: |
| liveins: $rdi, $rsi |
| |
| ; CHECK-LABEL: name: test_rcr |
| ; CHECK: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags |
| ; CHECK-NEXT: [[RCR64r1_:%[0-9]+]]:gr64 = RCR64r1 [[ADD64rr]], implicit-def $eflags, implicit killed $eflags |
| ; CHECK-NEXT: [[RCR64r1_1:%[0-9]+]]:gr64 = RCR64r1 [[RCR64r1_]], implicit-def $eflags, implicit $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[RCR64r1_1]] |
| ; CHECK-NEXT: RET 0 |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| %2:gr64 = ADD64rr %0, %1, implicit-def $eflags |
| %3:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %3 |
| %4:gr64 = RCR64r1 %2:gr64, implicit-def $eflags, implicit $eflags |
| %5:gr64 = RCR64r1 %4:gr64, implicit-def $eflags, implicit $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5 |
| |
| RET 0 |
| |
| ... |
| --- |
| name: test_setb_c |
| body: | |
| bb.0: |
| liveins: $rdi, $rsi |
| |
| ; CHECK-LABEL: name: test_setb_c |
| ; CHECK: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: [[ADD64rr:%[0-9]+]]:gr64 = ADD64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags |
| ; CHECK-NEXT: [[SETB_C32r:%[0-9]+]]:gr32 = SETB_C32r implicit-def $eflags, implicit killed $eflags |
| ; CHECK-NEXT: MOV32mr $rsp, 1, $noreg, -16, $noreg, killed [[SETB_C32r]] |
| ; CHECK-NEXT: dead [[ADD8ri1:%[0-9]+]]:gr8 = ADD8ri [[SETCCr]], 255, implicit-def $eflags |
| ; CHECK-NEXT: [[SETB_C64r:%[0-9]+]]:gr64 = SETB_C64r implicit-def $eflags, implicit killed $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[SETB_C64r]] |
| ; CHECK-NEXT: RET 0 |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| %2:gr64 = ADD64rr %0, %1, implicit-def $eflags |
| %3:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %3 |
| %4:gr32 = SETB_C32r implicit-def $eflags, implicit $eflags |
| MOV32mr $rsp, 1, $noreg, -16, $noreg, killed %4 |
| |
| $eflags = COPY %3 |
| %5:gr64 = SETB_C64r implicit-def $eflags, implicit $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5 |
| |
| RET 0 |
| |
| ... |
| --- |
| name: test_branch_with_livein_and_kill |
| body: | |
| ; CHECK-LABEL: name: test_branch_with_livein_and_kill |
| ; CHECK: bb.0: |
| ; CHECK-NEXT: successors: %bb.1(0x2aaaaaab), %bb.4(0x55555556) |
| ; CHECK-NEXT: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 8, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 5, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr3:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.4: |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr3]], [[SETCCr3]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.3 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.1: |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 4, implicit killed $eflags |
| ; CHECK-NEXT: $rax = COPY [[CMOV64rr]] |
| ; CHECK-NEXT: RET 0, $rax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.2: |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr1:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: $rax = COPY [[CMOV64rr1]] |
| ; CHECK-NEXT: RET 0, $rax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.3: |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr2:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: $rax = COPY [[CMOV64rr2]] |
| ; CHECK-NEXT: RET 0, $rax |
| bb.0: |
| successors: %bb.1, %bb.2, %bb.3 |
| liveins: $rdi, $rsi |
| |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| %2:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %2 |
| JCC_1 %bb.1, 7, implicit $eflags |
| JCC_1 %bb.2, 2, implicit $eflags |
| JMP_1 %bb.3 |
| |
| bb.1: |
| liveins: $eflags |
| |
| %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags |
| $rax = COPY %3 |
| RET 0, $rax |
| |
| bb.2: |
| liveins: $eflags |
| |
| %4:gr64 = CMOV64rr %0, %1, 5, implicit killed $eflags |
| $rax = COPY %4 |
| RET 0, $rax |
| |
| bb.3: |
| liveins: $eflags |
| |
| %5:gr64 = CMOV64rr %0, %1, 8, implicit killed $eflags |
| $rax = COPY %5 |
| RET 0, $rax |
| |
| ... |
| --- |
| name: test_branch_with_interleaved_livein_and_kill |
| body: | |
| ; CHECK-LABEL: name: test_branch_with_interleaved_livein_and_kill |
| ; CHECK: bb.0: |
| ; CHECK-NEXT: successors: %bb.1(0x2aaaaaab), %bb.6(0x55555556) |
| ; CHECK-NEXT: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 8, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 10, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 5, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr3:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr4:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr5:%[0-9]+]]:gr8 = SETCCr 0, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr3]], [[SETCCr3]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.6: |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.5(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr4]], [[SETCCr4]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.5 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.1: |
| ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 4, implicit killed $eflags |
| ; CHECK-NEXT: $rax = COPY [[CMOV64rr]] |
| ; CHECK-NEXT: RET 0, $rax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.2: |
| ; CHECK-NEXT: successors: %bb.3(0x40000000), %bb.4(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr5]], [[SETCCr5]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.3, 5, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.4 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.3: |
| ; CHECK-NEXT: TEST8rr [[SETCCr2]], [[SETCCr2]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr1:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: $rax = COPY [[CMOV64rr1]] |
| ; CHECK-NEXT: RET 0, $rax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.4: |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr2:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: $rax = COPY [[CMOV64rr2]] |
| ; CHECK-NEXT: RET 0, $rax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.5: |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr3:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: $rax = COPY [[CMOV64rr3]] |
| ; CHECK-NEXT: RET 0, $rax |
| bb.0: |
| successors: %bb.1, %bb.2, %bb.5 |
| liveins: $rdi, $rsi |
| |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| %2:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %2 |
| JCC_1 %bb.1, 7, implicit $eflags |
| JCC_1 %bb.2, 2, implicit $eflags |
| JMP_1 %bb.5 |
| |
| bb.1: |
| liveins: $eflags |
| |
| %3:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags |
| $rax = COPY %3 |
| RET 0, $rax |
| |
| bb.2: |
| successors: %bb.3, %bb.4 |
| liveins: $eflags |
| |
| JCC_1 %bb.3, 0, implicit $eflags |
| JMP_1 %bb.4 |
| |
| bb.3: |
| liveins: $eflags |
| |
| %4:gr64 = CMOV64rr %0, %1, 5, implicit $eflags |
| $rax = COPY %4 |
| RET 0, $rax |
| |
| bb.4: |
| liveins: $eflags |
| |
| %5:gr64 = CMOV64rr %0, %1, 10, implicit $eflags |
| $rax = COPY %5 |
| RET 0, $rax |
| |
| bb.5: |
| liveins: $eflags |
| |
| %6:gr64 = CMOV64rr %0, %1, 8, implicit killed $eflags |
| $rax = COPY %6 |
| RET 0, $rax |
| |
| ... |
| --- |
| # This test case is designed to exercise a particularly challenging situation: |
| # when the flags are copied and restored *inside* of a complex and cyclic CFG |
| # all of which have live-in flags. To correctly handle this case we have to walk |
| # up the dominator tree and locate a viable reaching definition location, |
| # checking for clobbers along any path. The CFG for this function looks like the |
| # following diagram, control flowing out the bottom of blocks and in the top: |
| # |
| # bb.0 |
| # | __________________ |
| # |/ \ |
| # bb.1 | |
| # |\_________ | |
| # | __ \ ____ | |
| # |/ \ |/ \ | |
| # bb.2 | bb.4 | | |
| # |\__/ / \ | | |
| # | / \ | | |
| # bb.3 bb.5 bb.6 | | |
| # | \ / | | |
| # | \ / | | |
| # | bb.7 | | |
| # | ________/ \____/ | |
| # |/ | |
| # bb.8 | |
| # |\__________________/ |
| # | |
| # bb.9 |
| # |
| # We set EFLAGS in bb.0, clobber them in bb.3, and copy them in bb.2 and bb.6. |
| # Because of the cycles this requires hoisting the `SETcc` instructions to |
| # capture the flags for the bb.6 copy to bb.1 and using them for the copy in |
| # `bb.2` as well despite the clobber in `bb.3`. The clobber in `bb.3` also |
| # prevents hoisting the `SETcc`s up to `bb.0`. |
| # |
| # Throughout the test we use branch instructions that are totally bogus (as the |
| # flags are obviously not changing!) but this is just to allow us to send |
| # a small but complex CFG structure through the backend and force it to choose |
| # plausible lowering decisions based on the core CFG presented, regardless of |
| # the futility of the actual branches. |
| name: test_mid_cycle_copies |
| body: | |
| ; CHECK-LABEL: name: test_mid_cycle_copies |
| ; CHECK: bb.0: |
| ; CHECK-NEXT: successors: %bb.1(0x80000000) |
| ; CHECK-NEXT: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: JMP_1 %bb.1 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.1: |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.4(0x40000000) |
| ; CHECK-NEXT: liveins: $eflags |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr2:%[0-9]+]]:gr8 = SETCCr 2, implicit $eflags |
| ; CHECK-NEXT: JCC_1 %bb.2, 4, implicit $eflags |
| ; CHECK-NEXT: JMP_1 %bb.4 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.2: |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.2, 5, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.3 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.3: |
| ; CHECK-NEXT: successors: %bb.8(0x80000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: dead [[ADD8ri:%[0-9]+]]:gr8 = ADD8ri [[SETCCr2]], 255, implicit-def $eflags |
| ; CHECK-NEXT: [[ADC64ri32_:%[0-9]+]]:gr64 = ADC64ri32 [[COPY]], 42, implicit-def dead $eflags, implicit killed $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[ADC64ri32_]] |
| ; CHECK-NEXT: JMP_1 %bb.8 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.4: |
| ; CHECK-NEXT: successors: %bb.5(0x40000000), %bb.6(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.5, 5, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.6 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.5: |
| ; CHECK-NEXT: successors: %bb.7(0x80000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr]] |
| ; CHECK-NEXT: JMP_1 %bb.7 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.6: |
| ; CHECK-NEXT: successors: %bb.7(0x80000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr1:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr1]] |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: [[CMOV64rr2:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 5, implicit killed $eflags |
| ; CHECK-NEXT: MOV64mr $rsp, 1, $noreg, -16, $noreg, killed [[CMOV64rr2]] |
| ; CHECK-NEXT: JMP_1 %bb.7 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.7: |
| ; CHECK-NEXT: successors: %bb.4(0x40000000), %bb.8(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.4, 5, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.8 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.8: |
| ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.9(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.1, 4, implicit $eflags |
| ; CHECK-NEXT: JMP_1 %bb.9 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.9: |
| ; CHECK-NEXT: liveins: $eflags |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[CMOV64rr3:%[0-9]+]]:gr64 = CMOV64rr [[COPY]], [[COPY1]], 4, implicit killed $eflags |
| ; CHECK-NEXT: $rax = COPY [[CMOV64rr3]] |
| ; CHECK-NEXT: RET 0, $rax |
| bb.0: |
| successors: %bb.1 |
| liveins: $rdi, $rsi |
| |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| JMP_1 %bb.1 |
| |
| bb.1: |
| successors: %bb.2, %bb.4 |
| liveins: $eflags |
| |
| JCC_1 %bb.2, 4, implicit $eflags |
| JMP_1 %bb.4 |
| |
| bb.2: |
| successors: %bb.2, %bb.3 |
| liveins: $eflags |
| |
| %2:gr64 = COPY $eflags |
| $eflags = COPY %2 |
| JCC_1 %bb.2, 4, implicit $eflags |
| JMP_1 %bb.3 |
| |
| bb.3: |
| successors: %bb.8 |
| liveins: $eflags |
| |
| %3:gr64 = ADC64ri32 %0, 42, implicit-def dead $eflags, implicit $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %3 |
| JMP_1 %bb.8 |
| |
| bb.4: |
| successors: %bb.5, %bb.6 |
| liveins: $eflags |
| |
| JCC_1 %bb.5, 4, implicit $eflags |
| JMP_1 %bb.6 |
| |
| bb.5: |
| successors: %bb.7 |
| liveins: $eflags |
| |
| %4:gr64 = CMOV64rr %0, %1, 7, implicit $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %4 |
| JMP_1 %bb.7 |
| |
| bb.6: |
| successors: %bb.7 |
| liveins: $eflags |
| |
| %5:gr64 = CMOV64rr %0, %1, 7, implicit $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %5 |
| |
| %6:gr64 = COPY $eflags |
| $eflags = COPY %6:gr64 |
| |
| %7:gr64 = CMOV64rr %0, %1, 7, implicit $eflags |
| MOV64mr $rsp, 1, $noreg, -16, $noreg, killed %7 |
| JMP_1 %bb.7 |
| |
| bb.7: |
| successors: %bb.4, %bb.8 |
| liveins: $eflags |
| |
| JCC_1 %bb.4, 4, implicit $eflags |
| JMP_1 %bb.8 |
| |
| bb.8: |
| successors: %bb.1, %bb.9 |
| |
| CMP64rr %0, %1, implicit-def $eflags |
| JCC_1 %bb.1, 4, implicit $eflags |
| JMP_1 %bb.9 |
| |
| bb.9: |
| liveins: $eflags |
| |
| %8:gr64 = CMOV64rr %0, %1, 4, implicit killed $eflags |
| $rax = COPY %8 |
| RET 0, $rax |
| |
| ... |
| --- |
| name: test_existing_setcc |
| body: | |
| ; CHECK-LABEL: name: test_existing_setcc |
| ; CHECK: bb.0: |
| ; CHECK-NEXT: successors: %bb.1(0x2aaaaaab), %bb.4(0x55555556) |
| ; CHECK-NEXT: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 7, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr1:%[0-9]+]]:gr8 = SETCCr 3, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.4: |
| ; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000) |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: TEST8rr [[SETCCr1]], [[SETCCr1]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.2, 4, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.3 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.1: |
| ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42 |
| ; CHECK-NEXT: $eax = COPY [[MOV32ri]] |
| ; CHECK-NEXT: RET 0, $eax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.2: |
| ; CHECK-NEXT: [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 43 |
| ; CHECK-NEXT: $eax = COPY [[MOV32ri1]] |
| ; CHECK-NEXT: RET 0, $eax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.3: |
| ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags |
| ; CHECK-NEXT: $eax = COPY [[MOV32r0_]] |
| ; CHECK-NEXT: RET 0, $eax |
| bb.0: |
| successors: %bb.1, %bb.2, %bb.3 |
| liveins: $rdi, $rsi |
| |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| %2:gr8 = SETCCr 7, implicit $eflags |
| %3:gr8 = SETCCr 3, implicit $eflags |
| %4:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %4 |
| JCC_1 %bb.1, 7, implicit $eflags |
| JCC_1 %bb.2, 2, implicit $eflags |
| JMP_1 %bb.3 |
| |
| bb.1: |
| %5:gr32 = MOV32ri 42 |
| $eax = COPY %5 |
| RET 0, $eax |
| |
| bb.2: |
| %6:gr32 = MOV32ri 43 |
| $eax = COPY %6 |
| RET 0, $eax |
| |
| bb.3: |
| %7:gr32 = MOV32r0 implicit-def dead $eflags |
| $eax = COPY %7 |
| RET 0, $eax |
| |
| ... |
| --- |
| # We cannot reuse this SETE because it stores the flag directly to memory, |
| # so we have two SETEs here. FIXME: It'd be great if something could fold |
| # these automatically. If not, maybe we want to unfold SETcc instructions |
| # writing to memory so we can reuse them. |
| |
| name: test_existing_setcc_memory |
| body: | |
| ; CHECK-LABEL: name: test_existing_setcc_memory |
| ; CHECK: bb.0: |
| ; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000) |
| ; CHECK-NEXT: liveins: $rdi, $rsi |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdi |
| ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi |
| ; CHECK-NEXT: CMP64rr [[COPY]], [[COPY1]], implicit-def $eflags |
| ; CHECK-NEXT: SETCCm [[COPY]], 1, $noreg, -16, $noreg, 4, implicit $eflags |
| ; CHECK-NEXT: [[SETCCr:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags |
| ; CHECK-NEXT: INLINEASM &nop, 1 /* sideeffect attdialect */, 12 /* clobber */, implicit-def dead $eflags |
| ; CHECK-NEXT: TEST8rr [[SETCCr]], [[SETCCr]], implicit-def $eflags |
| ; CHECK-NEXT: JCC_1 %bb.1, 5, implicit killed $eflags |
| ; CHECK-NEXT: JMP_1 %bb.2 |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.1: |
| ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 42 |
| ; CHECK-NEXT: $eax = COPY [[MOV32ri]] |
| ; CHECK-NEXT: RET 0, $eax |
| ; CHECK-NEXT: {{ $}} |
| ; CHECK-NEXT: bb.2: |
| ; CHECK-NEXT: [[MOV32ri1:%[0-9]+]]:gr32 = MOV32ri 43 |
| ; CHECK-NEXT: $eax = COPY [[MOV32ri1]] |
| ; CHECK-NEXT: RET 0, $eax |
| bb.0: |
| successors: %bb.1, %bb.2 |
| liveins: $rdi, $rsi |
| |
| %0:gr64 = COPY $rdi |
| %1:gr64 = COPY $rsi |
| CMP64rr %0, %1, implicit-def $eflags |
| SETCCm %0, 1, $noreg, -16, $noreg, 4, implicit $eflags |
| %2:gr64 = COPY $eflags |
| |
| INLINEASM &nop, 1, 12, implicit-def dead $eflags |
| |
| $eflags = COPY %2 |
| JCC_1 %bb.1, 4, implicit $eflags |
| JMP_1 %bb.2 |
| |
| bb.1: |
| %3:gr32 = MOV32ri 42 |
| $eax = COPY %3 |
| RET 0, $eax |
| |
| bb.2: |
| %4:gr32 = MOV32ri 43 |
| $eax = COPY %4 |
| RET 0, $eax |
| |
| ... |