[llvm] [AArch64] Don't inline streaming Fn if caller has no SVE (PR #150595)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 25 02:19:06 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-aarch64

Author: Sander de Smalen (sdesmalen-arm)

<details>
<summary>Changes</summary>

Without this change, the following test would fail to compile
with `-march=armv8-a+sme`:

```
  void func1(const svuint32_t *in, svuint32_t *out) {
    [&]() __arm_streaming { *out = *in; }();
  }
```

---
Full diff: https://github.com/llvm/llvm-project/pull/150595.diff


2 Files Affected:

- (modified) llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp (+9-3) 
- (modified) llvm/test/Transforms/Inline/AArch64/sme-pstatesm-attrs.ll (+22) 


``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
index 40f49dade6131..38711206a9ea1 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
@@ -280,6 +280,15 @@ bool AArch64TTIImpl::areInlineCompatible(const Function *Caller,
   if (CallAttrs.callee().isNewZA() || CallAttrs.callee().isNewZT0())
     return false;
 
+  const TargetMachine &TM = getTLI()->getTargetMachine();
+  const FeatureBitset &CallerBits =
+      TM.getSubtargetImpl(*Caller)->getFeatureBits();
+
+  // Cannot inline a streaming function into a non-streaming function,
+  // if the caller has no SVE.
+  if (CallAttrs.requiresSMChange() && !CallerBits.test(AArch64::FeatureSVE))
+    return false;
+
   if (CallAttrs.requiresLazySave() || CallAttrs.requiresSMChange() ||
       CallAttrs.requiresPreservingZT0() ||
       CallAttrs.requiresPreservingAllZAState()) {
@@ -287,9 +296,6 @@ bool AArch64TTIImpl::areInlineCompatible(const Function *Caller,
       return false;
   }
 
-  const TargetMachine &TM = getTLI()->getTargetMachine();
-  const FeatureBitset &CallerBits =
-      TM.getSubtargetImpl(*Caller)->getFeatureBits();
   const FeatureBitset &CalleeBits =
       TM.getSubtargetImpl(*Callee)->getFeatureBits();
   // Adjust the feature bitsets by inverting some of the bits. This is needed
diff --git a/llvm/test/Transforms/Inline/AArch64/sme-pstatesm-attrs.ll b/llvm/test/Transforms/Inline/AArch64/sme-pstatesm-attrs.ll
index 6cb16928ae6ca..ce323701cbe48 100644
--- a/llvm/test/Transforms/Inline/AArch64/sme-pstatesm-attrs.ll
+++ b/llvm/test/Transforms/Inline/AArch64/sme-pstatesm-attrs.ll
@@ -676,4 +676,26 @@ define void @streaming_caller_multiple_streaming_compatible_callees_inline() #0
   ret void
 }
 
+define void @nosve_streaming_function(ptr %ptr) "target-features"="+sme" "aarch64_pstate_sm_enabled" {
+; CHECK-LABEL: define void @nosve_streaming_function
+; CHECK-SAME: (ptr [[PTR:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT:    store <vscale x 4 x i32> zeroinitializer, ptr [[PTR]], align 16
+; CHECK-NEXT:    ret void
+;
+  store <vscale x 4 x i32> zeroinitializer, ptr %ptr
+  ret void
+}
+
+; Don't allow inlining a streaming function into a non-streaming function
+; if the non-streaming function has no SVE.
+define void @nosve_non_streaming_caller_streaming_callee_dont_inline(ptr %ptr) "target-features"="+sme"  {
+; CHECK-LABEL: define void @nosve_non_streaming_caller_streaming_callee_dont_inline
+; CHECK-SAME: (ptr [[PTR:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    call void @nosve_streaming_function(ptr [[PTR]])
+; CHECK-NEXT:    ret void
+;
+  call void @nosve_streaming_function(ptr %ptr)
+  ret void
+}
+
 attributes #0 = { "target-features"="+sve,+sme" }

``````````

</details>


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


More information about the llvm-commits mailing list