[llvm] 79845ed - [DAG] Fold setcc eq with ashr to compare to zero.

David Green via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 5 06:06:56 PDT 2021


Author: David Green
Date: 2021-09-05T14:06:47+01:00
New Revision: 79845ed6dfc6511f999d4ada21d46d971f8dd724

URL: https://github.com/llvm/llvm-project/commit/79845ed6dfc6511f999d4ada21d46d971f8dd724
DIFF: https://github.com/llvm/llvm-project/commit/79845ed6dfc6511f999d4ada21d46d971f8dd724.diff

LOG: [DAG] Fold setcc eq with ashr to compare to zero.

Pulled out of D109149, this folds set_cc seteq (ashr X, BW-1), -1 ->
set_cc setlt X, 0 to prevent some regressions later on when folding
select_cc setgt X, -1, C, ~C -> xor (ashr X, BW-1), C

Differential Revision: https://reviews.llvm.org/D109214

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
    llvm/test/CodeGen/AArch64/select-constant-xor.ll
    llvm/test/CodeGen/AMDGPU/select-constant-xor.ll
    llvm/test/CodeGen/ARM/select-constant-xor.ll
    llvm/test/CodeGen/PowerPC/select-constant-xor.ll
    llvm/test/CodeGen/RISCV/select-constant-xor.ll
    llvm/test/CodeGen/X86/select-constant-xor.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 18bcd239af321..28996cc06fb3a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -3910,6 +3910,17 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
         return DAG.getSetCC(dl, VT, N0.getOperand(0), N1, Cond);
     }
 
+    // Fold set_cc seteq (ashr X, BW-1), -1 -> set_cc setlt X, 0
+    //  and set_cc setne (ashr X, BW-1), -1 -> set_cc setge X, 0
+    if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
+        N0.getOpcode() == ISD::SRA && isa<ConstantSDNode>(N0.getOperand(1)) &&
+        N0.getConstantOperandAPInt(1) == OpVT.getScalarSizeInBits() - 1 &&
+        N1C && N1C->isAllOnesValue()) {
+      return DAG.getSetCC(dl, VT, N0.getOperand(0),
+                          DAG.getConstant(0, dl, OpVT),
+                          Cond == ISD::SETEQ ? ISD::SETLT : ISD::SETGT);
+    }
+
     if (SDValue V =
             optimizeSetCCOfSignedTruncationCheck(VT, N0, N1, Cond, DCI, dl))
       return V;

