Skip to content

Commit 1455b3c

Browse files
authored
[RISCV] Reorganize select lowering to pull binop expansion early (llvm#156974)
This is purely stylistic, but I think makes the code easier to follow. It isn't quite NFC because it undoes the arithmetic lowering added yesterday in llvm#156957 for the select c, simm12, 0 cases for a processor with both conditional move forwarding and zicond. What the right code is for that combination of features is currently an open question.
1 parent be1510f commit 1455b3c

File tree

2 files changed

+22
-36
lines changed

2 files changed

+22
-36
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9114,8 +9114,12 @@ static std::optional<bool> matchSetCC(SDValue LHS, SDValue RHS,
91149114
return std::nullopt;
91159115
}
91169116

9117-
static SDValue combineSelectToBinOp(SDNode *N, SelectionDAG &DAG,
9118-
const RISCVSubtarget &Subtarget) {
9117+
static bool isSimm12Constant(SDValue V) {
9118+
return isa<ConstantSDNode>(V) && V->getAsAPIntVal().isSignedIntN(12);
9119+
}
9120+
9121+
static SDValue lowerSelectToBinOp(SDNode *N, SelectionDAG &DAG,
9122+
const RISCVSubtarget &Subtarget) {
91199123
SDValue CondV = N->getOperand(0);
91209124
SDValue TrueV = N->getOperand(1);
91219125
SDValue FalseV = N->getOperand(2);
@@ -9135,14 +9139,18 @@ static SDValue combineSelectToBinOp(SDNode *N, SelectionDAG &DAG,
91359139
return DAG.getNode(ISD::OR, DL, VT, Neg, DAG.getFreeze(TrueV));
91369140
}
91379141

9142+
const bool HasCZero =
9143+
VT.isScalarInteger() &&
9144+
(Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps());
9145+
91389146
// (select c, 0, y) -> (c-1) & y
9139-
if (isNullConstant(TrueV)) {
9140-
SDValue Neg = DAG.getNode(ISD::ADD, DL, VT, CondV,
9141-
DAG.getAllOnesConstant(DL, VT));
9147+
if (isNullConstant(TrueV) && (!HasCZero || isSimm12Constant(FalseV))) {
9148+
SDValue Neg =
9149+
DAG.getNode(ISD::ADD, DL, VT, CondV, DAG.getAllOnesConstant(DL, VT));
91429150
return DAG.getNode(ISD::AND, DL, VT, Neg, DAG.getFreeze(FalseV));
91439151
}
91449152
// (select c, y, 0) -> -c & y
9145-
if (isNullConstant(FalseV)) {
9153+
if (isNullConstant(FalseV) && (!HasCZero || isSimm12Constant(TrueV))) {
91469154
SDValue Neg = DAG.getNegative(CondV, DL, VT);
91479155
return DAG.getNode(ISD::AND, DL, VT, Neg, DAG.getFreeze(TrueV));
91489156
}
@@ -9248,10 +9256,6 @@ foldBinOpIntoSelectIfProfitable(SDNode *BO, SelectionDAG &DAG,
92489256
return DAG.getSelect(DL, VT, Sel.getOperand(0), NewT, NewF);
92499257
}
92509258

9251-
static bool isSimm12Constant(SDValue V) {
9252-
return isa<ConstantSDNode>(V) && V->getAsAPIntVal().isSignedIntN(12);
9253-
}
9254-
92559259
SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
92569260
SDValue CondV = Op.getOperand(0);
92579261
SDValue TrueV = Op.getOperand(1);
@@ -9267,26 +9271,17 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
92679271
return DAG.getNode(ISD::VSELECT, DL, VT, CondSplat, TrueV, FalseV);
92689272
}
92699273

9274+
// Try some other optimizations before falling back to generic lowering.
9275+
if (SDValue V = lowerSelectToBinOp(Op.getNode(), DAG, Subtarget))
9276+
return V;
9277+
92709278
// When Zicond or XVentanaCondOps is present, emit CZERO_EQZ and CZERO_NEZ
92719279
// nodes to implement the SELECT. Performing the lowering here allows for
92729280
// greater control over when CZERO_{EQZ/NEZ} are used vs another branchless
92739281
// sequence or RISCVISD::SELECT_CC node (branch-based select).
92749282
if ((Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps()) &&
92759283
VT.isScalarInteger()) {
92769284

9277-
// select c, simm12, 0 -> andi (sub x0, c), simm12
9278-
if (isSimm12Constant(TrueV) && isNullConstant(FalseV)) {
9279-
SDValue Mask = DAG.getNegative(CondV, DL, VT);
9280-
return DAG.getNode(ISD::AND, DL, VT, TrueV, Mask);
9281-
}
9282-
9283-
// select c, 0, simm12 -> andi (addi c, -1), simm12
9284-
if (isNullConstant(TrueV) && isSimm12Constant(FalseV)) {
9285-
SDValue Mask = DAG.getNode(ISD::ADD, DL, VT, CondV,
9286-
DAG.getSignedConstant(-1, DL, XLenVT));
9287-
return DAG.getNode(ISD::AND, DL, VT, FalseV, Mask);
9288-
}
9289-
92909285
// (select c, t, 0) -> (czero_eqz t, c)
92919286
if (isNullConstant(FalseV))
92929287
return DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV);
@@ -9340,10 +9335,6 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
93409335
DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV));
93419336
}
93429337

9343-
// Try some other optimizations before falling back to generic lowering.
9344-
if (SDValue V = combineSelectToBinOp(Op.getNode(), DAG, Subtarget))
9345-
return V;
9346-
93479338
// (select c, c1, c2) -> (add (czero_nez c2 - c1, c), c1)
93489339
// (select c, c1, c2) -> (add (czero_eqz c1 - c2, c), c2)
93499340
if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
@@ -9446,9 +9437,6 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
94469437
SDNodeFlags::Disjoint);
94479438
}
94489439

