[llvm] [RISCV] Fold vp.reverse of vp.load through binary ops (PR #205529)
Ryan Buchner via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 25 09:03:17 PDT 2026
================
@@ -19649,61 +19649,85 @@ static SDValue performReverseEVLCombine(SDNode *N, SelectionDAG &DAG,
//
// splice.right(reverse(vp.load(ADDR, REVMASK, EVL)), poison, EVL)
// -> vp.strided.load(ADDR, -1, MASK, EVL)
-
- // Check if its first operand is a vp.load.
+ //
+ // vp.reverse(binop(vp.load(ADDR, REVMASK, EVL), splat), EVL)
+ // -> binop(vp.strided.load(ADDR, -1, MASK, EVL), splat)
using namespace SDPatternMatch;
SDValue Op, EVL;
- if (!sd_match(N,
- m_ReverseEVL(m_OneUse(m_Value(Op, m_SpecificOpc(ISD::VP_LOAD))),
- m_Value(EVL))))
+ if (!sd_match(N, m_ReverseEVL(m_Value(Op), m_Value(EVL))))
return SDValue();
- auto *VPLoad = cast<VPLoadSDNode>(Op);
-
- EVT LoadVT = VPLoad->getValueType(0);
- // We do not have a strided_load version for masks, and the evl of vp.reverse
- // and vp.load should always be the same.
- if (!LoadVT.getVectorElementType().isByteSized() ||
- EVL != VPLoad->getVectorLength())
- return SDValue();
-
- SDValue LoadMask = VPLoad->getMask();
- // If Mask is all ones, then load is unmasked and can be reversed.
- if (!isOneOrOneSplat(LoadMask)) {
- // If the mask is not all ones, we can reverse the load if the mask was also
- // reversed by a vp.reverse with the same EVL.
- SDValue OrigMask;
- if (!sd_match(LoadMask, m_ReverseEVL(m_Value(OrigMask), m_Specific(EVL))))
+ // Check that all leaves are splats or vp_loads, and collect the latter.
+ SmallVector<SDValue> Worklist = {Op};
+ SmallVector<VPLoadSDNode *> VPLoads;
+ while (!Worklist.empty()) {
+ SDValue X = Worklist.pop_back_val();
+ if (!X->hasOneUse())
+ return SDValue();
+ if (auto *VPLoad = dyn_cast<VPLoadSDNode>(X))
+ VPLoads.push_back(VPLoad);
+ else if (DAG.isSplatValue(X))
+ continue;
+ else if (DAG.getTargetLoweringInfo().isBinOp(X.getOpcode()))
+ append_range(Worklist, X->op_values());
+ else
return SDValue();
- LoadMask = OrigMask;
}
- // Base = LoadAddr + (NumElem - 1) * ElemWidthByte
- SDLoc DL(N);
- MVT XLenVT = Subtarget.getXLenVT();
- SDValue NumElem = VPLoad->getVectorLength();
- uint64_t ElemWidthByte = VPLoad->getValueType(0).getScalarSizeInBits() / 8;
+ SmallVector<SDValue> LoadMasks;
+ for (auto *VPLoad : VPLoads) {
----------------
bababuck wrote:
I think SLP just uses shufflevectors rather than vp.reverse. It will make the strided load(-1) optimization, but I believe it's heuristic is to first minimize the number of shuffles, so this pass might improve SLP vectors (assuming the shuffles get converted to vp.reverses).
https://github.com/llvm/llvm-project/pull/205529
More information about the llvm-commits
mailing list