[llvm] 132546d - [RISCV] Add DAG combine to fold (select C, (add X, Y), Y) -> (add (select C, X, 0), Y).
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 21 10:58:21 PST 2022
Author: Craig Topper
Date: 2022-12-21T10:57:57-08:00
New Revision: 132546d9397c062d4b2f50fac76392a11d3d6f27
URL: https://github.com/llvm/llvm-project/commit/132546d9397c062d4b2f50fac76392a11d3d6f27
DIFF: https://github.com/llvm/llvm-project/commit/132546d9397c062d4b2f50fac76392a11d3d6f27.diff
LOG: [RISCV] Add DAG combine to fold (select C, (add X, Y), Y) -> (add (select C, X, 0), Y).
Similar for sub, or, and xor. These are all operations that have 0
as a neutral value. This is based on a similar tranform in InstCombine.
This allows us to remove some XVentanaCondOps patterns and
some code from DAGCombine for RISCVISD::SELECT_CC.
Reviewed By: asb
Differential Revision: https://reviews.llvm.org/D140465
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
llvm/test/CodeGen/RISCV/select.ll
llvm/test/CodeGen/RISCV/sextw-removal.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 71382736270f5..d34786d5d0fdd 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1019,7 +1019,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setJumpIsExpensive();
setTargetDAGCombine({ISD::INTRINSIC_WO_CHAIN, ISD::ADD, ISD::SUB, ISD::AND,
- ISD::OR, ISD::XOR, ISD::SETCC});
+ ISD::OR, ISD::XOR, ISD::SETCC, ISD::SELECT});
if (Subtarget.is64Bit())
setTargetDAGCombine(ISD::SRA);
@@ -9637,6 +9637,65 @@ static bool combine_CC(SDValue &LHS, SDValue &RHS, SDValue &CC, const SDLoc &DL,
return false;
}
+// Fold
+// (select C, (add Y, X), Y) -> (add Y, (select C, X, 0)).
+// (select C, (sub Y, X), Y) -> (sub Y, (select C, X, 0)).
+// (select C, (or Y, X), Y) -> (or Y, (select C, X, 0)).
+// (select C, (xor Y, X), Y) -> (xor Y, (select C, X, 0)).
+static SDValue tryFoldSelectIntoOp(SDNode *N, SelectionDAG &DAG,
+ SDValue TrueVal, SDValue FalseVal,
+ bool Swapped) {
+ bool Commutative = true;
+ switch (TrueVal.getOpcode()) {
+ default:
+ return SDValue();
+ case ISD::SUB:
+ Commutative = false;
+ break;
+ case ISD::ADD:
+ case ISD::OR:
+ case ISD::XOR:
+ break;
+ }
+
+ if (!TrueVal.hasOneUse() || isa<ConstantSDNode>(FalseVal))
+ return SDValue();
+
+ unsigned OpToFold;
+ if (FalseVal == TrueVal.getOperand(0))
+ OpToFold = 0;
+ else if (Commutative && FalseVal == TrueVal.getOperand(1))
+ OpToFold = 1;
+ else
+ return SDValue();
+
+ EVT VT = N->getValueType(0);
+ SDLoc DL(N);
+ SDValue Zero = DAG.getConstant(0, DL, VT);
+ SDValue OtherOp = TrueVal.getOperand(1 - OpToFold);
+
+ if (Swapped)
+ std::swap(OtherOp, Zero);
+ SDValue NewSel = DAG.getSelect(DL, VT, N->getOperand(0), OtherOp, Zero);
+ return DAG.getNode(TrueVal.getOpcode(), DL, VT, FalseVal, NewSel);
+}
+
+static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,
+ const RISCVSubtarget &Subtarget) {
+ if (Subtarget.hasShortForwardBranchOpt())
+ return SDValue();
+
+ // Only support XLenVT.
+ if (N->getValueType(0) != Subtarget.getXLenVT())
+ return SDValue();
+
+ SDValue TrueVal = N->getOperand(1);
+ SDValue FalseVal = N->getOperand(2);
+ if (SDValue V = tryFoldSelectIntoOp(N, DAG, TrueVal, FalseVal, /*Swapped*/false))
+ return V;
+ return tryFoldSelectIntoOp(N, DAG, FalseVal, TrueVal, /*Swapped*/true);
+}
+
SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
SelectionDAG &DAG = DCI.DAG;
@@ -9806,6 +9865,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
return SDValue();
case ISD::TRUNCATE:
return performTRUNCATECombine(N, DAG, Subtarget);
+ case ISD::SELECT:
+ return performSELECTCombine(N, DAG, Subtarget);
case RISCVISD::SELECT_CC: {
// Transform
SDValue LHS = N->getOperand(0);
@@ -9821,51 +9882,6 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
if (TrueV == FalseV)
return TrueV;
- // (select (x in [0,1] == 0), y, (z ^ y) ) -> (-x & z ) ^ y
- // (select (x in [0,1] != 0), (z ^ y), y ) -> (-x & z ) ^ y
- // (select (x in [0,1] == 0), y, (z | y) ) -> (-x & z ) | y
- // (select (x in [0,1] != 0), (z | y), y ) -> (-x & z ) | y
- // NOTE: We only do this if the target does not have the short forward
- // branch optimization.
- APInt Mask = APInt::getBitsSetFrom(LHS.getValueSizeInBits(), 1);
- if (!Subtarget.hasShortForwardBranchOpt() && isNullConstant(RHS) &&
- ISD::isIntEqualitySetCC(CCVal) && DAG.MaskedValueIsZero(LHS, Mask)) {
- unsigned Opcode;
- SDValue Src1, Src2;
- // true if FalseV is XOR or OR operator and one of its operands
- // is equal to Op1
- // ( a , a op b) || ( b , a op b)
- auto isOrXorPattern = [&]() {
- if (CCVal == ISD::SETEQ &&
- (FalseV.getOpcode() == ISD::XOR || FalseV.getOpcode() == ISD::OR) &&
- (FalseV.getOperand(0) == TrueV || FalseV.getOperand(1) == TrueV)) {
- Src1 = FalseV.getOperand(0) == TrueV ?
- FalseV.getOperand(1) : FalseV.getOperand(0);
- Src2 = TrueV;
- Opcode = FalseV.getOpcode();
- return true;
- }
- if (CCVal == ISD::SETNE &&
- (TrueV.getOpcode() == ISD::XOR || TrueV.getOpcode() == ISD::OR) &&
- (TrueV.getOperand(0) == FalseV || TrueV.getOperand(1) == FalseV)) {
- Src1 = TrueV.getOperand(0) == FalseV ?
- TrueV.getOperand(1) : TrueV.getOperand(0);
- Src2 = FalseV;
- Opcode = TrueV.getOpcode();
- return true;
- }
-
- return false;
- };
-
- if (isOrXorPattern()) {
- assert(LHS.getValueType() == VT && "Unexpected VT!");
- SDValue Mask = DAG.getNegative(LHS, DL, VT); // -x
- SDValue And = DAG.getNode(ISD::AND, DL, VT, Mask, Src1); // Mask & z
- return DAG.getNode(Opcode, DL, VT, And, Src2); // And Op y
- }
- }
-
// (select (x < 0), y, z) -> x >> (XLEN - 1) & (y - z) + z
// (select (x >= 0), y, z) -> x >> (XLEN - 1) & (z - y) + y
if (!Subtarget.hasShortForwardBranchOpt() && isa<ConstantSDNode>(TrueV) &&
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
index b4e28e6fc3d64..18d6515f39d4b 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
@@ -28,13 +28,6 @@ def VT_MASKC : VTMaskedMove<0b110, "vt.maskc">,
def VT_MASKCN : VTMaskedMove<0b111, "vt.maskcn">,
Sched<[WriteIALU, ReadIALU, ReadIALU]>;
-multiclass XVentanaCondops_pats<SDPatternOperator Op, RVInst MI> {
- def : Pat<(i64 (select GPR:$rc, (Op GPR:$rs1, GPR:$rs2), GPR:$rs1)),
- (MI $rs1, (VT_MASKC $rs2, $rc))>;
- def : Pat<(i64 (select GPR:$rc, GPR:$rs1, (Op GPR:$rs1, GPR:$rs2))),
- (MI $rs1, (VT_MASKCN $rs2, $rc))>;
-}
-
let Predicates = [IsRV64, HasVendorXVentanaCondOps] in {
// Directly use MASKC/MASKCN in case of any of the operands being 0.
def : Pat<(select GPR:$rc, GPR:$rs1, (i64 0)),
@@ -42,12 +35,6 @@ def : Pat<(select GPR:$rc, GPR:$rs1, (i64 0)),
def : Pat<(select GPR:$rc, (i64 0), GPR:$rs1),
(VT_MASKCN $rs1, $rc)>;
-// Conditional operations patterns.
-defm : XVentanaCondops_pats<add, ADD>;
-defm : XVentanaCondops_pats<sub, SUB>;
-defm : XVentanaCondops_pats<or, OR>;
-defm : XVentanaCondops_pats<xor, XOR>;
-
// Conditional AND operation patterns.
def : Pat<(i64 (select GPR:$rc, (and GPR:$rs1, GPR:$rs2), GPR:$rs1)),
(OR (AND $rs1, $rs2), (VT_MASKCN $rs1, $rc))>;
diff --git a/llvm/test/CodeGen/RISCV/select.ll b/llvm/test/CodeGen/RISCV/select.ll
index de54a4622cf90..2e9c4e7df1d08 100644
--- a/llvm/test/CodeGen/RISCV/select.ll
+++ b/llvm/test/CodeGen/RISCV/select.ll
@@ -9,25 +9,16 @@ define i16 @select_xor_1(i16 %A, i8 %cond) {
; RV32-NEXT: slli a1, a1, 31
; RV32-NEXT: srai a1, a1, 31
; RV32-NEXT: andi a1, a1, 43
-; RV32-NEXT: xor a0, a1, a0
+; RV32-NEXT: xor a0, a0, a1
; RV32-NEXT: ret
;
-; NOCONDOPS-LABEL: select_xor_1:
-; NOCONDOPS: # %bb.0: # %entry
-; NOCONDOPS-NEXT: slli a1, a1, 63
-; NOCONDOPS-NEXT: srai a1, a1, 63
-; NOCONDOPS-NEXT: andi a1, a1, 43
-; NOCONDOPS-NEXT: xor a0, a1, a0
-; NOCONDOPS-NEXT: ret
-;
-; CONDOPS-LABEL: select_xor_1:
-; CONDOPS: # %bb.0: # %entry
-; CONDOPS-NEXT: andi a1, a1, 1
-; CONDOPS-NEXT: seqz a1, a1
-; CONDOPS-NEXT: li a2, 43
-; CONDOPS-NEXT: vt.maskcn a1, a2, a1
-; CONDOPS-NEXT: xor a0, a0, a1
-; CONDOPS-NEXT: ret
+; RV64-LABEL: select_xor_1:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: slli a1, a1, 63
+; RV64-NEXT: srai a1, a1, 63
+; RV64-NEXT: andi a1, a1, 43
+; RV64-NEXT: xor a0, a0, a1
+; RV64-NEXT: ret
entry:
%and = and i8 %cond, 1
%cmp10 = icmp eq i8 %and, 0
@@ -44,7 +35,7 @@ define i16 @select_xor_1b(i16 %A, i8 %cond) {
; RV32-NEXT: slli a1, a1, 31
; RV32-NEXT: srai a1, a1, 31
; RV32-NEXT: andi a1, a1, 43
-; RV32-NEXT: xor a0, a1, a0
+; RV32-NEXT: xor a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_xor_1b:
@@ -52,7 +43,7 @@ define i16 @select_xor_1b(i16 %A, i8 %cond) {
; NOCONDOPS-NEXT: slli a1, a1, 63
; NOCONDOPS-NEXT: srai a1, a1, 63
; NOCONDOPS-NEXT: andi a1, a1, 43
-; NOCONDOPS-NEXT: xor a0, a1, a0
+; NOCONDOPS-NEXT: xor a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_xor_1b:
@@ -76,24 +67,16 @@ define i32 @select_xor_2(i32 %A, i32 %B, i8 %cond) {
; RV32-NEXT: slli a2, a2, 31
; RV32-NEXT: srai a2, a2, 31
; RV32-NEXT: and a1, a2, a1
-; RV32-NEXT: xor a0, a1, a0
+; RV32-NEXT: xor a0, a0, a1
; RV32-NEXT: ret
;
-; NOCONDOPS-LABEL: select_xor_2:
-; NOCONDOPS: # %bb.0: # %entry
-; NOCONDOPS-NEXT: slli a2, a2, 63
-; NOCONDOPS-NEXT: srai a2, a2, 63
-; NOCONDOPS-NEXT: and a1, a2, a1
-; NOCONDOPS-NEXT: xor a0, a1, a0
-; NOCONDOPS-NEXT: ret
-;
-; CONDOPS-LABEL: select_xor_2:
-; CONDOPS: # %bb.0: # %entry
-; CONDOPS-NEXT: andi a2, a2, 1
-; CONDOPS-NEXT: seqz a2, a2
-; CONDOPS-NEXT: vt.maskcn a1, a1, a2
-; CONDOPS-NEXT: xor a0, a0, a1
-; CONDOPS-NEXT: ret
+; RV64-LABEL: select_xor_2:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: slli a2, a2, 63
+; RV64-NEXT: srai a2, a2, 63
+; RV64-NEXT: and a1, a2, a1
+; RV64-NEXT: xor a0, a0, a1
+; RV64-NEXT: ret
entry:
%and = and i8 %cond, 1
%cmp10 = icmp eq i8 %and, 0
@@ -110,7 +93,7 @@ define i32 @select_xor_2b(i32 %A, i32 %B, i8 %cond) {
; RV32-NEXT: slli a2, a2, 31
; RV32-NEXT: srai a2, a2, 31
; RV32-NEXT: and a1, a2, a1
-; RV32-NEXT: xor a0, a1, a0
+; RV32-NEXT: xor a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_xor_2b:
@@ -118,7 +101,7 @@ define i32 @select_xor_2b(i32 %A, i32 %B, i8 %cond) {
; NOCONDOPS-NEXT: slli a2, a2, 63
; NOCONDOPS-NEXT: srai a2, a2, 63
; NOCONDOPS-NEXT: and a1, a2, a1
-; NOCONDOPS-NEXT: xor a0, a1, a0
+; NOCONDOPS-NEXT: xor a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_xor_2b:
@@ -139,19 +122,17 @@ define i16 @select_xor_3(i16 %A, i8 %cond) {
; RV32-LABEL: select_xor_3:
; RV32: # %bb.0: # %entry
; RV32-NEXT: andi a1, a1, 1
-; RV32-NEXT: bnez a1, .LBB4_2
-; RV32-NEXT: # %bb.1:
-; RV32-NEXT: xori a0, a0, 43
-; RV32-NEXT: .LBB4_2: # %entry
+; RV32-NEXT: addi a1, a1, -1
+; RV32-NEXT: andi a1, a1, 43
+; RV32-NEXT: xor a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_xor_3:
; NOCONDOPS: # %bb.0: # %entry
; NOCONDOPS-NEXT: andi a1, a1, 1
-; NOCONDOPS-NEXT: bnez a1, .LBB4_2
-; NOCONDOPS-NEXT: # %bb.1:
-; NOCONDOPS-NEXT: xori a0, a0, 43
-; NOCONDOPS-NEXT: .LBB4_2: # %entry
+; NOCONDOPS-NEXT: addiw a1, a1, -1
+; NOCONDOPS-NEXT: andi a1, a1, 43
+; NOCONDOPS-NEXT: xor a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_xor_3:
@@ -176,19 +157,17 @@ define i16 @select_xor_3b(i16 %A, i8 %cond) {
; RV32-LABEL: select_xor_3b:
; RV32: # %bb.0: # %entry
; RV32-NEXT: andi a1, a1, 1
-; RV32-NEXT: bnez a1, .LBB5_2
-; RV32-NEXT: # %bb.1: # %entry
-; RV32-NEXT: xori a0, a0, 43
-; RV32-NEXT: .LBB5_2: # %entry
+; RV32-NEXT: addi a1, a1, -1
+; RV32-NEXT: andi a1, a1, 43
+; RV32-NEXT: xor a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_xor_3b:
; NOCONDOPS: # %bb.0: # %entry
; NOCONDOPS-NEXT: andi a1, a1, 1
-; NOCONDOPS-NEXT: bnez a1, .LBB5_2
-; NOCONDOPS-NEXT: # %bb.1: # %entry
-; NOCONDOPS-NEXT: xori a0, a0, 43
-; NOCONDOPS-NEXT: .LBB5_2: # %entry
+; NOCONDOPS-NEXT: addiw a1, a1, -1
+; NOCONDOPS-NEXT: andi a1, a1, 43
+; NOCONDOPS-NEXT: xor a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_xor_3b:
@@ -210,19 +189,17 @@ define i32 @select_xor_4(i32 %A, i32 %B, i8 %cond) {
; RV32-LABEL: select_xor_4:
; RV32: # %bb.0: # %entry
; RV32-NEXT: andi a2, a2, 1
-; RV32-NEXT: bnez a2, .LBB6_2
-; RV32-NEXT: # %bb.1:
-; RV32-NEXT: xor a0, a1, a0
-; RV32-NEXT: .LBB6_2: # %entry
+; RV32-NEXT: addi a2, a2, -1
+; RV32-NEXT: and a1, a2, a1
+; RV32-NEXT: xor a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_xor_4:
; NOCONDOPS: # %bb.0: # %entry
; NOCONDOPS-NEXT: andi a2, a2, 1
-; NOCONDOPS-NEXT: bnez a2, .LBB6_2
-; NOCONDOPS-NEXT: # %bb.1:
-; NOCONDOPS-NEXT: xor a0, a1, a0
-; NOCONDOPS-NEXT: .LBB6_2: # %entry
+; NOCONDOPS-NEXT: addi a2, a2, -1
+; NOCONDOPS-NEXT: and a1, a2, a1
+; NOCONDOPS-NEXT: xor a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_xor_4:
@@ -246,19 +223,17 @@ define i32 @select_xor_4b(i32 %A, i32 %B, i8 %cond) {
; RV32-LABEL: select_xor_4b:
; RV32: # %bb.0: # %entry
; RV32-NEXT: andi a2, a2, 1
-; RV32-NEXT: bnez a2, .LBB7_2
-; RV32-NEXT: # %bb.1: # %entry
-; RV32-NEXT: xor a0, a1, a0
-; RV32-NEXT: .LBB7_2: # %entry
+; RV32-NEXT: addi a2, a2, -1
+; RV32-NEXT: and a1, a2, a1
+; RV32-NEXT: xor a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_xor_4b:
; NOCONDOPS: # %bb.0: # %entry
; NOCONDOPS-NEXT: andi a2, a2, 1
-; NOCONDOPS-NEXT: bnez a2, .LBB7_2
-; NOCONDOPS-NEXT: # %bb.1: # %entry
-; NOCONDOPS-NEXT: xor a0, a1, a0
-; NOCONDOPS-NEXT: .LBB7_2: # %entry
+; NOCONDOPS-NEXT: addi a2, a2, -1
+; NOCONDOPS-NEXT: and a1, a2, a1
+; NOCONDOPS-NEXT: xor a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_xor_4b:
@@ -281,24 +256,16 @@ define i32 @select_or(i32 %A, i32 %B, i8 %cond) {
; RV32-NEXT: slli a2, a2, 31
; RV32-NEXT: srai a2, a2, 31
; RV32-NEXT: and a1, a2, a1
-; RV32-NEXT: or a0, a1, a0
+; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
-; NOCONDOPS-LABEL: select_or:
-; NOCONDOPS: # %bb.0: # %entry
-; NOCONDOPS-NEXT: slli a2, a2, 63
-; NOCONDOPS-NEXT: srai a2, a2, 63
-; NOCONDOPS-NEXT: and a1, a2, a1
-; NOCONDOPS-NEXT: or a0, a1, a0
-; NOCONDOPS-NEXT: ret
-;
-; CONDOPS-LABEL: select_or:
-; CONDOPS: # %bb.0: # %entry
-; CONDOPS-NEXT: andi a2, a2, 1
-; CONDOPS-NEXT: seqz a2, a2
-; CONDOPS-NEXT: vt.maskcn a1, a1, a2
-; CONDOPS-NEXT: or a0, a0, a1
-; CONDOPS-NEXT: ret
+; RV64-LABEL: select_or:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: slli a2, a2, 63
+; RV64-NEXT: srai a2, a2, 63
+; RV64-NEXT: and a1, a2, a1
+; RV64-NEXT: or a0, a0, a1
+; RV64-NEXT: ret
entry:
%and = and i8 %cond, 1
%cmp10 = icmp eq i8 %and, 0
@@ -315,7 +282,7 @@ define i32 @select_or_b(i32 %A, i32 %B, i8 %cond) {
; RV32-NEXT: slli a2, a2, 31
; RV32-NEXT: srai a2, a2, 31
; RV32-NEXT: and a1, a2, a1
-; RV32-NEXT: or a0, a1, a0
+; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_or_b:
@@ -323,7 +290,7 @@ define i32 @select_or_b(i32 %A, i32 %B, i8 %cond) {
; NOCONDOPS-NEXT: slli a2, a2, 63
; NOCONDOPS-NEXT: srai a2, a2, 63
; NOCONDOPS-NEXT: and a1, a2, a1
-; NOCONDOPS-NEXT: or a0, a1, a0
+; NOCONDOPS-NEXT: or a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_or_b:
@@ -346,24 +313,16 @@ define i32 @select_or_1(i32 %A, i32 %B, i32 %cond) {
; RV32-NEXT: slli a2, a2, 31
; RV32-NEXT: srai a2, a2, 31
; RV32-NEXT: and a1, a2, a1
-; RV32-NEXT: or a0, a1, a0
+; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
-; NOCONDOPS-LABEL: select_or_1:
-; NOCONDOPS: # %bb.0: # %entry
-; NOCONDOPS-NEXT: slli a2, a2, 63
-; NOCONDOPS-NEXT: srai a2, a2, 63
-; NOCONDOPS-NEXT: and a1, a2, a1
-; NOCONDOPS-NEXT: or a0, a1, a0
-; NOCONDOPS-NEXT: ret
-;
-; CONDOPS-LABEL: select_or_1:
-; CONDOPS: # %bb.0: # %entry
-; CONDOPS-NEXT: andi a2, a2, 1
-; CONDOPS-NEXT: seqz a2, a2
-; CONDOPS-NEXT: vt.maskcn a1, a1, a2
-; CONDOPS-NEXT: or a0, a0, a1
-; CONDOPS-NEXT: ret
+; RV64-LABEL: select_or_1:
+; RV64: # %bb.0: # %entry
+; RV64-NEXT: slli a2, a2, 63
+; RV64-NEXT: srai a2, a2, 63
+; RV64-NEXT: and a1, a2, a1
+; RV64-NEXT: or a0, a0, a1
+; RV64-NEXT: ret
entry:
%and = and i32 %cond, 1
%cmp10 = icmp eq i32 %and, 0
@@ -380,7 +339,7 @@ define i32 @select_or_1b(i32 %A, i32 %B, i32 %cond) {
; RV32-NEXT: slli a2, a2, 31
; RV32-NEXT: srai a2, a2, 31
; RV32-NEXT: and a1, a2, a1
-; RV32-NEXT: or a0, a1, a0
+; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_or_1b:
@@ -388,7 +347,7 @@ define i32 @select_or_1b(i32 %A, i32 %B, i32 %cond) {
; NOCONDOPS-NEXT: slli a2, a2, 63
; NOCONDOPS-NEXT: srai a2, a2, 63
; NOCONDOPS-NEXT: and a1, a2, a1
-; NOCONDOPS-NEXT: or a0, a1, a0
+; NOCONDOPS-NEXT: or a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_or_1b:
@@ -409,19 +368,17 @@ define i32 @select_or_2(i32 %A, i32 %B, i8 %cond) {
; RV32-LABEL: select_or_2:
; RV32: # %bb.0: # %entry
; RV32-NEXT: andi a2, a2, 1
-; RV32-NEXT: bnez a2, .LBB12_2
-; RV32-NEXT: # %bb.1:
-; RV32-NEXT: or a0, a1, a0
-; RV32-NEXT: .LBB12_2: # %entry
+; RV32-NEXT: addi a2, a2, -1
+; RV32-NEXT: and a1, a2, a1
+; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_or_2:
; NOCONDOPS: # %bb.0: # %entry
; NOCONDOPS-NEXT: andi a2, a2, 1
-; NOCONDOPS-NEXT: bnez a2, .LBB12_2
-; NOCONDOPS-NEXT: # %bb.1:
-; NOCONDOPS-NEXT: or a0, a1, a0
-; NOCONDOPS-NEXT: .LBB12_2: # %entry
+; NOCONDOPS-NEXT: addi a2, a2, -1
+; NOCONDOPS-NEXT: and a1, a2, a1
+; NOCONDOPS-NEXT: or a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_or_2:
@@ -445,19 +402,17 @@ define i32 @select_or_2b(i32 %A, i32 %B, i8 %cond) {
; RV32-LABEL: select_or_2b:
; RV32: # %bb.0: # %entry
; RV32-NEXT: andi a2, a2, 1
-; RV32-NEXT: bnez a2, .LBB13_2
-; RV32-NEXT: # %bb.1: # %entry
-; RV32-NEXT: or a0, a1, a0
-; RV32-NEXT: .LBB13_2: # %entry
+; RV32-NEXT: addi a2, a2, -1
+; RV32-NEXT: and a1, a2, a1
+; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_or_2b:
; NOCONDOPS: # %bb.0: # %entry
; NOCONDOPS-NEXT: andi a2, a2, 1
-; NOCONDOPS-NEXT: bnez a2, .LBB13_2
-; NOCONDOPS-NEXT: # %bb.1: # %entry
-; NOCONDOPS-NEXT: or a0, a1, a0
-; NOCONDOPS-NEXT: .LBB13_2: # %entry
+; NOCONDOPS-NEXT: addi a2, a2, -1
+; NOCONDOPS-NEXT: and a1, a2, a1
+; NOCONDOPS-NEXT: or a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_or_2b:
@@ -478,19 +433,17 @@ define i32 @select_or_3(i32 %A, i32 %B, i32 %cond) {
; RV32-LABEL: select_or_3:
; RV32: # %bb.0: # %entry
; RV32-NEXT: andi a2, a2, 1
-; RV32-NEXT: bnez a2, .LBB14_2
-; RV32-NEXT: # %bb.1:
-; RV32-NEXT: or a0, a1, a0
-; RV32-NEXT: .LBB14_2: # %entry
+; RV32-NEXT: addi a2, a2, -1
+; RV32-NEXT: and a1, a2, a1
+; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_or_3:
; NOCONDOPS: # %bb.0: # %entry
; NOCONDOPS-NEXT: andi a2, a2, 1
-; NOCONDOPS-NEXT: bnez a2, .LBB14_2
-; NOCONDOPS-NEXT: # %bb.1:
-; NOCONDOPS-NEXT: or a0, a1, a0
-; NOCONDOPS-NEXT: .LBB14_2: # %entry
+; NOCONDOPS-NEXT: addi a2, a2, -1
+; NOCONDOPS-NEXT: and a1, a2, a1
+; NOCONDOPS-NEXT: or a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_or_3:
@@ -514,19 +467,17 @@ define i32 @select_or_3b(i32 %A, i32 %B, i32 %cond) {
; RV32-LABEL: select_or_3b:
; RV32: # %bb.0: # %entry
; RV32-NEXT: andi a2, a2, 1
-; RV32-NEXT: bnez a2, .LBB15_2
-; RV32-NEXT: # %bb.1: # %entry
-; RV32-NEXT: or a0, a1, a0
-; RV32-NEXT: .LBB15_2: # %entry
+; RV32-NEXT: addi a2, a2, -1
+; RV32-NEXT: and a1, a2, a1
+; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_or_3b:
; NOCONDOPS: # %bb.0: # %entry
; NOCONDOPS-NEXT: andi a2, a2, 1
-; NOCONDOPS-NEXT: bnez a2, .LBB15_2
-; NOCONDOPS-NEXT: # %bb.1: # %entry
-; NOCONDOPS-NEXT: or a0, a1, a0
-; NOCONDOPS-NEXT: .LBB15_2: # %entry
+; NOCONDOPS-NEXT: addi a2, a2, -1
+; NOCONDOPS-NEXT: and a1, a2, a1
+; NOCONDOPS-NEXT: or a0, a0, a1
; NOCONDOPS-NEXT: ret
;
; CONDOPS-LABEL: select_or_3b:
@@ -546,11 +497,9 @@ entry:
define i32 @select_add_1(i1 zeroext %cond, i32 %a, i32 %b) {
; RV32-LABEL: select_add_1:
; RV32: # %bb.0: # %entry
-; RV32-NEXT: beqz a0, .LBB16_2
-; RV32-NEXT: # %bb.1:
-; RV32-NEXT: add a2, a1, a2
-; RV32-NEXT: .LBB16_2: # %entry
-; RV32-NEXT: mv a0, a2
+; RV32-NEXT: neg a0, a0
+; RV32-NEXT: and a0, a0, a1
+; RV32-NEXT: add a0, a2, a0
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_add_1:
@@ -578,11 +527,9 @@ entry:
define i32 @select_add_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV32-LABEL: select_add_2:
; RV32: # %bb.0: # %entry
-; RV32-NEXT: bnez a0, .LBB17_2
-; RV32-NEXT: # %bb.1: # %entry
-; RV32-NEXT: add a1, a1, a2
-; RV32-NEXT: .LBB17_2: # %entry
-; RV32-NEXT: mv a0, a1
+; RV32-NEXT: addi a0, a0, -1
+; RV32-NEXT: and a0, a0, a2
+; RV32-NEXT: add a0, a1, a0
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_add_2:
@@ -610,11 +557,9 @@ entry:
define i32 @select_add_3(i1 zeroext %cond, i32 %a) {
; RV32-LABEL: select_add_3:
; RV32: # %bb.0: # %entry
-; RV32-NEXT: bnez a0, .LBB18_2
-; RV32-NEXT: # %bb.1: # %entry
-; RV32-NEXT: addi a1, a1, 42
-; RV32-NEXT: .LBB18_2: # %entry
-; RV32-NEXT: mv a0, a1
+; RV32-NEXT: addi a0, a0, -1
+; RV32-NEXT: andi a0, a0, 42
+; RV32-NEXT: add a0, a1, a0
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_add_3:
@@ -674,11 +619,9 @@ entry:
define i32 @select_sub_2(i1 zeroext %cond, i32 %a, i32 %b) {
; RV32-LABEL: select_sub_2:
; RV32: # %bb.0: # %entry
-; RV32-NEXT: bnez a0, .LBB20_2
-; RV32-NEXT: # %bb.1: # %entry
-; RV32-NEXT: sub a1, a1, a2
-; RV32-NEXT: .LBB20_2: # %entry
-; RV32-NEXT: mv a0, a1
+; RV32-NEXT: addi a0, a0, -1
+; RV32-NEXT: and a0, a0, a2
+; RV32-NEXT: sub a0, a1, a0
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_sub_2:
@@ -706,11 +649,9 @@ entry:
define i32 @select_sub_3(i1 zeroext %cond, i32 %a) {
; RV32-LABEL: select_sub_3:
; RV32: # %bb.0: # %entry
-; RV32-NEXT: bnez a0, .LBB21_2
-; RV32-NEXT: # %bb.1: # %entry
-; RV32-NEXT: addi a1, a1, -42
-; RV32-NEXT: .LBB21_2: # %entry
-; RV32-NEXT: mv a0, a1
+; RV32-NEXT: addi a0, a0, -1
+; RV32-NEXT: andi a0, a0, 42
+; RV32-NEXT: sub a0, a1, a0
; RV32-NEXT: ret
;
; NOCONDOPS-LABEL: select_sub_3:
@@ -1161,5 +1102,3 @@ entry:
%res = select i1 %cond, i32 %a, i32 %c
ret i32 %res
}
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; RV64: {{.*}}
diff --git a/llvm/test/CodeGen/RISCV/sextw-removal.ll b/llvm/test/CodeGen/RISCV/sextw-removal.ll
index 976837ed13401..1d1883716d47c 100644
--- a/llvm/test/CodeGen/RISCV/sextw-removal.ll
+++ b/llvm/test/CodeGen/RISCV/sextw-removal.ll
@@ -1024,95 +1024,96 @@ bb7: ; preds = %bb2
define signext i32 @bug(i32 signext %x) {
; CHECK-LABEL: bug:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: beqz a0, .LBB18_10
+; CHECK-NEXT: beqz a0, .LBB18_11
; CHECK-NEXT: # %bb.1: # %if.end
; CHECK-NEXT: srliw a1, a0, 16
; CHECK-NEXT: beqz a1, .LBB18_3
; CHECK-NEXT: # %bb.2: # %if.end
; CHECK-NEXT: li a1, 32
-; CHECK-NEXT: srliw a2, a0, 24
-; CHECK-NEXT: beqz a2, .LBB18_4
-; CHECK-NEXT: j .LBB18_5
+; CHECK-NEXT: j .LBB18_4
; CHECK-NEXT: .LBB18_3:
; CHECK-NEXT: slliw a0, a0, 16
; CHECK-NEXT: li a1, 16
-; CHECK-NEXT: srliw a2, a0, 24
-; CHECK-NEXT: bnez a2, .LBB18_5
-; CHECK-NEXT: .LBB18_4:
+; CHECK-NEXT: .LBB18_4: # %if.end
+; CHECK-NEXT: srliw a3, a0, 24
+; CHECK-NEXT: snez a2, a3
+; CHECK-NEXT: bnez a3, .LBB18_6
+; CHECK-NEXT: # %bb.5:
; CHECK-NEXT: slliw a0, a0, 8
-; CHECK-NEXT: addi a1, a1, -8
-; CHECK-NEXT: .LBB18_5: # %if.end
-; CHECK-NEXT: srliw a2, a0, 28
-; CHECK-NEXT: beqz a2, .LBB18_11
-; CHECK-NEXT: # %bb.6: # %if.end
-; CHECK-NEXT: srliw a2, a0, 30
-; CHECK-NEXT: beqz a2, .LBB18_12
-; CHECK-NEXT: .LBB18_7: # %if.end
-; CHECK-NEXT: bnez a2, .LBB18_9
-; CHECK-NEXT: .LBB18_8:
-; CHECK-NEXT: addi a1, a1, -2
-; CHECK-NEXT: .LBB18_9: # %if.end
+; CHECK-NEXT: .LBB18_6: # %if.end
+; CHECK-NEXT: addiw a2, a2, -1
+; CHECK-NEXT: andi a2, a2, -8
+; CHECK-NEXT: addw a1, a1, a2
+; CHECK-NEXT: srliw a3, a0, 28
+; CHECK-NEXT: snez a2, a3
+; CHECK-NEXT: bnez a3, .LBB18_8
+; CHECK-NEXT: # %bb.7:
+; CHECK-NEXT: slliw a0, a0, 4
+; CHECK-NEXT: .LBB18_8: # %if.end
+; CHECK-NEXT: addiw a2, a2, -1
+; CHECK-NEXT: andi a2, a2, -4
+; CHECK-NEXT: addw a1, a1, a2
+; CHECK-NEXT: srliw a3, a0, 30
+; CHECK-NEXT: snez a2, a3
+; CHECK-NEXT: bnez a3, .LBB18_10
+; CHECK-NEXT: # %bb.9:
+; CHECK-NEXT: slliw a0, a0, 2
+; CHECK-NEXT: .LBB18_10: # %if.end
+; CHECK-NEXT: addiw a2, a2, -1
+; CHECK-NEXT: andi a2, a2, -2
+; CHECK-NEXT: addw a1, a1, a2
; CHECK-NEXT: not a0, a0
; CHECK-NEXT: srli a0, a0, 31
; CHECK-NEXT: addw a0, a1, a0
-; CHECK-NEXT: .LBB18_10: # %cleanup
+; CHECK-NEXT: .LBB18_11: # %cleanup
; CHECK-NEXT: ret
-; CHECK-NEXT: .LBB18_11:
-; CHECK-NEXT: slliw a0, a0, 4
-; CHECK-NEXT: addi a1, a1, -4
-; CHECK-NEXT: srliw a2, a0, 30
-; CHECK-NEXT: bnez a2, .LBB18_7
-; CHECK-NEXT: .LBB18_12:
-; CHECK-NEXT: slliw a0, a0, 2
-; CHECK-NEXT: beqz a2, .LBB18_8
-; CHECK-NEXT: j .LBB18_9
;
; NOREMOVAL-LABEL: bug:
; NOREMOVAL: # %bb.0: # %entry
-; NOREMOVAL-NEXT: beqz a0, .LBB18_10
+; NOREMOVAL-NEXT: beqz a0, .LBB18_11
; NOREMOVAL-NEXT: # %bb.1: # %if.end
; NOREMOVAL-NEXT: srliw a1, a0, 16
; NOREMOVAL-NEXT: beqz a1, .LBB18_3
; NOREMOVAL-NEXT: # %bb.2: # %if.end
; NOREMOVAL-NEXT: li a1, 32
-; NOREMOVAL-NEXT: srliw a2, a0, 24
-; NOREMOVAL-NEXT: beqz a2, .LBB18_4
-; NOREMOVAL-NEXT: j .LBB18_5
+; NOREMOVAL-NEXT: j .LBB18_4
; NOREMOVAL-NEXT: .LBB18_3:
; NOREMOVAL-NEXT: slliw a0, a0, 16
; NOREMOVAL-NEXT: li a1, 16
-; NOREMOVAL-NEXT: srliw a2, a0, 24
-; NOREMOVAL-NEXT: bnez a2, .LBB18_5
-; NOREMOVAL-NEXT: .LBB18_4:
+; NOREMOVAL-NEXT: .LBB18_4: # %if.end
+; NOREMOVAL-NEXT: srliw a3, a0, 24
+; NOREMOVAL-NEXT: snez a2, a3
+; NOREMOVAL-NEXT: bnez a3, .LBB18_6
+; NOREMOVAL-NEXT: # %bb.5:
; NOREMOVAL-NEXT: slliw a0, a0, 8
-; NOREMOVAL-NEXT: addi a1, a1, -8
-; NOREMOVAL-NEXT: .LBB18_5: # %if.end
-; NOREMOVAL-NEXT: srliw a2, a0, 28
-; NOREMOVAL-NEXT: beqz a2, .LBB18_11
-; NOREMOVAL-NEXT: # %bb.6: # %if.end
-; NOREMOVAL-NEXT: srliw a2, a0, 30
-; NOREMOVAL-NEXT: beqz a2, .LBB18_12
-; NOREMOVAL-NEXT: .LBB18_7: # %if.end
+; NOREMOVAL-NEXT: .LBB18_6: # %if.end
+; NOREMOVAL-NEXT: addiw a2, a2, -1
+; NOREMOVAL-NEXT: andi a2, a2, -8
+; NOREMOVAL-NEXT: addw a1, a1, a2
+; NOREMOVAL-NEXT: srliw a3, a0, 28
+; NOREMOVAL-NEXT: snez a2, a3
+; NOREMOVAL-NEXT: bnez a3, .LBB18_8
+; NOREMOVAL-NEXT: # %bb.7:
+; NOREMOVAL-NEXT: slliw a0, a0, 4
+; NOREMOVAL-NEXT: .LBB18_8: # %if.end
+; NOREMOVAL-NEXT: addiw a2, a2, -1
+; NOREMOVAL-NEXT: andi a2, a2, -4
+; NOREMOVAL-NEXT: addw a1, a1, a2
+; NOREMOVAL-NEXT: srliw a3, a0, 30
+; NOREMOVAL-NEXT: snez a2, a3
+; NOREMOVAL-NEXT: bnez a3, .LBB18_10
+; NOREMOVAL-NEXT: # %bb.9:
+; NOREMOVAL-NEXT: slli a0, a0, 2
+; NOREMOVAL-NEXT: .LBB18_10: # %if.end
; NOREMOVAL-NEXT: sext.w a0, a0
-; NOREMOVAL-NEXT: bnez a2, .LBB18_9
-; NOREMOVAL-NEXT: .LBB18_8:
-; NOREMOVAL-NEXT: addi a1, a1, -2
-; NOREMOVAL-NEXT: .LBB18_9: # %if.end
+; NOREMOVAL-NEXT: addiw a2, a2, -1
+; NOREMOVAL-NEXT: andi a2, a2, -2
+; NOREMOVAL-NEXT: addw a1, a1, a2
; NOREMOVAL-NEXT: not a0, a0
; NOREMOVAL-NEXT: srli a0, a0, 31
; NOREMOVAL-NEXT: addw a0, a1, a0
-; NOREMOVAL-NEXT: .LBB18_10: # %cleanup
+; NOREMOVAL-NEXT: .LBB18_11: # %cleanup
; NOREMOVAL-NEXT: ret
-; NOREMOVAL-NEXT: .LBB18_11:
-; NOREMOVAL-NEXT: slliw a0, a0, 4
-; NOREMOVAL-NEXT: addi a1, a1, -4
-; NOREMOVAL-NEXT: srliw a2, a0, 30
-; NOREMOVAL-NEXT: bnez a2, .LBB18_7
-; NOREMOVAL-NEXT: .LBB18_12:
-; NOREMOVAL-NEXT: slli a0, a0, 2
-; NOREMOVAL-NEXT: sext.w a0, a0
-; NOREMOVAL-NEXT: beqz a2, .LBB18_8
-; NOREMOVAL-NEXT: j .LBB18_9
entry:
%tobool.not = icmp eq i32 %x, 0
br i1 %tobool.not, label %cleanup, label %if.end
More information about the llvm-commits
mailing list