[llvm] [LLVM][CodeGen][SVE] Lower to multivector stores (PR #207397)

Benjamin Maxwell via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 05:13:08 PDT 2026


================
@@ -7734,6 +7736,150 @@ static SDValue LowerNTStore(StoreSDNode *StoreNode, EVT VT, EVT MemVT,
   return SDValue();
 }
 
+struct SVEMultiVectorInfo {
+  MVT RegVT;
+  unsigned NumVecs;
+  Intrinsic::ID LoadIntID;
+  Intrinsic::ID StoreIntID;
+  Intrinsic::ID PTrueIntID;
+};
+
+static std::optional<SVEMultiVectorInfo> getSVEMultiVectorInfo(MVT VT) {
+  SVEMultiVectorInfo Info;
+
+  switch (VT.SimpleTy) {
+  default:
+    return std::nullopt;
+
+  case MVT::nxv32i8:
+  case MVT::nxv16i16:
+  case MVT::nxv8i32:
+  case MVT::nxv4i64:
+  case MVT::nxv16f16:
+  case MVT::nxv8f32:
+  case MVT::nxv4f64:
+  case MVT::nxv16bf16:
+    Info.LoadIntID = Intrinsic::aarch64_sve_ld1_pn_x2;
+    Info.StoreIntID = Intrinsic::aarch64_sve_st1_pn_x2;
+    Info.NumVecs = 2;
+    Info.RegVT = VT.getHalfNumVectorElementsVT();
+    break;
+  case MVT::nxv64i8:
+  case MVT::nxv32i16:
+  case MVT::nxv16i32:
+  case MVT::nxv8i64:
+  case MVT::nxv32f16:
+  case MVT::nxv16f32:
+  case MVT::nxv8f64:
+  case MVT::nxv32bf16:
+    Info.LoadIntID = Intrinsic::aarch64_sve_ld1_pn_x4;
+    Info.StoreIntID = Intrinsic::aarch64_sve_st1_pn_x4;
+    Info.NumVecs = 4;
+    Info.RegVT = VT.getHalfNumVectorElementsVT().getHalfNumVectorElementsVT();
+    break;
+  }
+
+  switch (VT.getScalarSizeInBits()) {
+  default:
+    llvm_unreachable("covered by previous switch");
+  case 8:
+    Info.PTrueIntID = Intrinsic::aarch64_sve_ptrue_c8;
+    break;
+  case 16:
+    Info.PTrueIntID = Intrinsic::aarch64_sve_ptrue_c16;
+    break;
+  case 32:
+    Info.PTrueIntID = Intrinsic::aarch64_sve_ptrue_c32;
+    break;
+  case 64:
+    Info.PTrueIntID = Intrinsic::aarch64_sve_ptrue_c64;
+    break;
+  }
+
+  return Info;
+}
+
+static bool isValidSVEMultiVectorOp(const LSBaseSDNode *LSNode, EVT VT) {
+  return LSNode->isSimple() && LSNode->isUnindexed() &&
+         LSNode->getOffset().isUndef() && VT.isScalableVector() &&
+         VT.isSimple() && VT == LSNode->getMemoryVT();
+}
+
+// Lower scalable vectors that are 2/4 times the width of a legal SVE type to
+// multi-vector operations.
+static SDValue tryLowerMultiVectorStore(StoreSDNode *StoreNode,
+                                        SelectionDAG &DAG) {
+  SDValue Value = StoreNode->getValue();
+  EVT VT = Value.getValueType();
+
+  if (!isValidSVEMultiVectorOp(StoreNode, VT))
+    return SDValue();
+
----------------
MacDue wrote:

I think we can just return the chain (with remove the store), if the value being stored is `undef`. This should avoid the regressions in `sve-vector-interleave.ll` 
```suggestion

  if (Value->isUndef())
    return StoreNode->getChain();
    
```

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


More information about the llvm-commits mailing list