[llvm] [AArch64] Fold vector shifts guarded against oversized amounts into USHL (PR #207628)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 06:26:31 PDT 2026
================
@@ -29138,6 +29138,82 @@ static SDValue performVselectPowCombine(SDNode *N,
return DAG.getNode(ISD::VSELECT, DL, VT, Cond, TrueVal, NewPow);
}
+// A vselect can zero the lanes with an out-of-range shift amount with either:
+// vselect(setcc_ult(amt, EltSize), val, zeros)
+// vselect(setcc_uge(amt, EltSize), zeros, val)
+// Returns val for whichever polarity is present and sets RequiredCC to the
+// condition code the setcc has to be using.
+static SDValue matchZeroSelectArm(SDValue TVal, SDValue FVal,
+ ISD::CondCode &RequiredCC) {
+ if (ISD::isConstantSplatVectorAllZeros(FVal.getNode())) {
+ RequiredCC = ISD::SETULT;
+ return TVal;
+ }
+ if (ISD::isConstantSplatVectorAllZeros(TVal.getNode())) {
+ RequiredCC = ISD::SETUGE;
+ return FVal;
+ }
+ return SDValue();
+}
+
+// ushl already produces zero for shift amounts of EltSize or more, so a
+// select zeroing those lanes is redundant. However, ushl reads each lane's
+// shift amount as a signed value from its low byte and would misread amounts
+// above 127, so the amounts must either be provably at most 127 or get
+// clamped to EltSize with umin.
+static SDValue foldMaskedShiftToUSHL(SelectionDAG &DAG,
+ const AArch64Subtarget *Subtarget,
+ SDNode *N, SDValue X, SDValue Amt,
+ SDValue Cond, ISD::CondCode RequiredCC,
+ bool IsSRL) {
+ using namespace llvm::SDPatternMatch;
+ EVT VT = N->getValueType(0);
+ if (!Subtarget->isNeonAvailable() || !VT.isFixedLengthVector() ||
+ !VT.isInteger() || !DAG.getTargetLoweringInfo().isTypeLegal(VT))
----------------
davemgreen wrote:
This isTypeLegal needs to be the type legal for an aarch64_neon_ushl, in case other types are also legal.
https://github.com/llvm/llvm-project/pull/207628
More information about the llvm-commits
mailing list