[llvm] [AArch64] Lower masked.expandload intrinsic using SVE2p2/SME2p2 EXPAND (PR #190999)

Kerry McLaughlin via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 10 09:12:41 PDT 2026


================
@@ -31763,12 +31676,42 @@ SDValue AArch64TargetLowering::LowerFixedLengthVectorMLoadToSVE(
       IsPassThruZeroOrUndef = true;
   }
 
-  SDValue NewLoad = DAG.getMaskedLoad(
-      ContainerVT, DL, Load->getChain(), Load->getBasePtr(), Load->getOffset(),
-      Mask, PassThru, Load->getMemoryVT(), Load->getMemOperand(),
-      Load->getAddressingMode(), Load->getExtensionType());
+  if (!Load->isExpandingLoad()) {
+    NewLoad =
+        DAG.getMaskedLoad(ContainerVT, DL, Load->getChain(), Load->getBasePtr(),
+                          Load->getOffset(), Mask, PassThru,
+                          Load->getMemoryVT(), Load->getMemOperand(),
+                          Load->getAddressingMode(), Load->getExtensionType());
+    Result = NewLoad;
+  } else {
+    // Fixed-length masked.expandload intrinsics should have been scalarised
+    // if the required features are not available to use EXPAND.
+    assert(
+        (Subtarget->isSVEAvailable() && Subtarget->hasSVE2p2()) ||
+        (Subtarget->isSVEorStreamingSVEAvailable() && Subtarget->hasSME2p2()) &&
+            "Expected SVE2p2 or SME2p2");
+
+    SDValue CntActive = DAG.getNode(
+        ISD::INTRINSIC_WO_CHAIN, DL, MVT::i64,
+        DAG.getTargetConstant(Intrinsic::aarch64_sve_cntp, DL, MVT::i64), Mask,
+        Mask);
+
+    SDValue ActiveMask =
+        DAG.getNode(ISD::GET_ACTIVE_LANE_MASK, DL, Mask->getValueType(0),
+                    DAG.getConstant(0, DL, MVT::i64), CntActive);
+
+    NewLoad =
+        DAG.getMaskedLoad(ContainerVT, DL, Load->getChain(), Load->getBasePtr(),
+                          Load->getOffset(), ActiveMask, PassThru,
+                          Load->getMemoryVT(), Load->getMemOperand(),
+                          Load->getAddressingMode(), Load->getExtensionType());
+
+    Result = DAG.getNode(
+        ISD::INTRINSIC_WO_CHAIN, DL, ContainerVT,
+        DAG.getTargetConstant(Intrinsic::aarch64_sve_expand, DL, MVT::i64),
+        Mask, NewLoad);
+  }
----------------
kmclaughlin-arm wrote:

This is happening a little further down, i.e.
```
  if (!IsPassThruZeroOrUndef) {
    SDValue OldPassThru =
        convertToScalableVector(DAG, ContainerVT, Load->getPassThru());
    Result = DAG.getSelect(DL, ContainerVT, Mask, Result, OldPassThru);
  }
```

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


More information about the llvm-commits mailing list