
This reverts commit 7ae75851b2e1570662261c97c13cfc65357c283d. There is a problem with peephole optimization for CCMP instruction. See the example below: C source code: ``` if (a > 2 || (b && (a == 2))) { … } ``` MIR before peephole optimization: ``` TEST8rr %21:gr8, %21:gr8, implicit-def $eflags // b CCMP32ri %30:gr32, 2, 0, 5, implicit-def $eflags, implicit $eflags // a == 2 CCMP32ri %30:gr32, 3, 0, 5, implicit-def $eflags, implicit $eflags // a > 2 (transformed to a < 3) JCC_1 %bb.6, 2, implicit $eflags JMP_1 %bb.3 ``` Inputs: ``` a = 1, b = 0. ``` With the inputs above, the expected behavior is to jump to %bb.6 BB. After TEST8rr instruction being executed with b(%21) == 0, the ZF bit is set to 1 in eflags, so the eflags doesn't satisfy SCC condition in the following CCMP32ri instruction (for a==2 condition) which skips compare a(%30) with 2 and set flags in its payload to 0x202 (ZF = 0). The eflags satisfies the SCC condition in the 2nd CCMP32ri instruction which compares a(%30) with 3. It sets CF to 1 in eflags and the JCC instruction jumps to %bb.6 BB. But after adding CCMP support, peephole optimization eliminates the 2nd CCMP32ri instruction and updates the condition of JCC instruction to "BE" from "B". With the same inputs, JCC instruction falls through to the next instruction. It's not expected and the 2nd CCMP32ri should not be eliminated. ``` TEST8rr %21:gr8, %21:gr8, implicit-def $eflags // b CCMP32ri %30:gr32, 2, 0, 5, implicit-def $eflags, implicit $eflags // a == 2 JCC_1 %bb.6, 6, implicit $eflags JMP_1 %bb.3 ```
744 lines
25 KiB
YAML
744 lines
25 KiB
YAML
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
# RUN: llc -o - %s -mtriple=x86_64-- -run-pass peephole-opt | FileCheck %s
|
|
|
|
---
|
|
name: opt_zerocmp_0
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_zerocmp_0
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: [[XOR32ri:%[0-9]+]]:gr32 = XOR32ri [[COPY]], i32 1234, implicit-def $eflags
|
|
; CHECK-NEXT: $al = SETCCr 5, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
%1:gr32 = XOR32ri %0, i32 1234, implicit-def $eflags
|
|
; TEST should be removed.
|
|
TEST32rr %1, %1, implicit-def $eflags
|
|
$al = SETCCr 5, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_zerocmp_1
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_zerocmp_1
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: [[DEC64r:%[0-9]+]]:gr64 = DEC64r [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: [[LEA64r:%[0-9]+]]:gr64 = LEA64r [[DEC64r]], 5, $noreg, 12, $noreg
|
|
; CHECK-NEXT: $al = SETCCr 4, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
%1:gr64 = DEC64r %0, implicit-def $eflags
|
|
; CMP should be removed.
|
|
CMP64ri32 %1, 0, implicit-def $eflags
|
|
%2:gr64 = LEA64r %1, 5, $noreg, 12, $noreg
|
|
$al = SETCCr 4, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_multiple_blocks
|
|
tracksRegLiveness: true
|
|
body: |
|
|
; CHECK-LABEL: name: opt_multiple_blocks
|
|
; CHECK: bb.0:
|
|
; CHECK-NEXT: successors: %bb.1(0x80000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY undef $rsi
|
|
; CHECK-NEXT: [[INC64r:%[0-9]+]]:gr64 = INC64r [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: PUSH64r undef $rcx, implicit-def $rsp, implicit $rsp
|
|
; CHECK-NEXT: $rcx = POP64r implicit-def $rsp, implicit $rsp
|
|
; CHECK-NEXT: JMP_1 %bb.1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.1:
|
|
; CHECK-NEXT: liveins: $eflags
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[LEA64r:%[0-9]+]]:gr64 = LEA64r [[INC64r]], 5, $noreg, 12, $noreg
|
|
; CHECK-NEXT: $al = SETCCr 4, implicit $eflags
|
|
bb.0:
|
|
%0:gr64 = COPY undef $rsi
|
|
%1:gr64 = INC64r %0, implicit-def $eflags
|
|
PUSH64r undef $rcx, implicit-def $rsp, implicit $rsp
|
|
$rcx = POP64r implicit-def $rsp, implicit $rsp
|
|
JMP_1 %bb.1
|
|
|
|
bb.1:
|
|
; TEST should be removed.
|
|
TEST64rr %1, %1, implicit-def $eflags
|
|
%2:gr64 = LEA64r %1, 5, $noreg, 12, $noreg
|
|
$al = SETCCr 4, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_multiple_blocks_noopt_0
|
|
body: |
|
|
; CHECK-LABEL: name: opt_multiple_blocks_noopt_0
|
|
; CHECK: bb.0:
|
|
; CHECK-NEXT: successors: %bb.1(0x80000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY undef $rsi
|
|
; CHECK-NEXT: [[INC64r:%[0-9]+]]:gr64 = INC64r [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: JMP_1 %bb.1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.1:
|
|
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: TEST64rr [[INC64r]], [[INC64r]], implicit-def $eflags
|
|
; CHECK-NEXT: [[LEA64r:%[0-9]+]]:gr64 = LEA64r [[INC64r]], 5, $noreg, 12, $noreg
|
|
; CHECK-NEXT: $al = SETCCr 4, implicit $eflags
|
|
; CHECK-NEXT: JCC_1 %bb.1, 2, implicit $eflags
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.2:
|
|
bb.0:
|
|
%0:gr64 = COPY undef $rsi
|
|
%1:gr64 = INC64r %0, implicit-def $eflags
|
|
JMP_1 %bb.1
|
|
|
|
bb.1:
|
|
; The TEST64rr should not be removed, since there are multiple preds.
|
|
TEST64rr %1, %1, implicit-def $eflags
|
|
%2:gr64 = LEA64r %1, 5, $noreg, 12, $noreg
|
|
$al = SETCCr 4, implicit $eflags
|
|
JCC_1 %bb.1, 2, implicit $eflags
|
|
|
|
bb.2:
|
|
...
|
|
---
|
|
name: opt_multiple_blocks_noopt_1
|
|
body: |
|
|
; CHECK-LABEL: name: opt_multiple_blocks_noopt_1
|
|
; CHECK: bb.0:
|
|
; CHECK-NEXT: successors: %bb.1(0x80000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: JMP_1 %bb.1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.1:
|
|
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY undef $rsi
|
|
; CHECK-NEXT: TEST64rr [[COPY]], [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: JCC_1 %bb.1, 2, implicit $eflags
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.2:
|
|
; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def $eflags
|
|
; CHECK-NEXT: TEST64rr [[COPY]], [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: $al = SETCCr 4, implicit $eflags
|
|
bb.0:
|
|
JMP_1 %bb.1
|
|
|
|
bb.1:
|
|
%0:gr64 = COPY undef $rsi
|
|
TEST64rr %0, %0, implicit-def $eflags
|
|
JCC_1 %bb.1, 2, implicit $eflags
|
|
|
|
bb.2:
|
|
; We should not move MOV32r0 up into the loop (that would be correct but
|
|
; slow).
|
|
%1:gr32 = MOV32r0 implicit-def $eflags
|
|
; TEST should not be removed because of MOV32r0.
|
|
TEST64rr %0, %0, implicit-def $eflags
|
|
$al = SETCCr 4, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_zerocmp_user_0
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_zerocmp_user_0
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: [[NEG32r:%[0-9]+]]:gr32 = NEG32r [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: $al = SETCCr 3, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
%1:gr32 = NEG32r %0, implicit-def dead $eflags
|
|
; TEST should be removed.
|
|
TEST32rr %0, %0, implicit-def $eflags
|
|
$al = SETCCr 4, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_0
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_0
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi
|
|
; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[COPY]], [[COPY1]], implicit-def $eflags
|
|
; CHECK-NEXT: $eax = COPY [[SUB32rr]]
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
%1:gr32 = COPY $edi
|
|
%2:gr32 = SUB32rr %0, %1, implicit-def dead $eflags
|
|
$eax = COPY %2
|
|
; CMP should be removed.
|
|
CMP32rr %0, %1, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_1
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_1
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi
|
|
; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[COPY]], [[COPY1]], implicit-def $eflags
|
|
; CHECK-NEXT: $eax = COPY [[SUB32rr]]
|
|
; CHECK-NEXT: $bl = SETCCr 6, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
%1:gr32 = COPY $edi
|
|
%2:gr32 = SUB32rr %0, %1, implicit-def dead $eflags
|
|
$eax = COPY %2
|
|
; CMP should be removed.
|
|
CMP32rr %1, %0, implicit-def $eflags
|
|
$bl = SETCCr 3, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_2
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_2
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi
|
|
; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[COPY]], [[COPY1]], implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: $eax = COPY [[SUB32rr]]
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
%1:gr32 = COPY $edi
|
|
%2:gr32 = SUB32rr %0, %1, implicit-def $eflags
|
|
; an extra eflags reader shouldn't stop optimization.
|
|
$cl = SETCCr 2, implicit $eflags
|
|
$eax = COPY %2
|
|
CMP32rr %0, %1, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_cmp_cmp
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_cmp_cmp
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi
|
|
; CHECK-NEXT: CMP32rr [[COPY]], [[COPY1]], implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 7, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
%1:gr32 = COPY $edi
|
|
CMP32rr %0, %1, implicit-def $eflags
|
|
$cl = SETCCr 2, implicit $eflags
|
|
; 2nd CMP should be removed.
|
|
CMP32rr %1, %0, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_cmp_cmp_2
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_cmp_cmp_2
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rdi
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], 15, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
%1:gr64 = COPY $rdi
|
|
CMP64ri32 %0, 15, implicit-def $eflags
|
|
$cl = SETCCr 2, implicit $eflags
|
|
; 2nd CMP should be removed.
|
|
CMP64ri32 %0, 15, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_test_test
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_test_test
|
|
; CHECK: [[COPY:%[0-9]+]]:gr16 = COPY $ax
|
|
; CHECK-NEXT: TEST16rr [[COPY]], [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr16 = COPY $ax
|
|
TEST16rr %0, %0, implicit-def $eflags
|
|
$cl = SETCCr 2, implicit $eflags
|
|
; 2nd CMP should be removed.
|
|
TEST16rr %0, %0, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_cmp_sub
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_cmp_sub
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi
|
|
; CHECK-NEXT: CMP32rr [[COPY]], [[COPY1]], implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 7, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
%1:gr32 = COPY $edi
|
|
CMP32rr %0, %1, implicit-def $eflags
|
|
$cl = SETCCr 2, implicit $eflags
|
|
; SUB should be removed.
|
|
dead %2:gr32 = SUB32rr %1, %0, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_cmp_sub_2
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_cmp_sub_2
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: CMP32ri [[COPY]], -12345, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
CMP32ri %0, -12345, implicit-def $eflags
|
|
$cl = SETCCr 2, implicit $eflags
|
|
; SUB should be removed
|
|
dead %2:gr32 = SUB32ri %0, -12345, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_cmp_sub_noopt
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_cmp_sub_noopt
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $edi
|
|
; CHECK-NEXT: CMP32rr [[COPY]], [[COPY1]], implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: [[SUB32rr:%[0-9]+]]:gr32 = SUB32rr [[COPY]], [[COPY1]], implicit-def $eflags
|
|
; CHECK-NEXT: $rdx = COPY [[SUB32rr]]
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
%1:gr32 = COPY $edi
|
|
CMP32rr %0, %1, implicit-def $eflags
|
|
$cl = SETCCr 2, implicit $eflags
|
|
; cannot optimize the SUB because the result value is used.
|
|
%2:gr32 = SUB32rr %0, %1, implicit-def $eflags
|
|
$rdx = COPY %2
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_cmp_test
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_cmp_test
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 0, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
CMP32ri %0, 0, implicit-def $eflags
|
|
$cl = SETCCr 2, implicit $eflags
|
|
; TEST should be removed
|
|
TEST32rr %0, %0, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_test_cmp
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_test_cmp
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: TEST32rr [[COPY]], [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
TEST32rr %0, %0, implicit-def $eflags
|
|
$cl = SETCCr 2, implicit $eflags
|
|
; TEST should be removed
|
|
CMP32ri %0, 0, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_cmp_addr
|
|
stack:
|
|
- { id: 0, size: 4, alignment: 4 }
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_cmp_addr
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], @opt_redundant_flags_cmp_addr + 4, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 7, implicit $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 3, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
CMP64ri32 %0, @opt_redundant_flags_cmp_addr + 4, implicit-def $eflags
|
|
$cl = SETCCr 7, implicit $eflags
|
|
; CMP should be removed
|
|
CMP64ri32 %0, @opt_redundant_flags_cmp_addr + 4, implicit-def $eflags
|
|
$cl = SETCCr 3, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_cmp_addr_noopt
|
|
stack:
|
|
- { id: 0, size: 4, alignment: 4 }
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_cmp_addr_noopt
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], @opt_redundant_flags_cmp_addr_noopt + 24, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 7, implicit $eflags
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], 24, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 3, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
CMP64ri32 %0, @opt_redundant_flags_cmp_addr_noopt + 24, implicit-def $eflags
|
|
$cl = SETCCr 7, implicit $eflags
|
|
; CMP should not be removed
|
|
CMP64ri32 %0, 24, implicit-def $eflags
|
|
$cl = SETCCr 3, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_adjusted_imm_0
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_0
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], 1, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 4, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 15, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 7, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 14, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 6, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
; CMP+SETCC %0 == 1
|
|
CMP64ri32 %0, 1, implicit-def $eflags
|
|
$cl = SETCCr 4, implicit $eflags
|
|
; CMP+SETCC %0 >= 2; CMP can be removed.
|
|
CMP64ri32 %0, 2, implicit-def $eflags
|
|
; %0 >=s 2 --> %0 >s 1
|
|
$bl = SETCCr 13, implicit $eflags
|
|
; %0 >=u 2 --> %0 >u 1
|
|
$bl = SETCCr 3, implicit $eflags
|
|
; %0 <s 2 --> %0 <=s 1
|
|
$bl = SETCCr 12, implicit $eflags
|
|
; %0 <u 2 --> %0 <=u 1
|
|
$bl = SETCCr 2, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_adjusted_imm_1
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_1
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], 42, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 5, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 13, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 3, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 12, implicit $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
; CMP+SETCC %0 != 42
|
|
CMP64ri32 %0, 42, implicit-def $eflags
|
|
$cl = SETCCr 5, implicit $eflags
|
|
; CMP+SETCC %0 >= 2; CMP can be removed.
|
|
CMP64ri32 %0, 41, implicit-def $eflags
|
|
; %0 >s 41 --> %0 >=s 42
|
|
$bl = SETCCr 15, implicit $eflags
|
|
; %0 >u 41 --> %0 >=u 42
|
|
$bl = SETCCr 7, implicit $eflags
|
|
; %0 <=s 41 --> %0 <s 42
|
|
$bl = SETCCr 14, implicit $eflags
|
|
; %0 <=u 41 --> %0 <u 42
|
|
$bl = SETCCr 6, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_adjusted_imm_test_cmp
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_test_cmp
|
|
; CHECK: [[COPY:%[0-9]+]]:gr8 = COPY $bl
|
|
; CHECK-NEXT: TEST8rr [[COPY]], [[COPY]], implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 14, implicit $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 7, implicit $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 12, implicit $eflags
|
|
%0:gr8 = COPY $bl
|
|
TEST8rr %0, %0, implicit-def $eflags
|
|
; SET %0 <=s 0
|
|
$cl = SETCCr 14, implicit $eflags
|
|
; CMP should be removed (%0 >=u 1)
|
|
CMP8ri %0, 1, implicit-def $eflags
|
|
$cl = SETCCr 3, implicit $eflags
|
|
|
|
; CMP should be removed (%0 <=s -1)
|
|
CMP8ri %0, -1, implicit-def $eflags
|
|
$cl = SETCCr 14, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_adjusted_imm_cmp_test
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_cmp_test
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], 1, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 13, implicit $eflags
|
|
; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $edi
|
|
; CHECK-NEXT: CMP64ri32 [[COPY1]], -1, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 14, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
CMP64ri32 %0, 1, implicit-def $eflags
|
|
; TEST should be removed
|
|
TEST64rr %0, %0, implicit-def $eflags
|
|
$cl = SETCCr 15, implicit $eflags
|
|
|
|
%1:gr64 = COPY $edi
|
|
CMP64ri32 %1, -1, implicit-def $eflags
|
|
; TEST should be removed
|
|
TEST64rr %1, %1, implicit-def $eflags
|
|
$cl = SETCCr 12, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_adjusted_imm_noopt_0
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_noopt_0
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], 42, implicit-def $eflags
|
|
; CHECK-NEXT: $cl = SETCCr 4, implicit $eflags
|
|
; CHECK-NEXT: CMP64ri32 [[COPY]], 41, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 4, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
; CMP+SETCC %0 <s 1
|
|
CMP64ri32 %0, 42, implicit-def $eflags
|
|
$cl = SETCCr 4, implicit $eflags
|
|
; CMP should not be removed.
|
|
CMP64ri32 %0, 41, implicit-def $eflags
|
|
; %0 == 41
|
|
$bl = SETCCr 4, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_adjusted_imm_noopt_1
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_noopt_1
|
|
; CHECK: [[COPY:%[0-9]+]]:gr32 = COPY $esi
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 2147483647, implicit-def $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], -2147483648, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 12, implicit $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 4294967295, implicit-def $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], -2147483648, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 12, implicit $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 2147483647, implicit-def $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], -2147483648, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 13, implicit $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 4294967295, implicit-def $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 0, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 2, implicit $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 4294967295, implicit-def $eflags
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 0, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 3, implicit $eflags
|
|
%0:gr32 = COPY $esi
|
|
; CMP+SETCC %0 == INT32_MAX
|
|
CMP32ri %0, 2147483647, implicit-def $eflags
|
|
; CMP should not be removed.
|
|
CMP32ri %0, -2147483648, implicit-def $eflags
|
|
; %0 <s INT32_MIN
|
|
$bl = SETCCr 12, implicit $eflags
|
|
|
|
CMP32ri %0, 4294967295, implicit-def $eflags
|
|
; CMP should not be removed.
|
|
CMP32ri %0, -2147483648, implicit-def $eflags
|
|
$bl = SETCCr 12, implicit $eflags
|
|
|
|
CMP32ri %0, 2147483647, implicit-def $eflags
|
|
; CMP should not be removed.
|
|
CMP32ri %0, -2147483648, implicit-def $eflags
|
|
$bl = SETCCr 13, implicit $eflags
|
|
|
|
CMP32ri %0, 4294967295, implicit-def $eflags
|
|
; should not be removed
|
|
CMP32ri %0, 0, implicit-def $eflags
|
|
$bl = SETCCr 2, implicit $eflags
|
|
|
|
CMP32ri %0, 4294967295, implicit-def $eflags
|
|
; should not be removed
|
|
CMP32ri %0, 0, implicit-def $eflags
|
|
$bl = SETCCr 3, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_redundant_flags_adjusted_imm_noopt_2
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_redundant_flags_adjusted_imm_noopt_2
|
|
; CHECK: [[COPY:%[0-9]+]]:gr16 = COPY $cx
|
|
; CHECK-NEXT: CMP16ri [[COPY]], -32768, implicit-def $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], 32767, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 15, implicit $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], 65535, implicit-def $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], 32767, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 15, implicit $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], -32768, implicit-def $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], 32767, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 14, implicit $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], 0, implicit-def $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], 65535, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 4, implicit $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], 0, implicit-def $eflags
|
|
; CHECK-NEXT: CMP16ri [[COPY]], 65535, implicit-def $eflags
|
|
; CHECK-NEXT: $bl = SETCCr 6, implicit $eflags
|
|
%0:gr16 = COPY $cx
|
|
; CMP+SETCC %0 == INT16_MIN
|
|
CMP16ri %0, -32768, implicit-def $eflags
|
|
; CMP should not be removed.
|
|
CMP16ri %0, 32767, implicit-def $eflags
|
|
; %0 >s INT16_MAX
|
|
$bl = SETCCr 15, implicit $eflags
|
|
|
|
CMP16ri %0, 65535, implicit-def $eflags
|
|
; CMP should not be removed.
|
|
CMP16ri %0, 32767, implicit-def $eflags
|
|
$bl = SETCCr 15, implicit $eflags
|
|
|
|
CMP16ri %0, -32768, implicit-def $eflags
|
|
; CMP should not be removed.
|
|
CMP16ri %0, 32767, implicit-def $eflags
|
|
$bl = SETCCr 14, implicit $eflags
|
|
|
|
CMP16ri %0, 0, implicit-def $eflags
|
|
; should not be removed
|
|
CMP16ri %0, 65535, implicit-def $eflags
|
|
$bl = SETCCr 4, implicit $eflags
|
|
|
|
CMP16ri %0, 0, implicit-def $eflags
|
|
; should not be removed
|
|
CMP16ri %0, 65535, implicit-def $eflags
|
|
$bl = SETCCr 6, implicit $eflags
|
|
...
|
|
---
|
|
name: opt_adjusted_imm_multiple_blocks
|
|
body: |
|
|
; CHECK-LABEL: name: opt_adjusted_imm_multiple_blocks
|
|
; CHECK: bb.0:
|
|
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $eax
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 20, implicit-def $eflags
|
|
; CHECK-NEXT: JCC_1 %bb.1, 4, implicit $eflags
|
|
; CHECK-NEXT: JMP_1 %bb.3
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.1:
|
|
; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
|
|
; CHECK-NEXT: liveins: $eflags
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: JCC_1 %bb.2, 15, implicit $eflags
|
|
; CHECK-NEXT: JMP_1 %bb.3
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.2:
|
|
; CHECK-NEXT: successors: %bb.3(0x80000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: JMP_1 %bb.3
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.3:
|
|
; CHECK-NEXT: RET 0
|
|
bb.0:
|
|
%0:gr32 = COPY $eax
|
|
CMP32ri %0, 20, implicit-def $eflags
|
|
JCC_1 %bb.1, 4, implicit $eflags
|
|
JMP_1 %bb.3
|
|
|
|
bb.1:
|
|
; CMP can be removed when adjusting the JCC.
|
|
CMP32ri %0, 21, implicit-def $eflags
|
|
JCC_1 %bb.2, 13, implicit $eflags
|
|
JMP_1 %bb.3
|
|
|
|
bb.2:
|
|
JMP_1 %bb.3
|
|
|
|
bb.3:
|
|
RET 0
|
|
...
|
|
---
|
|
name: opt_adjusted_imm_multiple_blocks_noopt
|
|
body: |
|
|
; CHECK-LABEL: name: opt_adjusted_imm_multiple_blocks_noopt
|
|
; CHECK: bb.0:
|
|
; CHECK-NEXT: successors: %bb.1(0x40000000), %bb.3(0x40000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $eax
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 20, implicit-def $eflags
|
|
; CHECK-NEXT: JCC_1 %bb.1, 4, implicit $eflags
|
|
; CHECK-NEXT: JMP_1 %bb.3
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.1:
|
|
; CHECK-NEXT: successors: %bb.2(0x40000000), %bb.3(0x40000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: CMP32ri [[COPY]], 21, implicit-def $eflags
|
|
; CHECK-NEXT: JCC_1 %bb.2, 13, implicit $eflags
|
|
; CHECK-NEXT: JMP_1 %bb.3
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.2:
|
|
; CHECK-NEXT: successors: %bb.3(0x80000000)
|
|
; CHECK-NEXT: liveins: $eflags
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: $al = SETCCr 4, implicit $eflags
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.3:
|
|
; CHECK-NEXT: RET 0
|
|
bb.0:
|
|
%0:gr32 = COPY $eax
|
|
CMP32ri %0, 20, implicit-def $eflags
|
|
JCC_1 %bb.1, 4, implicit $eflags
|
|
JMP_1 %bb.3
|
|
|
|
bb.1:
|
|
; The following CMP should not be optimized because $eflags is live-out
|
|
CMP32ri %0, 21, implicit-def $eflags
|
|
JCC_1 %bb.2, 13, implicit $eflags
|
|
JMP_1 %bb.3
|
|
|
|
bb.2:
|
|
liveins: $eflags
|
|
$al = SETCCr 4, implicit $eflags
|
|
|
|
bb.3:
|
|
RET 0
|
|
...
|
|
---
|
|
name: opt_shift_cmp_zero
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: opt_shift_cmp_zero
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 7, implicit-def $eflags
|
|
; CHECK-NEXT: $al = SETCCr 4, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
%1:gr64 = SHL64ri %0, 7, implicit-def dead $eflags
|
|
; TEST should be removed.
|
|
TEST64rr %1, %1, implicit-def $eflags
|
|
$al = SETCCr 4, implicit $eflags
|
|
...
|
|
---
|
|
name: noopt_shift_cmp_zero
|
|
body: |
|
|
bb.0:
|
|
; CHECK-LABEL: name: noopt_shift_cmp_zero
|
|
; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 9, implicit-def dead $eflags
|
|
; CHECK-NEXT: TEST64rr [[SHL64ri]], [[SHL64ri]], implicit-def $eflags
|
|
; CHECK-NEXT: $al = SETCCr 14, implicit $eflags
|
|
%0:gr64 = COPY $rsi
|
|
%1:gr64 = SHL64ri %0, 9, implicit-def dead $eflags
|
|
; TEST cannot be removed if a user relies on the OF flag.
|
|
TEST64rr %1, %1, implicit-def $eflags
|
|
$al = SETCCr 14, implicit $eflags
|
|
...
|
|
---
|
|
name: noopt_shift_cmp_zero_multiblock
|
|
body: |
|
|
; CHECK-LABEL: name: noopt_shift_cmp_zero_multiblock
|
|
; CHECK: bb.0:
|
|
; CHECK-NEXT: successors: %bb.1(0x80000000)
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rsi
|
|
; CHECK-NEXT: [[SHL64ri:%[0-9]+]]:gr64 = SHL64ri [[COPY]], 9, implicit-def dead $eflags
|
|
; CHECK-NEXT: TEST64rr [[SHL64ri]], [[SHL64ri]], implicit-def $eflags
|
|
; CHECK-NEXT: JMP_1 %bb.1
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: bb.1:
|
|
; CHECK-NEXT: liveins: $eflags
|
|
; CHECK-NEXT: {{ $}}
|
|
; CHECK-NEXT: $al = SETCCr 14, implicit $eflags
|
|
bb.0:
|
|
%0:gr64 = COPY $rsi
|
|
%1:gr64 = SHL64ri %0, 9, implicit-def dead $eflags
|
|
; TEST cannot be removed if a user relies on the OF flag.
|
|
TEST64rr %1, %1, implicit-def $eflags
|
|
JMP_1 %bb.1
|
|
|
|
bb.1:
|
|
liveins: $eflags
|
|
$al = SETCCr 14, implicit $eflags
|
|
...
|