@@ -2296,6 +2296,28 @@ SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
2296
2296
uint64_t Offset = (uint64_t )AddVal->getZExtValue ();
2297
2297
if (!foldOffsetIntoAddress (Offset * AM.Scale , AM)) {
2298
2298
SDLoc DL (N);
2299
+ SDValue Res;
2300
+ // If we're also scaling, see if we can use that as well.
2301
+ if (AddSrc.getOpcode () == ISD::SHL &&
2302
+ isa<ConstantSDNode>(AddSrc.getOperand (1 ))) {
2303
+ SDValue ShVal = AddSrc.getOperand (0 );
2304
+ uint64_t ShAmt = AddSrc.getConstantOperandVal (1 );
2305
+ APInt HiBits =
2306
+ APInt::getHighBitsSet (AddSrc.getScalarValueSizeInBits (), ShAmt);
2307
+ uint64_t ScaleAmt = 1ULL << ShAmt;
2308
+ if ((AM.Scale * ScaleAmt) <= 8 &&
2309
+ (AddSrc->getFlags ().hasNoUnsignedWrap () ||
2310
+ CurDAG->MaskedValueIsZero (ShVal, HiBits))) {
2311
+ AM.Scale *= ScaleAmt;
2312
+ SDValue ExtShVal = CurDAG->getNode (Opc, DL, VT, ShVal);
2313
+ SDValue ExtShift = CurDAG->getNode (ISD::SHL, DL, VT, ExtShVal,
2314
+ AddSrc.getOperand (1 ));
2315
+ insertDAGNode (*CurDAG, N, ExtShVal);
2316
+ insertDAGNode (*CurDAG, N, ExtShift);
2317
+ AddSrc = ExtShift;
2318
+ Res = ExtShVal;
2319
+ }
2320
+ }
2299
2321
SDValue ExtSrc = CurDAG->getNode (Opc, DL, VT, AddSrc);
2300
2322
SDValue ExtVal = CurDAG->getConstant (Offset, DL, VT);
2301
2323
SDValue ExtAdd = CurDAG->getNode (SrcOpc, DL, VT, ExtSrc, ExtVal);
@@ -2304,7 +2326,7 @@ SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
2304
2326
insertDAGNode (*CurDAG, N, ExtAdd);
2305
2327
CurDAG->ReplaceAllUsesWith (N, ExtAdd);
2306
2328
CurDAG->RemoveDeadNode (N.getNode ());
2307
- return ExtSrc;
2329
+ return Res ? Res : ExtSrc;
2308
2330
}
2309
2331
}
2310
2332
}
@@ -2589,8 +2611,18 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
2589
2611
if (AM.IndexReg .getNode () != nullptr || AM.Scale != 1 )
2590
2612
break ;
2591
2613
2592
- // Peek through mask: zext(and(shl(x,c1),c2))
2593
2614
SDValue Src = N.getOperand (0 );
2615
+
2616
+ // See if we can match a zext(addlike(x,c)).
2617
+ // TODO: Move more ZERO_EXTEND patterns into matchIndexRecursively.
2618
+ if (Src.getOpcode () == ISD::ADD || Src.getOpcode () == ISD::OR)
2619
+ if (SDValue Index = matchIndexRecursively (N, AM, Depth + 1 ))
2620
+ if (Index != N) {
2621
+ AM.IndexReg = Index;
2622
+ return false ;
2623
+ }
2624
+
2625
+ // Peek through mask: zext(and(shl(x,c1),c2))
2594
2626
APInt Mask = APInt::getAllOnes (Src.getScalarValueSizeInBits ());
2595
2627
if (Src.getOpcode () == ISD::AND && Src.hasOneUse ())
2596
2628
if (auto *MaskC = dyn_cast<ConstantSDNode>(Src.getOperand (1 ))) {
@@ -2613,7 +2645,8 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
2613
2645
// That makes it safe to widen to the destination type.
2614
2646
APInt HighZeros =
2615
2647
APInt::getHighBitsSet (ShlSrc.getValueSizeInBits (), ShAmtV);
2616
- if (!CurDAG->MaskedValueIsZero (ShlSrc, HighZeros & Mask))
2648
+ if (!Src->getFlags ().hasNoUnsignedWrap () &&
2649
+ !CurDAG->MaskedValueIsZero (ShlSrc, HighZeros & Mask))
2617
2650
break ;
2618
2651
2619
2652
// zext (shl nuw i8 %x, C1) to i32
0 commit comments