[llvm] 2984e35 - [X86] matchIndexRecursively - fold zext(addlike(shl_nuw(x,c1),c2) patterns into LEA
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 2 04:41:24 PDT 2023
Author: Simon Pilgrim
Date: 2023-10-02T12:38:25+01:00
New Revision: 2984e3529b559c90e37408d1b87628fae7bf11de
URL: https://github.com/llvm/llvm-project/commit/2984e3529b559c90e37408d1b87628fae7bf11de
DIFF: https://github.com/llvm/llvm-project/commit/2984e3529b559c90e37408d1b87628fae7bf11de.diff
LOG: [X86] matchIndexRecursively - fold zext(addlike(shl_nuw(x,c1),c2) patterns into LEA
Pulled out of D155472 - handle zeroextended scaled address indices
Added:
Modified:
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
llvm/test/CodeGen/X86/addr-mode-matcher-3.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index f4cf9ddfe829532..694a2df195c0922 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -2296,6 +2296,28 @@ SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
uint64_t Offset = (uint64_t)AddVal->getZExtValue();
if (!foldOffsetIntoAddress(Offset * AM.Scale, AM)) {
SDLoc DL(N);
+ SDValue Res;
+ // If we're also scaling, see if we can use that as well.
+ if (AddSrc.getOpcode() == ISD::SHL &&
+ isa<ConstantSDNode>(AddSrc.getOperand(1))) {
+ SDValue ShVal = AddSrc.getOperand(0);
+ uint64_t ShAmt = AddSrc.getConstantOperandVal(1);
+ APInt HiBits =
+ APInt::getHighBitsSet(AddSrc.getScalarValueSizeInBits(), ShAmt);
+ uint64_t ScaleAmt = 1ULL << ShAmt;
+ if ((AM.Scale * ScaleAmt) <= 8 &&
+ (AddSrc->getFlags().hasNoUnsignedWrap() ||
+ CurDAG->MaskedValueIsZero(ShVal, HiBits))) {
+ AM.Scale *= ScaleAmt;
+ SDValue ExtShVal = CurDAG->getNode(Opc, DL, VT, ShVal);
+ SDValue ExtShift = CurDAG->getNode(ISD::SHL, DL, VT, ExtShVal,
+ AddSrc.getOperand(1));
+ insertDAGNode(*CurDAG, N, ExtShVal);
+ insertDAGNode(*CurDAG, N, ExtShift);
+ AddSrc = ExtShift;
+ Res = ExtShVal;
+ }
+ }
SDValue ExtSrc = CurDAG->getNode(Opc, DL, VT, AddSrc);
SDValue ExtVal = CurDAG->getConstant(Offset, DL, VT);
SDValue ExtAdd = CurDAG->getNode(SrcOpc, DL, VT, ExtSrc, ExtVal);
@@ -2304,7 +2326,7 @@ SDValue X86DAGToDAGISel::matchIndexRecursively(SDValue N,
insertDAGNode(*CurDAG, N, ExtAdd);
CurDAG->ReplaceAllUsesWith(N, ExtAdd);
CurDAG->RemoveDeadNode(N.getNode());
- return ExtSrc;
+ return Res ? Res : ExtSrc;
}
}
}
@@ -2589,8 +2611,18 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
if (AM.IndexReg.getNode() != nullptr || AM.Scale != 1)
break;
- // Peek through mask: zext(and(shl(x,c1),c2))
SDValue Src = N.getOperand(0);
+
+ // See if we can match a zext(addlike(x,c)).
+ // TODO: Move more ZERO_EXTEND patterns into matchIndexRecursively.
+ if (Src.getOpcode() == ISD::ADD || Src.getOpcode() == ISD::OR)
+ if (SDValue Index = matchIndexRecursively(N, AM, Depth + 1))
+ if (Index != N) {
+ AM.IndexReg = Index;
+ return false;
+ }
+
+ // Peek through mask: zext(and(shl(x,c1),c2))
APInt Mask = APInt::getAllOnes(Src.getScalarValueSizeInBits());
if (Src.getOpcode() == ISD::AND && Src.hasOneUse())
if (auto *MaskC = dyn_cast<ConstantSDNode>(Src.getOperand(1))) {
@@ -2613,7 +2645,8 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
// That makes it safe to widen to the destination type.
APInt HighZeros =
APInt::getHighBitsSet(ShlSrc.getValueSizeInBits(), ShAmtV);
- if (!CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
+ if (!Src->getFlags().hasNoUnsignedWrap() &&
+ !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
break;
// zext (shl nuw i8 %x, C1) to i32
diff --git a/llvm/test/CodeGen/X86/addr-mode-matcher-3.ll b/llvm/test/CodeGen/X86/addr-mode-matcher-3.ll
index 0f03276389571e3..37d76ffb646f08a 100644
--- a/llvm/test/CodeGen/X86/addr-mode-matcher-3.ll
+++ b/llvm/test/CodeGen/X86/addr-mode-matcher-3.ll
@@ -15,8 +15,7 @@ define i32 @mask_offset_scale_i32_i64(ptr %base, i32 %i) {
; X64: # %bb.0:
; X64-NEXT: # kill: def $esi killed $esi def $rsi
; X64-NEXT: andl $65280, %esi # imm = 0xFF00
-; X64-NEXT: addl %esi, %esi
-; X64-NEXT: movl 48(%rdi,%rsi,4), %eax
+; X64-NEXT: movl 48(%rdi,%rsi,8), %eax
; X64-NEXT: retq
%mask = and i32 %i, 65280
%offset = or i32 %mask, 6
More information about the llvm-commits
mailing list