aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/RISCV/RISCVISelLowering.cpp20
-rw-r--r--llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll25
2 files changed, 37 insertions, 8 deletions
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 3711e52..e23844d 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -6206,6 +6206,13 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
// Transform
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
+ SDValue TrueV = N->getOperand(3);
+ SDValue FalseV = N->getOperand(4);
+
+ // If the True and False values are the same, we don't need a select_cc.
+ if (TrueV == FalseV)
+ return TrueV;
+
ISD::CondCode CCVal = cast<CondCodeSDNode>(N->getOperand(2))->get();
if (!ISD::isIntEqualitySetCC(CCVal))
break;
@@ -6228,9 +6235,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
translateSetCCForBranch(DL, LHS, RHS, CCVal, DAG);
SDValue TargetCC = DAG.getCondCode(CCVal);
- return DAG.getNode(
- RISCVISD::SELECT_CC, DL, N->getValueType(0),
- {LHS, RHS, TargetCC, N->getOperand(3), N->getOperand(4)});
+ return DAG.getNode(RISCVISD::SELECT_CC, DL, N->getValueType(0),
+ {LHS, RHS, TargetCC, TrueV, FalseV});
}
// Fold (select_cc (xor X, Y), 0, eq/ne, trueV, falseV) ->
@@ -6238,8 +6244,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
if (LHS.getOpcode() == ISD::XOR && isNullConstant(RHS))
return DAG.getNode(RISCVISD::SELECT_CC, SDLoc(N), N->getValueType(0),
{LHS.getOperand(0), LHS.getOperand(1),
- N->getOperand(2), N->getOperand(3),
- N->getOperand(4)});
+ N->getOperand(2), TrueV, FalseV});
// (select_cc X, 1, setne, trueV, falseV) ->
// (select_cc X, 0, seteq, trueV, falseV) if we can prove X is 0/1.
// This can occur when legalizing some floating point comparisons.
@@ -6249,9 +6254,8 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
CCVal = ISD::getSetCCInverse(CCVal, LHS.getValueType());
SDValue TargetCC = DAG.getCondCode(CCVal);
RHS = DAG.getConstant(0, DL, LHS.getValueType());
- return DAG.getNode(
- RISCVISD::SELECT_CC, DL, N->getValueType(0),
- {LHS, RHS, TargetCC, N->getOperand(3), N->getOperand(4)});
+ return DAG.getNode(RISCVISD::SELECT_CC, DL, N->getValueType(0),
+ {LHS, RHS, TargetCC, TrueV, FalseV});
}
break;
diff --git a/llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll b/llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll
index 9384b4a..8ff72b3 100644
--- a/llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll
+++ b/llvm/test/CodeGen/RISCV/rvv/rvv-vscale.i64.ll
@@ -81,4 +81,29 @@ entry:
ret i64 %1
}
+; vscale will always be a positive number, but we don't know that until after op
+; legalization. The and will be considered a NOP and replaced with its input,
+; but not until after the select becomes RISCVISD::SELECT_CC. Make sure we
+; simplify this and don't leave behind any code for calculating the select
+; condition.
+define i64 @vscale_select(i32 %x, i32 %y) {
+; RV64-LABEL: vscale_select:
+; RV64: # %bb.0:
+; RV64-NEXT: csrr a0, vlenb
+; RV64-NEXT: srli a0, a0, 3
+; RV64-NEXT: ret
+;
+; RV32-LABEL: vscale_select:
+; RV32: # %bb.0:
+; RV32-NEXT: csrr a0, vlenb
+; RV32-NEXT: srli a0, a0, 3
+; RV32-NEXT: mv a1, zero
+; RV32-NEXT: ret
+ %a = call i64 @llvm.vscale.i64()
+ %b = and i64 %a, 4294967295
+ %c = icmp eq i32 %x, %y
+ %d = select i1 %c, i64 %a, i64 %b
+ ret i64 %d
+}
+
declare i64 @llvm.vscale.i64()