diff  --git a/llvm/test/CodeGen/AArch64/select-constant-xor.ll b/llvm/test/CodeGen/AArch64/select-constant-xor.ll
index 728a629b1b330..79d28cdb68634 100644
--- a/llvm/test/CodeGen/AArch64/select-constant-xor.ll
+++ b/llvm/test/CodeGen/AArch64/select-constant-xor.ll
@@ -103,9 +103,8 @@ define i32 @selecti8i32(i8 %a) {
 define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 ; CHECK-LABEL: icmpasreq:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mov w8, #-1
-; CHECK-NEXT:    cmp w8, w0, asr #31
-; CHECK-NEXT:    csel w0, w1, w2, eq
+; CHECK-NEXT:    cmp w0, #0
+; CHECK-NEXT:    csel w0, w1, w2, lt
 ; CHECK-NEXT:    ret
   %sh = ashr i32 %input, 31
   %c = icmp eq i32 %sh, -1
@@ -116,9 +115,8 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ; CHECK-LABEL: icmpasrne:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    mov w8, #-1
-; CHECK-NEXT:    cmp w8, w0, asr #31
-; CHECK-NEXT:    csel w0, w1, w2, ne
+; CHECK-NEXT:    cmp w0, #0
+; CHECK-NEXT:    csel w0, w1, w2, gt
 ; CHECK-NEXT:    ret
   %sh = ashr i32 %input, 31
   %c = icmp ne i32 %sh, -1

diff  --git a/llvm/test/CodeGen/AMDGPU/select-constant-xor.ll b/llvm/test/CodeGen/AMDGPU/select-constant-xor.ll
index 2b0c79a822e17..217feb446fbc8 100644
--- a/llvm/test/CodeGen/AMDGPU/select-constant-xor.ll
+++ b/llvm/test/CodeGen/AMDGPU/select-constant-xor.ll
@@ -123,8 +123,7 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
-; CHECK-NEXT:    v_ashrrev_i32_e32 v0, 31, v0
-; CHECK-NEXT:    v_cmp_eq_u32_e32 vcc_lo, -1, v0
+; CHECK-NEXT:    v_cmp_gt_i32_e32 vcc_lo, 0, v0
 ; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %sh = ashr i32 %input, 31
@@ -138,8 +137,7 @@ define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ; CHECK:       ; %bb.0:
 ; CHECK-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
 ; CHECK-NEXT:    s_waitcnt_vscnt null, 0x0
-; CHECK-NEXT:    v_ashrrev_i32_e32 v0, 31, v0
-; CHECK-NEXT:    v_cmp_ne_u32_e32 vcc_lo, -1, v0
+; CHECK-NEXT:    v_cmp_lt_i32_e32 vcc_lo, 0, v0
 ; CHECK-NEXT:    v_cndmask_b32_e32 v0, v2, v1, vcc_lo
 ; CHECK-NEXT:    s_setpc_b64 s[30:31]
   %sh = ashr i32 %input, 31

diff  --git a/llvm/test/CodeGen/ARM/select-constant-xor.ll b/llvm/test/CodeGen/ARM/select-constant-xor.ll
index 77d7d8b4ec495..730d72c7415a0 100644
--- a/llvm/test/CodeGen/ARM/select-constant-xor.ll
+++ b/llvm/test/CodeGen/ARM/select-constant-xor.ll
@@ -353,17 +353,15 @@ define i32 @selecti8i32(i8 %a) {
 define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 ; CHECK7A-LABEL: icmpasreq:
 ; CHECK7A:       @ %bb.0:
-; CHECK7A-NEXT:    mvn r3, #0
-; CHECK7A-NEXT:    cmp r3, r0, asr #31
-; CHECK7A-NEXT:    movne r1, r2
+; CHECK7A-NEXT:    cmp r0, #0
+; CHECK7A-NEXT:    movpl r1, r2
 ; CHECK7A-NEXT:    mov r0, r1
 ; CHECK7A-NEXT:    bx lr
 ;
 ; CHECK6M-LABEL: icmpasreq:
 ; CHECK6M:       @ %bb.0:
-; CHECK6M-NEXT:    asrs r0, r0, #31
-; CHECK6M-NEXT:    adds r0, r0, #1
-; CHECK6M-NEXT:    beq .LBB8_2
+; CHECK6M-NEXT:    cmp r0, #0
+; CHECK6M-NEXT:    bmi .LBB8_2
 ; CHECK6M-NEXT:  @ %bb.1:
 ; CHECK6M-NEXT:    mov r1, r2
 ; CHECK6M-NEXT:  .LBB8_2:
@@ -372,18 +370,16 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 ;
 ; CHECK7M-LABEL: icmpasreq:
 ; CHECK7M:       @ %bb.0:
-; CHECK7M-NEXT:    asrs r0, r0, #31
-; CHECK7M-NEXT:    adds r0, #1
-; CHECK7M-NEXT:    it ne
-; CHECK7M-NEXT:    movne r1, r2
+; CHECK7M-NEXT:    cmp r0, #0
+; CHECK7M-NEXT:    it pl
+; CHECK7M-NEXT:    movpl r1, r2
 ; CHECK7M-NEXT:    mov r0, r1
 ; CHECK7M-NEXT:    bx lr
 ;
 ; CHECK81M-LABEL: icmpasreq:
 ; CHECK81M:       @ %bb.0:
-; CHECK81M-NEXT:    asrs r0, r0, #31
-; CHECK81M-NEXT:    adds r0, #1
-; CHECK81M-NEXT:    csel r0, r1, r2, eq
+; CHECK81M-NEXT:    cmp r0, #0
+; CHECK81M-NEXT:    csel r0, r1, r2, mi
 ; CHECK81M-NEXT:    bx lr
   %sh = ashr i32 %input, 31
   %c = icmp eq i32 %sh, -1
@@ -394,17 +390,15 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ; CHECK7A-LABEL: icmpasrne:
 ; CHECK7A:       @ %bb.0:
-; CHECK7A-NEXT:    mvn r3, #0
-; CHECK7A-NEXT:    cmp r3, r0, asr #31
-; CHECK7A-NEXT:    moveq r1, r2
+; CHECK7A-NEXT:    cmp r0, #0
+; CHECK7A-NEXT:    movle r1, r2
 ; CHECK7A-NEXT:    mov r0, r1
 ; CHECK7A-NEXT:    bx lr
 ;
 ; CHECK6M-LABEL: icmpasrne:
 ; CHECK6M:       @ %bb.0:
-; CHECK6M-NEXT:    asrs r0, r0, #31
-; CHECK6M-NEXT:    adds r0, r0, #1
-; CHECK6M-NEXT:    bne .LBB9_2
+; CHECK6M-NEXT:    cmp r0, #0
+; CHECK6M-NEXT:    bgt .LBB9_2
 ; CHECK6M-NEXT:  @ %bb.1:
 ; CHECK6M-NEXT:    mov r1, r2
 ; CHECK6M-NEXT:  .LBB9_2:
@@ -413,18 +407,16 @@ define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ;
 ; CHECK7M-LABEL: icmpasrne:
 ; CHECK7M:       @ %bb.0:
-; CHECK7M-NEXT:    asrs r0, r0, #31
-; CHECK7M-NEXT:    adds r0, #1
-; CHECK7M-NEXT:    it eq
-; CHECK7M-NEXT:    moveq r1, r2
+; CHECK7M-NEXT:    cmp r0, #0
+; CHECK7M-NEXT:    it le
+; CHECK7M-NEXT:    movle r1, r2
 ; CHECK7M-NEXT:    mov r0, r1
 ; CHECK7M-NEXT:    bx lr
 ;
 ; CHECK81M-LABEL: icmpasrne:
 ; CHECK81M:       @ %bb.0:
-; CHECK81M-NEXT:    asrs r0, r0, #31
-; CHECK81M-NEXT:    adds r0, #1
-; CHECK81M-NEXT:    csel r0, r1, r2, ne
+; CHECK81M-NEXT:    cmp r0, #0
+; CHECK81M-NEXT:    csel r0, r1, r2, gt
 ; CHECK81M-NEXT:    bx lr
   %sh = ashr i32 %input, 31
   %c = icmp ne i32 %sh, -1

diff  --git a/llvm/test/CodeGen/PowerPC/select-constant-xor.ll b/llvm/test/CodeGen/PowerPC/select-constant-xor.ll
index dd11c522f0e02..fb9df2fcc7d3d 100644
--- a/llvm/test/CodeGen/PowerPC/select-constant-xor.ll
+++ b/llvm/test/CodeGen/PowerPC/select-constant-xor.ll
@@ -113,9 +113,8 @@ define i32 @selecti8i32(i8 %a) {
 define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 ; CHECK-LABEL: icmpasreq:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    srawi 3, 3, 31
-; CHECK-NEXT:    cmpwi 3, -1
-; CHECK-NEXT:    iseleq 3, 4, 5
+; CHECK-NEXT:    cmpwi 3, 0
+; CHECK-NEXT:    isellt 3, 4, 5
 ; CHECK-NEXT:    blr
   %sh = ashr i32 %input, 31
   %c = icmp eq i32 %sh, -1
@@ -126,9 +125,8 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ; CHECK-LABEL: icmpasrne:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    srawi 3, 3, 31
-; CHECK-NEXT:    cmpwi 3, -1
-; CHECK-NEXT:    iseleq 3, 5, 4
+; CHECK-NEXT:    cmpwi 3, 0
+; CHECK-NEXT:    iselgt 3, 4, 5
 ; CHECK-NEXT:    blr
   %sh = ashr i32 %input, 31
   %c = icmp ne i32 %sh, -1

diff  --git a/llvm/test/CodeGen/RISCV/select-constant-xor.ll b/llvm/test/CodeGen/RISCV/select-constant-xor.ll
index ad7a76b69c990..b500b71b62975 100644
--- a/llvm/test/CodeGen/RISCV/select-constant-xor.ll
+++ b/llvm/test/CodeGen/RISCV/select-constant-xor.ll
@@ -202,21 +202,18 @@ define i32 @selecti8i32(i8 %a) {
 define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 ; CHECK32-LABEL: icmpasreq:
 ; CHECK32:       # %bb.0:
-; CHECK32-NEXT:    srai a3, a0, 31
-; CHECK32-NEXT:    addi a4, zero, -1
-; CHECK32-NEXT:    mv a0, a1
-; CHECK32-NEXT:    beq a3, a4, .LBB8_2
+; CHECK32-NEXT:    bltz a0, .LBB8_2
 ; CHECK32-NEXT:  # %bb.1:
-; CHECK32-NEXT:    mv a0, a2
+; CHECK32-NEXT:    mv a1, a2
 ; CHECK32-NEXT:  .LBB8_2:
+; CHECK32-NEXT:    mv a0, a1
 ; CHECK32-NEXT:    ret
 ;
 ; CHECK64-LABEL: icmpasreq:
 ; CHECK64:       # %bb.0:
-; CHECK64-NEXT:    sraiw a3, a0, 31
-; CHECK64-NEXT:    addi a4, zero, -1
+; CHECK64-NEXT:    sext.w a3, a0
 ; CHECK64-NEXT:    mv a0, a1
-; CHECK64-NEXT:    beq a3, a4, .LBB8_2
+; CHECK64-NEXT:    bltz a3, .LBB8_2
 ; CHECK64-NEXT:  # %bb.1:
 ; CHECK64-NEXT:    mv a0, a2
 ; CHECK64-NEXT:  .LBB8_2:
@@ -230,21 +227,18 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ; CHECK32-LABEL: icmpasrne:
 ; CHECK32:       # %bb.0:
-; CHECK32-NEXT:    srai a3, a0, 31
-; CHECK32-NEXT:    addi a4, zero, -1
-; CHECK32-NEXT:    mv a0, a1
-; CHECK32-NEXT:    bne a3, a4, .LBB9_2
+; CHECK32-NEXT:    bgtz a0, .LBB9_2
 ; CHECK32-NEXT:  # %bb.1:
-; CHECK32-NEXT:    mv a0, a2
+; CHECK32-NEXT:    mv a1, a2
 ; CHECK32-NEXT:  .LBB9_2:
+; CHECK32-NEXT:    mv a0, a1
 ; CHECK32-NEXT:    ret
 ;
 ; CHECK64-LABEL: icmpasrne:
 ; CHECK64:       # %bb.0:
-; CHECK64-NEXT:    sraiw a3, a0, 31
-; CHECK64-NEXT:    addi a4, zero, -1
+; CHECK64-NEXT:    sext.w a3, a0
 ; CHECK64-NEXT:    mv a0, a1
-; CHECK64-NEXT:    bne a3, a4, .LBB9_2
+; CHECK64-NEXT:    bgtz a3, .LBB9_2
 ; CHECK64-NEXT:  # %bb.1:
 ; CHECK64-NEXT:    mv a0, a2
 ; CHECK64-NEXT:  .LBB9_2:

diff  --git a/llvm/test/CodeGen/X86/select-constant-xor.ll b/llvm/test/CodeGen/X86/select-constant-xor.ll
index 9f76e99d5c1e4..6e1ffa1a8b0ad 100644
--- a/llvm/test/CodeGen/X86/select-constant-xor.ll
+++ b/llvm/test/CodeGen/X86/select-constant-xor.ll
@@ -115,9 +115,8 @@ define i32 @icmpasreq(i32 %input, i32 %a, i32 %b) {
 ; CHECK-LABEL: icmpasreq:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %esi, %eax
-; CHECK-NEXT:    sarl $31, %edi
-; CHECK-NEXT:    cmpl $-1, %edi
-; CHECK-NEXT:    cmovnel %edx, %eax
+; CHECK-NEXT:    testl %edi, %edi
+; CHECK-NEXT:    cmovnsl %edx, %eax
 ; CHECK-NEXT:    retq
   %sh = ashr i32 %input, 31
   %c = icmp eq i32 %sh, -1
@@ -129,9 +128,8 @@ define i32 @icmpasrne(i32 %input, i32 %a, i32 %b) {
 ; CHECK-LABEL: icmpasrne:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %esi, %eax
-; CHECK-NEXT:    sarl $31, %edi
-; CHECK-NEXT:    cmpl $-1, %edi
-; CHECK-NEXT:    cmovel %edx, %eax
+; CHECK-NEXT:    testl %edi, %edi
+; CHECK-NEXT:    cmovlel %edx, %eax
 ; CHECK-NEXT:    retq
   %sh = ashr i32 %input, 31
   %c = icmp ne i32 %sh, -1


        


More information about the llvm-commits mailing list