[llvm] [X86] matchAddressRecursively - move ZERO_EXTEND patterns into matchIndexRecursively (PR #85081)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 24 23:17:28 PDT 2024
================
@@ -2670,97 +2761,13 @@ bool X86DAGToDAGISel::matchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
break;
}
case ISD::ZERO_EXTEND: {
- // Try to widen a zexted shift left to the same size as its use, so we can
- // match the shift as a scale factor.
- if (AM.IndexReg.getNode() != nullptr || AM.Scale != 1)
+ if (AM.IndexReg.getNode() != nullptr)
break;
-
- 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))) {
- Mask = MaskC->getAPIntValue();
- Src = Src.getOperand(0);
- }
-
- if (Src.getOpcode() == ISD::SHL && Src.hasOneUse()) {
- // Give up if the shift is not a valid scale factor [1,2,3].
- SDValue ShlSrc = Src.getOperand(0);
- SDValue ShlAmt = Src.getOperand(1);
- auto *ShAmtC = dyn_cast<ConstantSDNode>(ShlAmt);
- if (!ShAmtC)
- break;
- unsigned ShAmtV = ShAmtC->getZExtValue();
- if (ShAmtV > 3)
- break;
-
- // The narrow shift must only shift out zero bits (it must be 'nuw').
- // That makes it safe to widen to the destination type.
- APInt HighZeros =
- APInt::getHighBitsSet(ShlSrc.getValueSizeInBits(), ShAmtV);
- if (!Src->getFlags().hasNoUnsignedWrap() &&
- !CurDAG->MaskedValueIsZero(ShlSrc, HighZeros & Mask))
- break;
-
- // zext (shl nuw i8 %x, C1) to i32
- // --> shl (zext i8 %x to i32), (zext C1)
- // zext (and (shl nuw i8 %x, C1), C2) to i32
- // --> shl (zext i8 (and %x, C2 >> C1) to i32), (zext C1)
- MVT SrcVT = ShlSrc.getSimpleValueType();
- MVT VT = N.getSimpleValueType();
- SDLoc DL(N);
-
- SDValue Res = ShlSrc;
- if (!Mask.isAllOnes()) {
- Res = CurDAG->getConstant(Mask.lshr(ShAmtV), DL, SrcVT);
- insertDAGNode(*CurDAG, N, Res);
- Res = CurDAG->getNode(ISD::AND, DL, SrcVT, ShlSrc, Res);
- insertDAGNode(*CurDAG, N, Res);
- }
- SDValue Zext = CurDAG->getNode(ISD::ZERO_EXTEND, DL, VT, Res);
- insertDAGNode(*CurDAG, N, Zext);
- SDValue NewShl = CurDAG->getNode(ISD::SHL, DL, VT, Zext, ShlAmt);
- insertDAGNode(*CurDAG, N, NewShl);
- CurDAG->ReplaceAllUsesWith(N, NewShl);
- CurDAG->RemoveDeadNode(N.getNode());
-
- // Convert the shift to scale factor.
- AM.Scale = 1 << ShAmtV;
- // If matchIndexRecursively is not called here,
- // Zext may be replaced by other nodes but later used to call a builder
- // method
- AM.IndexReg = matchIndexRecursively(Zext, AM, Depth + 1);
+ // All relevant operations are moved into matchIndexRecursively.
+ if (auto Index = matchIndexRecursively(N, AM, Depth + 1)) {
----------------
RicoAfoat wrote:
https://github.com/llvm/llvm-project/pull/85081#discussion_r1578811340
@topperc @RKSimon
For most of the time, `AM.IndexReg` will be set to the return value of `matchIndexRecursively` whenever this function is called except here. I'm wondering if a bool is nice for the return type, and we directly change the value of `AM.IndexReg` inside `matchIndexRecursively`(We have already done that to `AM.Scale`).
In addition, some functions (`foldMaskAndShiftToExtract`,`foldMaskAndShiftToScale`, `foldMaskedShiftToBEXTR`) which directly modify `AM.IndexReg` and are previously called in `matchAddressRecursively` are moved to `matchIndexRecursively`. It will be a little strange to return the value... Otherwise we need to adjust them as well.
Should we change it to a bool ?
https://github.com/llvm/llvm-project/pull/85081
More information about the llvm-commits
mailing list