[llvm] [AArch64] Fold NEON splats into users by using SVE immediates (PR #165559)

Paul Walker via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 12 05:02:05 PDT 2026


================
@@ -597,6 +605,77 @@ static bool isIntImmediateEq(SDValue N, const uint64_t ImmExpected) {
 }
 #endif
 
+static APInt DecodeFMOVImm(SDValue N) {
+  unsigned RegWidth = N.getScalarValueSizeInBits();
+  assert(N->getOpcode() == AArch64ISD::FMOV);
+  assert(RegWidth == 32 || RegWidth == 64);
+  if (RegWidth == 32)
+    return APInt(RegWidth, (uint32_t)AArch64_AM::decodeAdvSIMDModImmType11(
+                               N.getConstantOperandVal(0)));
+
+  return APInt(RegWidth, AArch64_AM::decodeAdvSIMDModImmType12(
+                             N.getConstantOperandVal(0)));
+}
+
+// Decodes the integer splat value from a NEON splat operation.
+static std::optional<APInt> DecodeNEONSplat(SDValue N) {
+  assert(N.getValueType().isInteger() && "Only integers are supported");
+  unsigned SplatWidth = N.getScalarValueSizeInBits();
+  if (N->getOpcode() == AArch64ISD::NVCAST) {
+    SDValue Op = N->getOperand(0);
+    if (Op.getOpcode() != AArch64ISD::FMOV ||
+        Op.getScalarValueSizeInBits() != N.getScalarValueSizeInBits())
+      return std::nullopt;
+    return DecodeFMOVImm(Op);
+  }
+  if (N->getOpcode() == AArch64ISD::MOVI)
+    return APInt(SplatWidth, N.getConstantOperandVal(0));
+  if (N->getOpcode() == AArch64ISD::MOVIshift)
+    return APInt(SplatWidth, N.getConstantOperandVal(0)
+                                 << N.getConstantOperandVal(1));
+  if (N->getOpcode() == AArch64ISD::MVNIshift)
+    return ~APInt(SplatWidth, N.getConstantOperandVal(0)
+                                  << N.getConstantOperandVal(1));
+  if (N->getOpcode() == AArch64ISD::DUP) {
+    if (auto *Const = dyn_cast<ConstantSDNode>(N->getOperand(0)))
+      return Const->getAPIntValue();
+  }
----------------
paulwalker-arm wrote:

Unnecessary {}.

The DUP operand can be bigger than the element type so truncating to SplatWidth could yield more matches.

https://github.com/llvm/llvm-project/pull/165559


More information about the llvm-commits mailing list