Skip to content

Commit edd0cb1

Browse files
committed
[SelectionDAG][X86] Enable SimplifySetCC CTPOP transforms for vector splats
This enables these transforms for vectors: (ctpop x) u< 2 -> (x & x-1) == 0 (ctpop x) u> 1 -> (x & x-1) != 0 (ctpop x) == 1 --> (x != 0) && ((x & x-1) == 0) (ctpop x) != 1 --> (x == 0) || ((x & x-1) != 0) All enabled if CTPOP isn't Legal. This differs from the scalar behavior where the first two are done unconditionally and the last two are done if CTPOP isn't Legal or Custom. The Legal check produced better results for vectors based on X86's custom handling. Might be worth re-visiting scalars here. I disabled the looking through truncate for vectors. The code that creates new setcc can use the same result VT as the original setcc even if we truncated the input. That may work work for most scalars, but definitely wouldn't work for vectors unless it was a vector of i1. Fixes or at least improves PR47825 Reviewed By: spatel Differential Revision: https://reviews.llvm.org/D89346
1 parent e28376e commit edd0cb1

File tree

4 files changed

+1480
-3678
lines changed

4 files changed

+1480
-3678
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3383,12 +3383,11 @@ static SDValue simplifySetCCWithCTPOP(const TargetLowering &TLI, EVT VT,
33833383
SDValue N0, const APInt &C1,
33843384
ISD::CondCode Cond, const SDLoc &dl,
33853385
SelectionDAG &DAG) {
3386-
assert(!VT.isVector() && "Vectors are not supported yet!");
3387-
33883386
// Look through truncs that don't change the value of a ctpop.
3387+
// FIXME: Add vector support? Need to be careful with setcc result type below.
33893388
SDValue CTPOP = N0;
3390-
if (N0.getOpcode() == ISD::TRUNCATE && N0.hasOneUse() &&
3391-
N0.getValueSizeInBits() > Log2_32(N0.getOperand(0).getValueSizeInBits()))
3389+
if (N0.getOpcode() == ISD::TRUNCATE && N0.hasOneUse() && !VT.isVector() &&
3390+
N0.getScalarValueSizeInBits() > Log2_32(N0.getOperand(0).getScalarValueSizeInBits()))
33923391
CTPOP = N0.getOperand(0);
33933392

33943393
if (CTPOP.getOpcode() != ISD::CTPOP || !CTPOP.hasOneUse())
@@ -3400,6 +3399,13 @@ static SDValue simplifySetCCWithCTPOP(const TargetLowering &TLI, EVT VT,
34003399
// (ctpop x) u< 2 -> (x & x-1) == 0
34013400
// (ctpop x) u> 1 -> (x & x-1) != 0
34023401
if ((Cond == ISD::SETULT && C1 == 2) || (Cond == ISD::SETUGT && C1 == 1)) {
3402+
// If this is a vector CTPOP, keep the CTPOP if it is legal.
3403+
// This based on X86's custom lowering for vector CTPOP which produces more
3404+
// instructions than the expansion here.
3405+
// TODO: Should we check if CTPOP is legal(or custom) for scalars?
3406+
if (VT.isVector() && TLI.isOperationLegal(ISD::CTPOP, CTVT))
3407+
return SDValue();
3408+
34033409
SDValue NegOne = DAG.getAllOnesConstant(dl, CTVT);
34043410
SDValue Add = DAG.getNode(ISD::ADD, dl, CTVT, CTOp, NegOne);
34053411
SDValue And = DAG.getNode(ISD::AND, dl, CTVT, CTOp, Add);
@@ -3408,8 +3414,16 @@ static SDValue simplifySetCCWithCTPOP(const TargetLowering &TLI, EVT VT,
34083414
}
34093415

34103416
// If ctpop is not supported, expand a power-of-2 comparison based on it.
3411-
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && C1 == 1 &&
3412-
!TLI.isOperationLegalOrCustom(ISD::CTPOP, CTVT)) {
3417+
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && C1 == 1) {
3418+
// For scalars, keep CTPOP if it is legal or custom.
3419+
if (!VT.isVector() && TLI.isOperationLegalOrCustom(ISD::CTPOP, CTVT))
3420+
return SDValue();
3421+
// For vectors, keep CTPOP only if it is legal.
3422+
// This is based on X86's custom lowering for CTPOP which produces more
3423+
// instructions than the expansion here.
3424+
if (VT.isVector() && TLI.isOperationLegal(ISD::CTPOP, CTVT))
3425+
return SDValue();
3426+
34133427
// (ctpop x) == 1 --> (x != 0) && ((x & x-1) == 0)
34143428
// (ctpop x) != 1 --> (x == 0) || ((x & x-1) != 0)
34153429
SDValue Zero = DAG.getConstant(0, dl, CTVT);
@@ -3460,6 +3474,15 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
34603474
!DAG.getNodeIfExists(ISD::SUB, DAG.getVTList(OpVT), { N0, N1 } ))
34613475
return DAG.getSetCC(dl, VT, N1, N0, SwappedCC);
34623476

3477+
if (auto *N1C = isConstOrConstSplat(N1)) {
3478+
const APInt &C1 = N1C->getAPIntValue();
3479+
3480+
// Optimize some CTPOP cases.
3481+
if (SDValue V = simplifySetCCWithCTPOP(*this, VT, N0, C1, Cond, dl, DAG))
3482+
return V;
3483+
}
3484+
3485+
// FIXME: Support vectors.
34633486
if (auto *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
34643487
const APInt &C1 = N1C->getAPIntValue();
34653488

@@ -3487,10 +3510,6 @@ SDValue TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
34873510
}
34883511
}
34893512

3490-
// Optimize some CTPOP cases.
3491-
if (SDValue V = simplifySetCCWithCTPOP(*this, VT, N0, C1, Cond, dl, DAG))
3492-
return V;
3493-
34943513
// (zext x) == C --> x == (trunc C)
34953514
// (sext x) == C --> x == (trunc C)
34963515
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&

0 commit comments

Comments
 (0)