forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clang][SME] Ignore flatten/clang::always_inline statements for calle…
…es with mismatched streaming attributes (llvm#116391) If `__attribute__((flatten))` is used on a function, or `[[clang::always_inline]]` on a statement, don't inline any callees with incompatible streaming attributes. Without this check, clang may produce incorrect code when these attributes are used in code with streaming functions. Note: The docs for flatten say it can be ignored when inlining is impossible: "causes calls within the attributed function to be inlined unless it is impossible to do so". Similarly, the (clang-only) `[[clang::always_inline]]` statement attribute is more relaxed than the GNU `__attribute__((always_inline))` (which says it should error it if it can't inline), saying only "If a statement is marked [[clang::always_inline]] and contains calls, the compiler attempts to inline those calls.". The docs also go on to show an example of where `[[clang::always_inline]]` has no effect.
- Loading branch information
Showing
4 changed files
with
172 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
clang/test/CodeGen/AArch64/sme-inline-callees-streaming-attrs.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -target-feature +sme %s -DUSE_FLATTEN -o - | FileCheck %s | ||
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -emit-llvm -target-feature +sme %s -DUSE_ALWAYS_INLINE_STMT -o - | FileCheck %s | ||
|
||
// REQUIRES: aarch64-registered-target | ||
|
||
extern void was_inlined(void); | ||
|
||
#if defined(USE_FLATTEN) | ||
#define FN_ATTR __attribute__((flatten)) | ||
#define STMT_ATTR | ||
#elif defined(USE_ALWAYS_INLINE_STMT) | ||
#define FN_ATTR | ||
#define STMT_ATTR [[clang::always_inline]] | ||
#else | ||
#error Expected USE_FLATTEN or USE_ALWAYS_INLINE_STMT to be defined. | ||
#endif | ||
|
||
void fn(void) { was_inlined(); } | ||
void fn_streaming_compatible(void) __arm_streaming_compatible { was_inlined(); } | ||
void fn_streaming(void) __arm_streaming { was_inlined(); } | ||
__arm_locally_streaming void fn_locally_streaming(void) { was_inlined(); } | ||
__arm_new("za") void fn_streaming_new_za(void) __arm_streaming { was_inlined(); } | ||
|
||
FN_ATTR | ||
void caller(void) { | ||
STMT_ATTR fn(); | ||
STMT_ATTR fn_streaming_compatible(); | ||
STMT_ATTR fn_streaming(); | ||
STMT_ATTR fn_locally_streaming(); | ||
STMT_ATTR fn_streaming_new_za(); | ||
} | ||
// CHECK-LABEL: void @caller() | ||
// CHECK-NEXT: entry: | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @fn_streaming | ||
// CHECK-NEXT: call void @fn_locally_streaming | ||
// CHECK-NEXT: call void @fn_streaming_new_za | ||
|
||
FN_ATTR void caller_streaming_compatible(void) __arm_streaming_compatible { | ||
STMT_ATTR fn(); | ||
STMT_ATTR fn_streaming_compatible(); | ||
STMT_ATTR fn_streaming(); | ||
STMT_ATTR fn_locally_streaming(); | ||
STMT_ATTR fn_streaming_new_za(); | ||
} | ||
// CHECK-LABEL: void @caller_streaming_compatible() | ||
// CHECK-NEXT: entry: | ||
// CHECK-NEXT: call void @fn | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @fn_streaming | ||
// CHECK-NEXT: call void @fn_locally_streaming | ||
// CHECK-NEXT: call void @fn_streaming_new_za | ||
|
||
FN_ATTR void caller_streaming(void) __arm_streaming { | ||
STMT_ATTR fn(); | ||
STMT_ATTR fn_streaming_compatible(); | ||
STMT_ATTR fn_streaming(); | ||
STMT_ATTR fn_locally_streaming(); | ||
STMT_ATTR fn_streaming_new_za(); | ||
} | ||
// CHECK-LABEL: void @caller_streaming() | ||
// CHECK-NEXT: entry: | ||
// CHECK-NEXT: call void @fn | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @fn_streaming_new_za | ||
|
||
FN_ATTR __arm_locally_streaming | ||
void caller_locally_streaming(void) { | ||
STMT_ATTR fn(); | ||
STMT_ATTR fn_streaming_compatible(); | ||
STMT_ATTR fn_streaming(); | ||
STMT_ATTR fn_locally_streaming(); | ||
STMT_ATTR fn_streaming_new_za(); | ||
} | ||
// CHECK-LABEL: void @caller_locally_streaming() | ||
// CHECK-NEXT: entry: | ||
// CHECK-NEXT: call void @fn | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @was_inlined | ||
// CHECK-NEXT: call void @fn_streaming_new_za |