Skip to content

Commit 438ac28

Browse files
committed
[X86] combineAddOrSubToADCOrSBB - Fold ADD/SUB + (AND(SRL(X,Y),1) -> ADC/SBB+BT(X,Y) (REAPPLIED)
As suggested on PR35908, if we are adding/subtracting an extracted bit, attempt to use BT instead to fold the op and use a ADC/SBB op. Reapply with extra type legality checks - LowerAndToBT was originally only used during lowering, now that it can occur earlier we might encounter illegal types that we can either promote to i32 or just bail. Differential Revision: https://reviews.llvm.org/D122084
1 parent d137528 commit 438ac28

File tree

2 files changed

+179
-259
lines changed

2 files changed

+179
-259
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23523,9 +23523,8 @@ X86TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
2352323523

2352423524
/// Result of 'and' is compared against zero. Change to a BT node if possible.
2352523525
/// Returns the BT node and the condition code needed to use it.
23526-
static SDValue LowerAndToBT(SDValue And, ISD::CondCode CC,
23527-
const SDLoc &dl, SelectionDAG &DAG,
23528-
SDValue &X86CC) {
23526+
static SDValue LowerAndToBT(SDValue And, ISD::CondCode CC, const SDLoc &dl,
23527+
SelectionDAG &DAG, X86::CondCode &X86CC) {
2352923528
assert(And.getOpcode() == ISD::AND && "Expected AND node!");
2353023529
SDValue Op0 = And.getOperand(0);
2353123530
SDValue Op1 = And.getOperand(1);
@@ -23587,9 +23586,13 @@ static SDValue LowerAndToBT(SDValue And, ISD::CondCode CC,
2358723586
// that doing a bittest on the i32 value is ok. We extend to i32 because
2358823587
// the encoding for the i16 version is larger than the i32 version.
2358923588
// Also promote i16 to i32 for performance / code size reason.
23590-
if (Src.getValueType() == MVT::i8 || Src.getValueType() == MVT::i16)
23589+
if (Src.getValueType().getScalarSizeInBits() < 32)
2359123590
Src = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, Src);
2359223591

23592+
// No legal type found, give up.
23593+
if (!DAG.getTargetLoweringInfo().isTypeLegal(Src.getValueType()))
23594+
return SDValue();
23595+
2359323596
// See if we can use the 32-bit instruction instead of the 64-bit one for a
2359423597
// shorter encoding. Since the former takes the modulo 32 of BitNo and the
2359523598
// latter takes the modulo 64, this is only valid if the 5th bit of BitNo is
@@ -23603,8 +23606,7 @@ static SDValue LowerAndToBT(SDValue And, ISD::CondCode CC,
2360323606
if (Src.getValueType() != BitNo.getValueType())
2360423607
BitNo = DAG.getNode(ISD::ANY_EXTEND, dl, Src.getValueType(), BitNo);
2360523608

23606-
X86CC = DAG.getTargetConstant(CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B,
23607-
dl, MVT::i8);
23609+
X86CC = CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B;
2360823610
return DAG.getNode(X86ISD::BT, dl, MVT::i32, Src, BitNo);
2360923611
}
2361023612

@@ -24310,8 +24312,11 @@ SDValue X86TargetLowering::emitFlagsForSetcc(SDValue Op0, SDValue Op1,
2431024312
// Lower ((X >>s N) & 1) != 0 to BT(X, N).
2431124313
if (Op0.getOpcode() == ISD::AND && Op0.hasOneUse() && isNullConstant(Op1) &&
2431224314
(CC == ISD::SETEQ || CC == ISD::SETNE)) {
24313-
if (SDValue BT = LowerAndToBT(Op0, CC, dl, DAG, X86CC))
24315+
X86::CondCode X86CondCode;
24316+
if (SDValue BT = LowerAndToBT(Op0, CC, dl, DAG, X86CondCode)) {
24317+
X86CC = DAG.getTargetConstant(X86CondCode, dl, MVT::i8);
2431424318
return BT;
24319+
}
2431524320
}
2431624321

2431724322
// Try to use PTEST/PMOVMSKB for a tree ORs equality compared with 0.
@@ -24783,9 +24788,9 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
2478324788
// We know the result of AND is compared against zero. Try to match
2478424789
// it to BT.
2478524790
if (Cond.getOpcode() == ISD::AND && Cond.hasOneUse()) {
24786-
SDValue BTCC;
24787-
if (SDValue BT = LowerAndToBT(Cond, ISD::SETNE, DL, DAG, BTCC)) {
24788-
CC = BTCC;
24791+
X86::CondCode X86CondCode;
24792+
if (SDValue BT = LowerAndToBT(Cond, ISD::SETNE, DL, DAG, X86CondCode)) {
24793+
CC = DAG.getTargetConstant(X86CondCode, DL, MVT::i8);
2478924794
Cond = BT;
2479024795
AddTest = false;
2479124796
}
@@ -52294,6 +52299,7 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
5229452299
/// If this is an add or subtract where one operand is produced by a cmp+setcc,
5229552300
/// then try to convert it to an ADC or SBB. This replaces TEST+SET+{ADD/SUB}
5229652301
/// with CMP+{ADC, SBB}.
52302+
/// Also try (ADD/SUB)+(AND(SRL,1)) bit extraction pattern with BT+{ADC, SBB}.
5229752303
static SDValue combineAddOrSubToADCOrSBB(bool IsSub, const SDLoc &DL, EVT VT,
5229852304
SDValue X, SDValue Y,
5229952305
SelectionDAG &DAG) {
@@ -52304,11 +52310,20 @@ static SDValue combineAddOrSubToADCOrSBB(bool IsSub, const SDLoc &DL, EVT VT,
5230452310
if (Y.getOpcode() == ISD::ZERO_EXTEND && Y.hasOneUse())
5230552311
Y = Y.getOperand(0);
5230652312

52307-
if (Y.getOpcode() != X86ISD::SETCC || !Y.hasOneUse())
52313+
if (!Y.hasOneUse())
5230852314
return SDValue();
5230952315

52310-
X86::CondCode CC = (X86::CondCode)Y.getConstantOperandVal(0);
52311-
SDValue EFLAGS = Y.getOperand(1);
52316+
X86::CondCode CC;
52317+
SDValue EFLAGS;
52318+
if (Y.getOpcode() == X86ISD::SETCC) {
52319+
CC = (X86::CondCode)Y.getConstantOperandVal(0);
52320+
EFLAGS = Y.getOperand(1);
52321+
} else if (Y.getOpcode() == ISD::AND && isOneConstant(Y.getOperand(1))) {
52322+
EFLAGS = LowerAndToBT(Y, ISD::SETNE, DL, DAG, CC);
52323+
}
52324+
52325+
if (!EFLAGS)
52326+
return SDValue();
5231252327

5231352328
// If X is -1 or 0, then we have an opportunity to avoid constants required in
5231452329
// the general case below.

0 commit comments

Comments
 (0)