Skip to content

Commit

Permalink
[RISCV] Break the (czero_eqz x, (setne x, 0)) -> x combine into 2 com…
Browse files Browse the repository at this point in the history
…bines. (#90428)

We can think of this as two separate combines

(czero_eqz x, (setne y, 0)) -> (czero_eqz x, y)
and
(czero_eqz x, x) -> x

Similary the (czero_nez x, (seteq x, 0)) -> x combine can be broken into

(czero_nez x, (seteq y, 0)) -> (czero_eqz x, y)
and
(czero_eqz x, x) -> x

isel already does the (czero_eqz x, (setne y, 0)) -> (czero_eqz x, y)
and (czero_nez x, (seteq y, 0)) -> (czero_eqz x, y) combines, but doing
them early could expose other opportunities.
  • Loading branch information
topperc committed Apr 29, 2024
1 parent 618adc7 commit f9d4d54
Showing 1 changed file with 29 additions and 21 deletions.
50 changes: 29 additions & 21 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16168,28 +16168,36 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
return performSELECTCombine(N, DAG, Subtarget);
case RISCVISD::CZERO_EQZ:
case RISCVISD::CZERO_NEZ: {
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
// czero_eq X, (xor Y, 1) -> czero_ne X, Y if Y is 0 or 1.
// czero_ne X, (xor Y, 1) -> czero_eq X, Y if Y is 0 or 1.
if (RHS.getOpcode() == ISD::XOR && isOneConstant(RHS.getOperand(1))) {
SDValue Cond = RHS.getOperand(0);
APInt Mask = APInt::getBitsSetFrom(Cond.getValueSizeInBits(), 1);
if (DAG.MaskedValueIsZero(Cond, Mask)) {
unsigned NewOpc = N->getOpcode() == RISCVISD::CZERO_EQZ
? RISCVISD::CZERO_NEZ
: RISCVISD::CZERO_EQZ;
return DAG.getNode(NewOpc, SDLoc(N), N->getValueType(0), LHS, Cond);
}
SDValue Val = N->getOperand(0);
SDValue Cond = N->getOperand(1);

unsigned Opc = N->getOpcode();

// czero_eqz x, x -> x
if (Opc == RISCVISD::CZERO_EQZ && Val == Cond)
return Val;

unsigned InvOpc =
Opc == RISCVISD::CZERO_EQZ ? RISCVISD::CZERO_NEZ : RISCVISD::CZERO_EQZ;

// czero_eqz X, (xor Y, 1) -> czero_nez X, Y if Y is 0 or 1.
// czero_nez X, (xor Y, 1) -> czero_eqz X, Y if Y is 0 or 1.
if (Cond.getOpcode() == ISD::XOR && isOneConstant(Cond.getOperand(1))) {
SDValue NewCond = Cond.getOperand(0);
APInt Mask = APInt::getBitsSetFrom(NewCond.getValueSizeInBits(), 1);
if (DAG.MaskedValueIsZero(NewCond, Mask))
return DAG.getNode(InvOpc, SDLoc(N), N->getValueType(0), Val, NewCond);
}
// czero_eqz x, (setcc y, 0, ne) -> czero_eqz x, y
// czero_nez x, (setcc y, 0, ne) -> czero_nez x, y
// czero_eqz x, (setcc y, 0, eq) -> czero_nez x, y
// czero_nez x, (setcc y, 0, eq) -> czero_eqz x, y
if (Cond.getOpcode() == ISD::SETCC && isNullConstant(Cond.getOperand(1))) {
ISD::CondCode CCVal = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
if (ISD::isIntEqualitySetCC(CCVal))
return DAG.getNode(CCVal == ISD::SETNE ? Opc : InvOpc, SDLoc(N),
N->getValueType(0), Val, Cond.getOperand(0));
}
// czero_eqz x, (setcc x, 0, ne) -> x
// czero_nez x, (setcc x, 0, eq) -> x
if (RHS.getOpcode() == ISD::SETCC && isNullConstant(RHS.getOperand(1)) &&
cast<CondCodeSDNode>(RHS.getOperand(2))->get() ==
(N->getOpcode() == RISCVISD::CZERO_EQZ ? ISD::CondCode::SETNE
: ISD::CondCode::SETEQ) &&
LHS == RHS.getOperand(0))
return LHS;
return SDValue();
}
case RISCVISD::SELECT_CC: {
Expand Down

0 comments on commit f9d4d54

Please sign in to comment.