Skip to content

Commit 5430f73

Browse files
[Clang] Demote always_inline error to warning for mismatching SME attrs (#100740)
PR #77936 introduced a diagnostic to avoid calls being inlined into functions with a different streaming mode, because inlining those functions may result in different runtime behaviour. This was necessary because LLVM doesn't check whether inlining is possible and thus blindly inlines the function without checking feasibility. In practice however, this introduces an artificial restriction that the user may not be able to work around. Calling an `always_inline` function from some header file that is out of the control of the user would result in an error that the user cannot remedy. Therefore, this patch demotes the error into a warning (for calls from streaming[-compatible] -> non-streaming), but the proper fix would be to fix the AlwaysInliner in LLVM to avoid inlining when it has analyzed the callee and has determined that inlining is not possible. Calling an always_inline function for calls from non-streaming -> streaming will remain an error, because there is little pre-existing code for SME, so it is expected that the header file can be modified by the user (e.g. by using `__arm_streaming_compatible` if the code is claimed to be compatible).
1 parent 3a2ef3a commit 5430f73

File tree

3 files changed

+10
-5
lines changed

3 files changed

+10
-5
lines changed

clang/include/clang/Basic/DiagnosticFrontendKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ def err_function_needs_feature : Error<
288288
let CategoryName = "Codegen ABI Check" in {
289289
def err_function_always_inline_attribute_mismatch : Error<
290290
"always_inline function %1 and its caller %0 have mismatching %2 attributes">;
291+
def warn_function_always_inline_attribute_mismatch : Warning<
292+
"always_inline function %1 and its caller %0 have mismatching %2 attributes, "
293+
"inlining may change runtime behaviour">, InGroup<AArch64SMEAttributes>;
291294
def err_function_always_inline_new_za : Error<
292295
"always_inline function %0 has new za state">;
293296

clang/lib/CodeGen/Targets/AArch64.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -883,8 +883,10 @@ void AArch64TargetCodeGenInfo::checkFunctionCallABIStreaming(
883883

884884
if (!CalleeIsStreamingCompatible &&
885885
(CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible))
886-
CGM.getDiags().Report(CallLoc,
887-
diag::err_function_always_inline_attribute_mismatch)
886+
CGM.getDiags().Report(
887+
CallLoc, CalleeIsStreaming
888+
? diag::err_function_always_inline_attribute_mismatch
889+
: diag::warn_function_always_inline_attribute_mismatch)
888890
<< Caller->getDeclName() << Callee->getDeclName() << "streaming";
889891
if (auto *NewAttr = Callee->getAttr<ArmNewAttr>())
890892
if (NewAttr->isNewZA())

clang/test/CodeGen/aarch64-sme-inline-streaming-attrs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void caller(void) {
2020

2121
#ifdef TEST_COMPATIBLE
2222
void caller_compatible(void) __arm_streaming_compatible {
23-
inlined_fn(); // expected-error {{always_inline function 'inlined_fn' and its caller 'caller_compatible' have mismatching streaming attributes}}
23+
inlined_fn(); // expected-warning {{always_inline function 'inlined_fn' and its caller 'caller_compatible' have mismatching streaming attributes, inlining may change runtime behaviour}}
2424
inlined_fn_streaming_compatible();
2525
inlined_fn_streaming(); // expected-error {{always_inline function 'inlined_fn_streaming' and its caller 'caller_compatible' have mismatching streaming attributes}}
2626
inlined_fn_local(); // expected-error {{always_inline function 'inlined_fn_local' and its caller 'caller_compatible' have mismatching streaming attributes}}
@@ -29,7 +29,7 @@ void caller_compatible(void) __arm_streaming_compatible {
2929

3030
#ifdef TEST_STREAMING
3131
void caller_streaming(void) __arm_streaming {
32-
inlined_fn(); // expected-error {{always_inline function 'inlined_fn' and its caller 'caller_streaming' have mismatching streaming attributes}}
32+
inlined_fn(); // expected-warning {{always_inline function 'inlined_fn' and its caller 'caller_streaming' have mismatching streaming attributes, inlining may change runtime behaviour}}
3333
inlined_fn_streaming_compatible();
3434
inlined_fn_streaming();
3535
inlined_fn_local();
@@ -39,7 +39,7 @@ void caller_streaming(void) __arm_streaming {
3939
#ifdef TEST_LOCALLY
4040
__arm_locally_streaming
4141
void caller_local(void) {
42-
inlined_fn(); // expected-error {{always_inline function 'inlined_fn' and its caller 'caller_local' have mismatching streaming attributes}}
42+
inlined_fn(); // expected-warning {{always_inline function 'inlined_fn' and its caller 'caller_local' have mismatching streaming attributes, inlining may change runtime behaviour}}
4343
inlined_fn_streaming_compatible();
4444
inlined_fn_streaming();
4545
inlined_fn_local();

0 commit comments

Comments
 (0)