Skip to content

Commit 806fdc7

Browse files
committed
[SDAG] Make Select-with-Identity-Fold More Flexible; NFC
This change introduces a new overload of the method `shouldFoldSelectWithIdentityConstant()`, which takes the opcode of the select node and the non-identity operand of the select node and is called after all other checks have been performed. Moreover, this change adjusts the precondition of the fold so that it would work for `SELECT` nodes in addition to `VSELECT` nodes. No functional change is intended because the default (and currently only) implementation restricts the fold to a `VSELECT` node; the same restriction as before. The rationale of this change is to make more fine grained decisions possible when to revert the InstCombine canonicalization of `(select c (binop x y) y)` to `(binop (select c x idc) y)` in the backends.
1 parent b6820c3 commit 806fdc7

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3351,13 +3351,26 @@ class TargetLoweringBase {
33513351
}
33523352

33533353
/// Return true if pulling a binary operation into a select with an identity
3354-
/// constant is profitable. This is the inverse of an IR transform.
3354+
/// constant is profitable for the given binary operation and type. This is
3355+
/// the inverse of an IR transform.
33553356
/// Example: X + (Cond ? Y : 0) --> Cond ? (X + Y) : X
33563357
virtual bool shouldFoldSelectWithIdentityConstant(unsigned BinOpcode,
33573358
EVT VT) const {
33583359
return false;
33593360
}
33603361

3362+
/// Return true if pulling a binary operation into a select with an identity
3363+
/// constant is profitable for the given binary operation, select operation,
3364+
/// operand to the binary operation, and select operand that is not the
3365+
/// identity constant. This is a more fine-grained variant of the previous
3366+
/// overload that is called only if the previous overload returned true.
3367+
virtual bool
3368+
shouldFoldSelectWithIdentityConstant(unsigned BinOpcode,
3369+
unsigned SelectOpcode, SDValue X,
3370+
SDValue NonIdConstNode) const {
3371+
return SelectOpcode == ISD::VSELECT;
3372+
}
3373+
33613374
/// Return true if it is beneficial to convert a load of a constant to
33623375
/// just the constant itself.
33633376
/// On some targets it might be more efficient to use a combination of

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2425,8 +2425,9 @@ static SDValue foldSelectWithIdentityConstant(SDNode *N, SelectionDAG &DAG,
24252425
if (ShouldCommuteOperands)
24262426
std::swap(N0, N1);
24272427

2428-
// TODO: Should this apply to scalar select too?
2429-
if (N1.getOpcode() != ISD::VSELECT || !N1.hasOneUse())
2428+
unsigned SelOpcode = N1.getOpcode();
2429+
if ((SelOpcode != ISD::VSELECT && SelOpcode != ISD::SELECT) ||
2430+
!N1.hasOneUse())
24302431
return SDValue();
24312432

24322433
// We can't hoist all instructions because of immediate UB (not speculatable).
@@ -2439,17 +2440,20 @@ static SDValue foldSelectWithIdentityConstant(SDNode *N, SelectionDAG &DAG,
24392440
SDValue Cond = N1.getOperand(0);
24402441
SDValue TVal = N1.getOperand(1);
24412442
SDValue FVal = N1.getOperand(2);
2443+
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
24422444

24432445
// This transform increases uses of N0, so freeze it to be safe.
24442446
// binop N0, (vselect Cond, IDC, FVal) --> vselect Cond, N0, (binop N0, FVal)
24452447
unsigned OpNo = ShouldCommuteOperands ? 0 : 1;
2446-
if (isNeutralConstant(Opcode, N->getFlags(), TVal, OpNo)) {
2448+
if (isNeutralConstant(Opcode, N->getFlags(), TVal, OpNo) &&
2449+
TLI.shouldFoldSelectWithIdentityConstant(Opcode, SelOpcode, N0, FVal)) {
24472450
SDValue F0 = DAG.getFreeze(N0);
24482451
SDValue NewBO = DAG.getNode(Opcode, SDLoc(N), VT, F0, FVal, N->getFlags());
24492452
return DAG.getSelect(SDLoc(N), VT, Cond, F0, NewBO);
24502453
}
24512454
// binop N0, (vselect Cond, TVal, IDC) --> vselect Cond, (binop N0, TVal), N0
2452-
if (isNeutralConstant(Opcode, N->getFlags(), FVal, OpNo)) {
2455+
if (isNeutralConstant(Opcode, N->getFlags(), FVal, OpNo) &&
2456+
TLI.shouldFoldSelectWithIdentityConstant(Opcode, SelOpcode, N0, TVal)) {
24532457
SDValue F0 = DAG.getFreeze(N0);
24542458
SDValue NewBO = DAG.getNode(Opcode, SDLoc(N), VT, F0, TVal, N->getFlags());
24552459
return DAG.getSelect(SDLoc(N), VT, Cond, NewBO, F0);

0 commit comments

Comments
 (0)