[llvm] ce8b393 - [RISCV] Add DAG combine to turn (setcc X, 1, setne) -> (setcc X, 0, seteq) if we can prove X is 0/1.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 19 11:22:37 PST 2021


Author: Craig Topper
Date: 2021-01-19T11:21:48-08:00
New Revision: ce8b3937ddad39536e6e715813682d9198229fb5

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

LOG: [RISCV] Add DAG combine to turn (setcc X, 1, setne) -> (setcc X, 0, seteq) if we can prove X is 0/1.

If we are able to compare with 0 instead of 1, we might be able
to fold the setcc into a beqz/bnez.

Often these setccs start life as an xor that gets converted to
a setcc by DAG combiner's rebuildSetcc. I looked into a detecting
(xor X, 1) and converting to (seteq X, 0) based on boolean contents
being 0/1 in rebuildSetcc instead of using computeKnownBits. It was
very perturbing to AMDGPU tests which I didn't look closely at.
It had a few changes on a couple other targets, but didn't seem
to be much if any improvement.

Reviewed By: lenary

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

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/ISDOpcodes.h
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/double-br-fcmp.ll
    llvm/test/CodeGen/RISCV/float-br-fcmp.ll
    llvm/test/CodeGen/RISCV/half-br-fcmp.ll
    llvm/test/CodeGen/RISCV/select-and.ll
    llvm/test/CodeGen/RISCV/select-or.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 5358b15437cc..1974e2f842c9 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -1332,6 +1332,12 @@ inline bool isUnsignedIntSetCC(CondCode Code) {
   return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
 }
 
+/// Return true if this is a setcc instruction that performs an equality
+/// comparison when used with integer operands.
+inline bool isIntEqualitySetCC(CondCode Code) {
+  return Code == SETEQ || Code == SETNE;
+}
+
 /// Return true if the specified condition returns true if the two operands to
 /// the condition are equal. Note that if one of the two operands is a NaN,
 /// this value is meaningless.

diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 8ca30d654421..4359d24acafc 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -447,6 +447,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
   // We can use any register for comparisons
   setHasMultipleConditionRegisters();
 
+  setTargetDAGCombine(ISD::SETCC);
   if (Subtarget.hasStdExtZbp()) {
     setTargetDAGCombine(ISD::OR);
   }
@@ -1961,7 +1962,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
     SDValue RHS = N->getOperand(1);
     auto CCVal = static_cast<ISD::CondCode>(N->getConstantOperandVal(2));
     APInt Mask = APInt::getBitsSetFrom(LHS.getValueSizeInBits(), 1);
-    if ((CCVal == ISD::SETNE || CCVal == ISD::SETEQ) && isNullConstant(RHS) &&
+    if (ISD::isIntEqualitySetCC(CCVal) && isNullConstant(RHS) &&
         LHS.getOpcode() == ISD::XOR && isOneConstant(LHS.getOperand(1)) &&
         DAG.MaskedValueIsZero(LHS.getOperand(0), Mask)) {
       SDLoc DL(N);
@@ -1973,6 +1974,22 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
     }
     break;
   }
+  case ISD::SETCC: {
+    // (setcc X, 1, setne) -> (setcc X, 0, seteq) if we can prove X is 0/1.
+    // Comparing with 0 may allow us to fold into bnez/beqz.
+    SDValue LHS = N->getOperand(0);
+    SDValue RHS = N->getOperand(1);
+    auto CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
+    APInt Mask = APInt::getBitsSetFrom(LHS.getValueSizeInBits(), 1);
+    if (isOneConstant(RHS) && ISD::isIntEqualitySetCC(CC) &&
+        DAG.MaskedValueIsZero(LHS, Mask)) {
+      SDLoc DL(N);
+      SDValue Zero = DAG.getConstant(0, DL, LHS.getValueType());
+      CC = ISD::getSetCCInverse(CC, LHS.getValueType());
+      return DAG.getSetCC(DL, N->getValueType(0), LHS, Zero, CC);
+    }
+    break;
+  }
   }
 
   return SDValue();

