[llvm-branch-commits] [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-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jan 19 11:26:46 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-branch-commits
mailing list