Skip to content

Commit 2984e35

Browse files
committed
[X86] matchIndexRecursively - fold zext(addlike(shl_nuw(x,c1),c2) patterns into LEA
Pulled out of D155472 - handle zeroextended scaled address indices
1 parent 2908142 commit 2984e35

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

llvm/lib/Target/X86/X86ISelDAGToDAG.cpp

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,6 +2296,28 @@ SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
22962296
uint64_t Offset = (uint64_t)AddVal->getZExtValue();
22972297
if (!foldOffsetIntoAddress(Offset * AM.Scale, AM)) {
22982298
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+
}
22992321
SDValue ExtSrc = CurDAG->getNode(Opc, DL, VT, AddSrc);
23002322
SDValue ExtVal = CurDAG->getConstant(Offset, DL, VT);
23012323
SDValue ExtAdd = CurDAG->getNode(SrcOpc, DL, VT, ExtSrc, ExtVal);
@@ -2304,7 +2326,7 @@ SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
23042326
insertDAGNode(*CurDAG, N, ExtAdd);
23052327
CurDAG->ReplaceAllUsesWith(N, ExtAdd);
23062328
CurDAG->RemoveDeadNode(N.getNode());
2307-
return ExtSrc;
2329+
return Res ? Res : ExtSrc;
23082330
}
23092331
}
23102332
}
@@ -2589,8 +2611,18 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
25892611
if (AM.IndexReg.getNode() != nullptr || AM.Scale != 1)
25902612
break;
25912613

2592-
// Peek through mask: zext(and(shl(x,c1),c2))
25932614
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))
25942626
APInt Mask = APInt::getAllOnes(Src.getScalarValueSizeInBits());
25952627
if (Src.getOpcode() == ISD::AND && Src.hasOneUse())
25962628
if (auto *MaskC = dyn_cast<ConstantSDNode>(Src.getOperand(1))) {
@@ -2613,7 +2645,8 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
26132645
// That makes it safe to widen to the destination type.
26142646
APInt HighZeros =
26152647
APInt::getHighBitsSet(ShlSrc.getValueSizeInBits(), ShAmtV);
2616-
if (!CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
2648+
if (!Src->getFlags().hasNoUnsignedWrap() &&
2649+
!CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
26172650
break;
26182651

26192652
// zext (shl nuw i8 %x, C1) to i32

llvm/test/CodeGen/X86/addr-mode-matcher-3.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ define i32 @mask_offset_scale_i32_i64(ptr %base, i32 %i) {
1515
; X64: # %bb.0:
1616
; X64-NEXT: # kill: def $esi killed $esi def $rsi
1717
; X64-NEXT: andl $65280, %esi # imm = 0xFF00
18-
; X64-NEXT: addl %esi, %esi
19-
; X64-NEXT: movl 48(%rdi,%rsi,4), %eax
18+
; X64-NEXT: movl 48(%rdi,%rsi,8), %eax
2019
; X64-NEXT: retq
2120
%mask = and i32 %i, 65280
2221
%offset = or i32 %mask, 6

0 commit comments

Comments
 (0)