9449-
if (SDValue V = combineSelectToBinOp(Op.getNode(), DAG, Subtarget))
9450-
return V;
9451-
94529440
if (Op.hasOneUse()) {
94539441
unsigned UseOpc = Op->user_begin()->getOpcode();
94549442
if (isBinOp(UseOpc) && DAG.isSafeToSpeculativelyExecute(UseOpc)) {

llvm/test/CodeGen/RISCV/cmov-branch-opt.ll

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,8 @@ define signext i32 @test4(i32 signext %x, i32 signext %y, i32 signext %z) {
149149
;
150150
; CMOV-ZICOND-LABEL: test4:
151151
; CMOV-ZICOND: # %bb.0:
152-
; CMOV-ZICOND-NEXT: snez a0, a2
153-
; CMOV-ZICOND-NEXT: addi a0, a0, -1
154-
; CMOV-ZICOND-NEXT: andi a0, a0, 3
152+
; CMOV-ZICOND-NEXT: li a0, 3
153+
; CMOV-ZICOND-NEXT: czero.nez a0, a0, a2
155154
; CMOV-ZICOND-NEXT: ret
156155
;
157156
; SFB-NOZICOND-LABEL: test4:
@@ -165,9 +164,8 @@ define signext i32 @test4(i32 signext %x, i32 signext %y, i32 signext %z) {
165164
;
166165
; SFB-ZICOND-LABEL: test4:
167166
; SFB-ZICOND: # %bb.0:
168-
; SFB-ZICOND-NEXT: snez a0, a2
169-
; SFB-ZICOND-NEXT: addi a0, a0, -1
170-
; SFB-ZICOND-NEXT: andi a0, a0, 3
167+
; SFB-ZICOND-NEXT: li a0, 3
168+
; SFB-ZICOND-NEXT: czero.nez a0, a0, a2
171169
; SFB-ZICOND-NEXT: ret
172170
%c = icmp eq i32 %z, 0
173171
%a = select i1 %c, i32 3, i32 0

0 commit comments

Comments
 (0)