Skip to content

Commit

Permalink
[RISCV] Handle seteq/setne conditions for CZERO_NEZ/CZERO_EQZ during …
Browse files Browse the repository at this point in the history
…isel.

This removes selectSETCC and adds isel patterns for seteq/setne
conditions.

This removes the duplication of selectSETCC between lowering and
isel. This also gets some cases in xaluo.ll that we missed previously.

Reviewed By: wangpc

Differential Revision: https://reviews.llvm.org/D156250
  • Loading branch information
topperc committed Jul 26, 2023
1 parent c217ff8 commit e28307e
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 174 deletions.
79 changes: 0 additions & 79 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5908,56 +5908,6 @@ static SDValue combineSelectToBinOp(SDNode *N, SelectionDAG &DAG,
return SDValue();
}

/// RISC-V doesn't have general instructions for integer setne/seteq, but we can
/// check for equality with 0. This function emits nodes that convert the
/// seteq/setne into something that can be compared with 0.
/// Based on RISCVDAGToDAGISel::selectSETCC but modified to produce
/// target-independent SelectionDAG nodes rather than machine nodes.
static SDValue selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal,
SelectionDAG &DAG) {
assert(ISD::isIntEqualitySetCC(ExpectedCCVal) &&
"Unexpected condition code!");

// We're looking for a setcc.
if (N->getOpcode() != ISD::SETCC)
return SDValue();

// Must be an equality comparison.
ISD::CondCode CCVal = cast<CondCodeSDNode>(N->getOperand(2))->get();
if (CCVal != ExpectedCCVal)
return SDValue();

SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);

if (!LHS.getValueType().isScalarInteger())
return SDValue();

// If the RHS side is 0, we don't need any extra instructions, return the LHS.
if (isNullConstant(RHS))
return LHS;

SDLoc DL(N);

if (auto *C = dyn_cast<ConstantSDNode>(RHS)) {
int64_t CVal = C->getSExtValue();
// If the RHS is -2048, we can use xori to produce 0 if the LHS is -2048 and
// non-zero otherwise.
if (CVal == -2048)
return DAG.getNode(ISD::XOR, DL, N->getValueType(0), LHS,
DAG.getConstant(CVal, DL, N->getValueType(0)));
// If the RHS is [-2047,2048], we can use addi with -RHS to produce 0 if the
// LHS is equal to the RHS and non-zero otherwise.
if (isInt<12>(CVal) || CVal == 2048)
return DAG.getNode(ISD::ADD, DL, N->getValueType(0), LHS,
DAG.getConstant(-CVal, DL, N->getValueType(0)));
}

// If nothing else we can XOR the LHS and RHS to produce zero if they are
// equal and a non-zero value if they aren't.
return DAG.getNode(ISD::XOR, DL, N->getValueType(0), LHS, RHS);
}

// Transform `binOp (select cond, x, c0), c1` where `c0` and `c1` are constants
// into `select cond, binOp(x, c1), binOp(c0, c1)` if profitable.
// For now we only consider transformation profitable if `binOp(c0, c1)` ends up
Expand Down Expand Up @@ -6045,35 +5995,6 @@ SDValue RISCVTargetLowering::lowerSELECT(SDValue Op, SelectionDAG &DAG) const {
// sequence or RISCVISD::SELECT_CC node (branch-based select).
if ((Subtarget.hasStdExtZicond() || Subtarget.hasVendorXVentanaCondOps()) &&
VT.isScalarInteger()) {
if (SDValue NewCondV = selectSETCC(CondV, ISD::SETNE, DAG)) {
// (select (riscv_setne c), t, 0) -> (czero_eqz t, c)
if (isNullConstant(FalseV))
return DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, NewCondV);
// (select (riscv_setne c), 0, f) -> (czero_nez f, c)
if (isNullConstant(TrueV))
return DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, NewCondV);
// (select (riscv_setne c), t, f) -> (or (czero_eqz t, c), (czero_nez f,
// c)
return DAG.getNode(
ISD::OR, DL, VT,
DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, NewCondV),
DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, FalseV, NewCondV));
}
if (SDValue NewCondV = selectSETCC(CondV, ISD::SETEQ, DAG)) {
// (select (riscv_seteq c), t, 0) -> (czero_nez t, c)
if (isNullConstant(FalseV))
return DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, TrueV, NewCondV);
// (select (riscv_seteq c), 0, f) -> (czero_eqz f, c)
if (isNullConstant(TrueV))
return DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, FalseV, NewCondV);
// (select (riscv_seteq c), t, f) -> (or (czero_eqz f, c), (czero_nez t,
// c)
return DAG.getNode(
ISD::OR, DL, VT,
DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, FalseV, NewCondV),
DAG.getNode(RISCVISD::CZERO_NEZ, DL, VT, TrueV, NewCondV));
}

// (select c, t, 0) -> (czero_eqz t, c)
if (isNullConstant(FalseV))
return DAG.getNode(RISCVISD::CZERO_EQZ, DL, VT, TrueV, CondV);
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,13 @@ def : Pat<(XLenVT (riscv_czero_eqz GPR:$rs1, GPR:$rc)),
(VT_MASKC GPR:$rs1, GPR:$rc)>;
def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, GPR:$rc)),
(VT_MASKCN GPR:$rs1, GPR:$rc)>;

def : Pat<(XLenVT (riscv_czero_eqz GPR:$rs1, (riscv_setne (XLenVT GPR:$rc)))),
(VT_MASKC GPR:$rs1, GPR:$rc)>;
def : Pat<(XLenVT (riscv_czero_eqz GPR:$rs1, (riscv_seteq (XLenVT GPR:$rc)))),
(VT_MASKCN GPR:$rs1, GPR:$rc)>;
def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, (riscv_setne (XLenVT GPR:$rc)))),
(VT_MASKCN GPR:$rs1, GPR:$rc)>;
def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, (riscv_seteq (XLenVT GPR:$rc)))),
(VT_MASKC GPR:$rs1, GPR:$rc)>;
} // Predicates = [IsRV64, HasVendorXVentanaCondOps]
9 changes: 9 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZicond.td
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,13 @@ def : Pat<(XLenVT (riscv_czero_eqz GPR:$rs1, GPR:$rc)),
(CZERO_EQZ GPR:$rs1, GPR:$rc)>;
def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, GPR:$rc)),
(CZERO_NEZ GPR:$rs1, GPR:$rc)>;

def : Pat<(XLenVT (riscv_czero_eqz GPR:$rs1, (riscv_setne (XLenVT GPR:$rc)))),
(CZERO_EQZ GPR:$rs1, GPR:$rc)>;
def : Pat<(XLenVT (riscv_czero_eqz GPR:$rs1, (riscv_seteq (XLenVT GPR:$rc)))),
(CZERO_NEZ GPR:$rs1, GPR:$rc)>;
def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, (riscv_setne (XLenVT GPR:$rc)))),
(CZERO_NEZ GPR:$rs1, GPR:$rc)>;
def : Pat<(XLenVT (riscv_czero_nez GPR:$rs1, (riscv_seteq (XLenVT GPR:$rc)))),
(CZERO_EQZ GPR:$rs1, GPR:$rc)>;
} // Predicates = [HasStdExtZicond]
Loading

0 comments on commit e28307e

Please sign in to comment.