Skip to content

Commit 76ce464

Browse files
[AArch64] Dont inline streaming fn into non-streaming caller (#150595)
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; }(); } ``` But in general, it's probably better never to inline streaming functions into non-streaming functions, because they will have been marked as 'streaming' for a reason by the user.
1 parent 451912a commit 76ce464

File tree

3 files changed

+131
-82
lines changed

3 files changed

+131
-82
lines changed

llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,13 @@ bool AArch64TTIImpl::areInlineCompatible(const Function *Caller,
270270
const Function *Callee) const {
271271
SMECallAttrs CallAttrs(*Caller, *Callee);
272272

273+
// Never inline a function explicitly marked as being streaming,
274+
// into a non-streaming function. Assume it was marked as streaming
275+
// for a reason.
276+
if (CallAttrs.caller().hasNonStreamingInterfaceAndBody() &&
277+
CallAttrs.callee().hasStreamingInterfaceOrBody())
278+
return false;
279+
273280
// When inlining, we should consider the body of the function, not the
274281
// interface.
275282
if (CallAttrs.callee().hasStreamingBody()) {

llvm/test/Transforms/Inline/AArch64/sme-pstatesm-attrs-low-threshold.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ target triple = "aarch64"
77

88
declare void @streaming_compatible_f() #0 "aarch64_pstate_sm_compatible"
99

10-
; Function @streaming_callee doesn't contain any operations that may use ZA
10+
; Function @non_streaming_callee doesn't contain any operations that may use ZA
1111
; state and therefore can be legally inlined into a normal function.
12-
define void @streaming_callee() #0 "aarch64_pstate_sm_enabled" {
13-
; CHECK-LABEL: define void @streaming_callee
12+
define void @non_streaming_callee() #0 {
13+
; CHECK-LABEL: define void @non_streaming_callee
1414
; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
1515
; CHECK-NEXT: call void @streaming_compatible_f()
1616
; CHECK-NEXT: call void @streaming_compatible_f()
@@ -21,26 +21,26 @@ define void @streaming_callee() #0 "aarch64_pstate_sm_enabled" {
2121
ret void
2222
}
2323

24-
; Inline call to @streaming_callee to remove a streaming mode change.
25-
define void @non_streaming_caller_inline() #0 {
26-
; CHECK-LABEL: define void @non_streaming_caller_inline
24+
; Inline call to @non_streaming_callee to remove a streaming mode change.
25+
define void @streaming_caller_inline() #0 "aarch64_pstate_sm_enabled" {
26+
; CHECK-LABEL: define void @streaming_caller_inline
2727
; CHECK-SAME: () #[[ATTR2:[0-9]+]] {
2828
; CHECK-NEXT: call void @streaming_compatible_f()
2929
; CHECK-NEXT: call void @streaming_compatible_f()
3030
; CHECK-NEXT: ret void
3131
;
32-
call void @streaming_callee()
32+
call void @non_streaming_callee()
3333
ret void
3434
}
3535

36-
; Don't inline call to @streaming_callee when the inline-threshold is set to 1, because it does not eliminate a streaming-mode change.
37-
define void @streaming_caller_dont_inline() #0 "aarch64_pstate_sm_enabled" {
38-
; CHECK-LABEL: define void @streaming_caller_dont_inline
36+
; Don't inline call to @non_streaming_callee when the inline-threshold is set to 1, because it does not eliminate a streaming-mode change.
37+
define void @non_streaming_caller_dont_inline() #0 {
38+
; CHECK-LABEL: define void @non_streaming_caller_dont_inline
3939
; CHECK-SAME: () #[[ATTR1]] {
40-
; CHECK-NEXT: call void @streaming_callee()
40+
; CHECK-NEXT: call void @non_streaming_callee()
4141
; CHECK-NEXT: ret void
4242
;
43-
call void @streaming_callee()
43+
call void @non_streaming_callee()
4444
ret void
4545
}
4646

0 commit comments

Comments
 (0)