llvm-project/llvm/test/CodeGen/X86/optimize-compare.mir
Feng Zou 7a424276de
Revert "[X86][APX] Support peephole optimization with CCMP instruction (#129994)" (#136796)
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
```
2025-04-25 10:55:31 +08:00

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
...