diff  --git a/llvm/test/CodeGen/RISCV/double-br-fcmp.ll b/llvm/test/CodeGen/RISCV/double-br-fcmp.ll
index 6336d7b12ef3..4fe3d9d0465e 100644
--- a/llvm/test/CodeGen/RISCV/double-br-fcmp.ll
+++ b/llvm/test/CodeGen/RISCV/double-br-fcmp.ll
@@ -411,8 +411,7 @@ define void @br_fcmp_ueq(double %a, double %b) nounwind {
 ; RV32IFD-NEXT:    flt.d a0, ft1, ft0
 ; RV32IFD-NEXT:    flt.d a1, ft0, ft1
 ; RV32IFD-NEXT:    or a0, a1, a0
-; RV32IFD-NEXT:    addi a1, zero, 1
-; RV32IFD-NEXT:    bne a0, a1, .LBB9_2
+; RV32IFD-NEXT:    beqz a0, .LBB9_2
 ; RV32IFD-NEXT:  # %bb.1: # %if.else
 ; RV32IFD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32IFD-NEXT:    addi sp, sp, 16
@@ -429,8 +428,7 @@ define void @br_fcmp_ueq(double %a, double %b) nounwind {
 ; RV64IFD-NEXT:    flt.d a0, ft1, ft0
 ; RV64IFD-NEXT:    flt.d a1, ft0, ft1
 ; RV64IFD-NEXT:    or a0, a1, a0
-; RV64IFD-NEXT:    addi a1, zero, 1
-; RV64IFD-NEXT:    bne a0, a1, .LBB9_2
+; RV64IFD-NEXT:    beqz a0, .LBB9_2
 ; RV64IFD-NEXT:  # %bb.1: # %if.else
 ; RV64IFD-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IFD-NEXT:    addi sp, sp, 16
@@ -676,8 +674,7 @@ define void @br_fcmp_uno(double %a, double %b) nounwind {
 ; RV32IFD-NEXT:    feq.d a0, ft1, ft1
 ; RV32IFD-NEXT:    feq.d a1, ft0, ft0
 ; RV32IFD-NEXT:    and a0, a1, a0
-; RV32IFD-NEXT:    addi a1, zero, 1
-; RV32IFD-NEXT:    bne a0, a1, .LBB15_2
+; RV32IFD-NEXT:    beqz a0, .LBB15_2
 ; RV32IFD-NEXT:  # %bb.1: # %if.else
 ; RV32IFD-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32IFD-NEXT:    addi sp, sp, 16
@@ -694,8 +691,7 @@ define void @br_fcmp_uno(double %a, double %b) nounwind {
 ; RV64IFD-NEXT:    feq.d a0, ft1, ft1
 ; RV64IFD-NEXT:    feq.d a1, ft0, ft0
 ; RV64IFD-NEXT:    and a0, a1, a0
-; RV64IFD-NEXT:    addi a1, zero, 1
-; RV64IFD-NEXT:    bne a0, a1, .LBB15_2
+; RV64IFD-NEXT:    beqz a0, .LBB15_2
 ; RV64IFD-NEXT:  # %bb.1: # %if.else
 ; RV64IFD-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IFD-NEXT:    addi sp, sp, 16

diff  --git a/llvm/test/CodeGen/RISCV/float-br-fcmp.ll b/llvm/test/CodeGen/RISCV/float-br-fcmp.ll
index a941ebc24e28..4a2687fd66b8 100644
--- a/llvm/test/CodeGen/RISCV/float-br-fcmp.ll
+++ b/llvm/test/CodeGen/RISCV/float-br-fcmp.ll
@@ -376,8 +376,7 @@ define void @br_fcmp_ueq(float %a, float %b) nounwind {
 ; RV32IF-NEXT:    flt.s a0, ft1, ft0
 ; RV32IF-NEXT:    flt.s a1, ft0, ft1
 ; RV32IF-NEXT:    or a0, a1, a0
-; RV32IF-NEXT:    addi a1, zero, 1
-; RV32IF-NEXT:    bne a0, a1, .LBB9_2
+; RV32IF-NEXT:    beqz a0, .LBB9_2
 ; RV32IF-NEXT:  # %bb.1: # %if.else
 ; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32IF-NEXT:    addi sp, sp, 16
@@ -394,8 +393,7 @@ define void @br_fcmp_ueq(float %a, float %b) nounwind {
 ; RV64IF-NEXT:    flt.s a0, ft1, ft0
 ; RV64IF-NEXT:    flt.s a1, ft0, ft1
 ; RV64IF-NEXT:    or a0, a1, a0
-; RV64IF-NEXT:    addi a1, zero, 1
-; RV64IF-NEXT:    bne a0, a1, .LBB9_2
+; RV64IF-NEXT:    beqz a0, .LBB9_2
 ; RV64IF-NEXT:  # %bb.1: # %if.else
 ; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IF-NEXT:    addi sp, sp, 16
@@ -617,8 +615,7 @@ define void @br_fcmp_uno(float %a, float %b) nounwind {
 ; RV32IF-NEXT:    feq.s a0, ft1, ft1
 ; RV32IF-NEXT:    feq.s a1, ft0, ft0
 ; RV32IF-NEXT:    and a0, a1, a0
-; RV32IF-NEXT:    addi a1, zero, 1
-; RV32IF-NEXT:    bne a0, a1, .LBB15_2
+; RV32IF-NEXT:    beqz a0, .LBB15_2
 ; RV32IF-NEXT:  # %bb.1: # %if.else
 ; RV32IF-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32IF-NEXT:    addi sp, sp, 16
@@ -635,8 +632,7 @@ define void @br_fcmp_uno(float %a, float %b) nounwind {
 ; RV64IF-NEXT:    feq.s a0, ft1, ft1
 ; RV64IF-NEXT:    feq.s a1, ft0, ft0
 ; RV64IF-NEXT:    and a0, a1, a0
-; RV64IF-NEXT:    addi a1, zero, 1
-; RV64IF-NEXT:    bne a0, a1, .LBB15_2
+; RV64IF-NEXT:    beqz a0, .LBB15_2
 ; RV64IF-NEXT:  # %bb.1: # %if.else
 ; RV64IF-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IF-NEXT:    addi sp, sp, 16

diff  --git a/llvm/test/CodeGen/RISCV/half-br-fcmp.ll b/llvm/test/CodeGen/RISCV/half-br-fcmp.ll
index 93f35a5b9dbe..538b864c0f4f 100644
--- a/llvm/test/CodeGen/RISCV/half-br-fcmp.ll
+++ b/llvm/test/CodeGen/RISCV/half-br-fcmp.ll
@@ -342,8 +342,7 @@ define void @br_fcmp_ueq(half %a, half %b) nounwind {
 ; RV32IZFH-NEXT:    flt.h a0, fa0, fa1
 ; RV32IZFH-NEXT:    flt.h a1, fa1, fa0
 ; RV32IZFH-NEXT:    or a0, a1, a0
-; RV32IZFH-NEXT:    addi a1, zero, 1
-; RV32IZFH-NEXT:    bne a0, a1, .LBB9_2
+; RV32IZFH-NEXT:    beqz a0, .LBB9_2
 ; RV32IZFH-NEXT:  # %bb.1: # %if.else
 ; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32IZFH-NEXT:    addi sp, sp, 16
@@ -358,8 +357,7 @@ define void @br_fcmp_ueq(half %a, half %b) nounwind {
 ; RV64IZFH-NEXT:    flt.h a0, fa0, fa1
 ; RV64IZFH-NEXT:    flt.h a1, fa1, fa0
 ; RV64IZFH-NEXT:    or a0, a1, a0
-; RV64IZFH-NEXT:    addi a1, zero, 1
-; RV64IZFH-NEXT:    bne a0, a1, .LBB9_2
+; RV64IZFH-NEXT:    beqz a0, .LBB9_2
 ; RV64IZFH-NEXT:  # %bb.1: # %if.else
 ; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IZFH-NEXT:    addi sp, sp, 16
@@ -559,8 +557,7 @@ define void @br_fcmp_uno(half %a, half %b) nounwind {
 ; RV32IZFH-NEXT:    feq.h a0, fa1, fa1
 ; RV32IZFH-NEXT:    feq.h a1, fa0, fa0
 ; RV32IZFH-NEXT:    and a0, a1, a0
-; RV32IZFH-NEXT:    addi a1, zero, 1
-; RV32IZFH-NEXT:    bne a0, a1, .LBB15_2
+; RV32IZFH-NEXT:    beqz a0, .LBB15_2
 ; RV32IZFH-NEXT:  # %bb.1: # %if.else
 ; RV32IZFH-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32IZFH-NEXT:    addi sp, sp, 16
@@ -575,8 +572,7 @@ define void @br_fcmp_uno(half %a, half %b) nounwind {
 ; RV64IZFH-NEXT:    feq.h a0, fa1, fa1
 ; RV64IZFH-NEXT:    feq.h a1, fa0, fa0
 ; RV64IZFH-NEXT:    and a0, a1, a0
-; RV64IZFH-NEXT:    addi a1, zero, 1
-; RV64IZFH-NEXT:    bne a0, a1, .LBB15_2
+; RV64IZFH-NEXT:    beqz a0, .LBB15_2
 ; RV64IZFH-NEXT:  # %bb.1: # %if.else
 ; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
 ; RV64IZFH-NEXT:    addi sp, sp, 16

diff  --git a/llvm/test/CodeGen/RISCV/select-and.ll b/llvm/test/CodeGen/RISCV/select-and.ll
index 5160a6c79f6d..61ba35b69dfa 100644
--- a/llvm/test/CodeGen/RISCV/select-and.ll
+++ b/llvm/test/CodeGen/RISCV/select-and.ll
@@ -65,8 +65,7 @@ define signext i32 @if_of_and(i1 zeroext %a, i1 zeroext %b) nounwind {
 ; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    and a0, a0, a1
-; RV32I-NEXT:    addi a1, zero, 1
-; RV32I-NEXT:    bne a0, a1, .LBB1_2
+; RV32I-NEXT:    beqz a0, .LBB1_2
 ; RV32I-NEXT:  # %bb.1: # %if.then
 ; RV32I-NEXT:    call both at plt
 ; RV32I-NEXT:    j .LBB1_3
@@ -82,8 +81,7 @@ define signext i32 @if_of_and(i1 zeroext %a, i1 zeroext %b) nounwind {
 ; RV32IBT-NEXT:    addi sp, sp, -16
 ; RV32IBT-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
 ; RV32IBT-NEXT:    and a0, a0, a1
-; RV32IBT-NEXT:    addi a1, zero, 1
-; RV32IBT-NEXT:    bne a0, a1, .LBB1_2
+; RV32IBT-NEXT:    beqz a0, .LBB1_2
 ; RV32IBT-NEXT:  # %bb.1: # %if.then
 ; RV32IBT-NEXT:    call both at plt
 ; RV32IBT-NEXT:    j .LBB1_3
@@ -99,8 +97,7 @@ define signext i32 @if_of_and(i1 zeroext %a, i1 zeroext %b) nounwind {
 ; RV64I-NEXT:    addi sp, sp, -16
 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    and a0, a0, a1
-; RV64I-NEXT:    addi a1, zero, 1
-; RV64I-NEXT:    bne a0, a1, .LBB1_2
+; RV64I-NEXT:    beqz a0, .LBB1_2
 ; RV64I-NEXT:  # %bb.1: # %if.then
 ; RV64I-NEXT:    call both at plt
 ; RV64I-NEXT:    j .LBB1_3
@@ -116,8 +113,7 @@ define signext i32 @if_of_and(i1 zeroext %a, i1 zeroext %b) nounwind {
 ; RV64IBT-NEXT:    addi sp, sp, -16
 ; RV64IBT-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
 ; RV64IBT-NEXT:    and a0, a0, a1
-; RV64IBT-NEXT:    addi a1, zero, 1
-; RV64IBT-NEXT:    bne a0, a1, .LBB1_2
+; RV64IBT-NEXT:    beqz a0, .LBB1_2
 ; RV64IBT-NEXT:  # %bb.1: # %if.then
 ; RV64IBT-NEXT:    call both at plt
 ; RV64IBT-NEXT:    j .LBB1_3

diff  --git a/llvm/test/CodeGen/RISCV/select-or.ll b/llvm/test/CodeGen/RISCV/select-or.ll
index 4ae6b7798ec7..1bcfad0378de 100644
--- a/llvm/test/CodeGen/RISCV/select-or.ll
+++ b/llvm/test/CodeGen/RISCV/select-or.ll
@@ -65,8 +65,7 @@ define signext i32 @if_of_or(i1 zeroext %a, i1 zeroext %b) nounwind {
 ; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    or a0, a0, a1
-; RV32I-NEXT:    addi a1, zero, 1
-; RV32I-NEXT:    bne a0, a1, .LBB1_2
+; RV32I-NEXT:    beqz a0, .LBB1_2
 ; RV32I-NEXT:  # %bb.1: # %if.then
 ; RV32I-NEXT:    call either at plt
 ; RV32I-NEXT:    j .LBB1_3
@@ -82,8 +81,7 @@ define signext i32 @if_of_or(i1 zeroext %a, i1 zeroext %b) nounwind {
 ; RV32IBT-NEXT:    addi sp, sp, -16
 ; RV32IBT-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
 ; RV32IBT-NEXT:    or a0, a0, a1
-; RV32IBT-NEXT:    addi a1, zero, 1
-; RV32IBT-NEXT:    bne a0, a1, .LBB1_2
+; RV32IBT-NEXT:    beqz a0, .LBB1_2
 ; RV32IBT-NEXT:  # %bb.1: # %if.then
 ; RV32IBT-NEXT:    call either at plt
 ; RV32IBT-NEXT:    j .LBB1_3
@@ -99,8 +97,7 @@ define signext i32 @if_of_or(i1 zeroext %a, i1 zeroext %b) nounwind {
 ; RV64I-NEXT:    addi sp, sp, -16
 ; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
 ; RV64I-NEXT:    or a0, a0, a1
-; RV64I-NEXT:    addi a1, zero, 1
-; RV64I-NEXT:    bne a0, a1, .LBB1_2
+; RV64I-NEXT:    beqz a0, .LBB1_2
 ; RV64I-NEXT:  # %bb.1: # %if.then
 ; RV64I-NEXT:    call either at plt
 ; RV64I-NEXT:    j .LBB1_3
@@ -116,8 +113,7 @@ define signext i32 @if_of_or(i1 zeroext %a, i1 zeroext %b) nounwind {
 ; RV64IBT-NEXT:    addi sp, sp, -16
 ; RV64IBT-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
 ; RV64IBT-NEXT:    or a0, a0, a1
-; RV64IBT-NEXT:    addi a1, zero, 1
-; RV64IBT-NEXT:    bne a0, a1, .LBB1_2
+; RV64IBT-NEXT:    beqz a0, .LBB1_2
 ; RV64IBT-NEXT:  # %bb.1: # %if.then
 ; RV64IBT-NEXT:    call either at plt
 ; RV64IBT-NEXT:    j .LBB1_3


        


More information about the llvm-commits mailing list