@@ -23523,9 +23523,8 @@ X86TargetLowering::BuildSDIVPow2(SDNode *N, const APInt &Divisor,
23523
23523
23524
23524
/// Result of 'and' is compared against zero. Change to a BT node if possible.
23525
23525
/// 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) {
23529
23528
assert(And.getOpcode() == ISD::AND && "Expected AND node!");
23530
23529
SDValue Op0 = And.getOperand(0);
23531
23530
SDValue Op1 = And.getOperand(1);
@@ -23587,9 +23586,13 @@ static SDValue LowerAndToBT(SDValue And, ISD::CondCode CC,
23587
23586
// that doing a bittest on the i32 value is ok. We extend to i32 because
23588
23587
// the encoding for the i16 version is larger than the i32 version.
23589
23588
// 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 )
23591
23590
Src = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, Src);
23592
23591
23592
+ // No legal type found, give up.
23593
+ if (!DAG.getTargetLoweringInfo().isTypeLegal(Src.getValueType()))
23594
+ return SDValue();
23595
+
23593
23596
// See if we can use the 32-bit instruction instead of the 64-bit one for a
23594
23597
// shorter encoding. Since the former takes the modulo 32 of BitNo and the
23595
23598
// 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,
23603
23606
if (Src.getValueType() != BitNo.getValueType())
23604
23607
BitNo = DAG.getNode(ISD::ANY_EXTEND, dl, Src.getValueType(), BitNo);
23605
23608
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;
23608
23610
return DAG.getNode(X86ISD::BT, dl, MVT::i32, Src, BitNo);
23609
23611
}
23610
23612
@@ -24310,8 +24312,11 @@ SDValue X86TargetLowering::emitFlagsForSetcc(SDValue Op0, SDValue Op1,
24310
24312
// Lower ((X >>s N) & 1) != 0 to BT(X, N).
24311
24313
if (Op0.getOpcode() == ISD::AND && Op0.hasOneUse() && isNullConstant(Op1) &&
24312
24314
(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);
24314
24318
return BT;
24319
+ }
24315
24320
}
24316
24321
24317
24322
// 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 {
24783
24788
// We know the result of AND is compared against zero. Try to match
24784
24789
// it to BT.
24785
24790
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) ;
24789
24794
Cond = BT;
24790
24795
AddTest = false;
24791
24796
}
@@ -52294,6 +52299,7 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
52294
52299
/// If this is an add or subtract where one operand is produced by a cmp+setcc,
52295
52300
/// then try to convert it to an ADC or SBB. This replaces TEST+SET+{ADD/SUB}
52296
52301
/// with CMP+{ADC, SBB}.
52302
+ /// Also try (ADD/SUB)+(AND(SRL,1)) bit extraction pattern with BT+{ADC, SBB}.
52297
52303
static SDValue combineAddOrSubToADCOrSBB(bool IsSub, const SDLoc &DL, EVT VT,
52298
52304
SDValue X, SDValue Y,
52299
52305
SelectionDAG &DAG) {
@@ -52304,11 +52310,20 @@ static SDValue combineAddOrSubToADCOrSBB(bool IsSub, const SDLoc &DL, EVT VT,
52304
52310
if (Y.getOpcode() == ISD::ZERO_EXTEND && Y.hasOneUse())
52305
52311
Y = Y.getOperand(0);
52306
52312
52307
- if (Y.getOpcode() != X86ISD::SETCC || !Y.hasOneUse())
52313
+ if (!Y.hasOneUse())
52308
52314
return SDValue();
52309
52315
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();
52312
52327
52313
52328
// If X is -1 or 0, then we have an opportunity to avoid constants required in
52314
52329
// the general case below.
0 commit comments