[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
https://github.com/SamTebbs33 edited https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Sam Tebbs (SamTebbs33) Changes This patch adds an error that is emitted when a streaming function is marked as always_inline and is called from a non-streaming function. --- Full diff: https://github.com/llvm/llvm-project/pull/77936.diff 7 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+2) - (modified) clang/include/clang/Sema/Sema.h (+9) - (modified) clang/lib/CodeGen/CMakeLists.txt (+1) - (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+20) - (modified) clang/lib/Sema/SemaChecking.cpp (+10-17) - (added) clang/test/CodeGen/aarch64-sme-func-attrs-inline-locally-streaming.c (+12) - (added) clang/test/CodeGen/aarch64-sme-func-attrs-inline-streaming.c (+12) ``diff diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 568000106a84dc..dbd92b600a936e 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -279,6 +279,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_function_alwaysinline_attribute_mismatch : Error< + "always_inline function %1 and its caller %0 have mismatched %2 attributes">; def warn_avx_calling_convention : Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' " diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4c464a1ae4c67f..0fed60103c9a2c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13803,8 +13803,17 @@ class Sema final { FormatArgumentPassingKind ArgPassingKind; }; +enum ArmStreamingType { + ArmNonStreaming, + ArmStreaming, + ArmStreamingCompatible, + ArmStreamingOrSVE2p1 +}; + + static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI); + static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 52216d93a302bb..03a6f2f1d7a9d2 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -151,4 +151,5 @@ add_clang_library(clangCodeGen clangFrontend clangLex clangSerialization + clangSema ) diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 7102d190fe008b..ea3d5a97605f1c 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -8,6 +8,8 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" +#include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Sema/Sema.h" using namespace clang; using namespace clang::CodeGen; @@ -153,6 +155,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, +const FunctionDecl *Caller, +const FunctionDecl *Callee, +const CallArgList &Args) const override; }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { @@ -812,6 +819,19 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { +if (!Callee->hasAttr()) + return; + +auto CalleeIsStreaming = Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; +auto CallerIsStreaming = Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + +if (CalleeIsStreaming && !CallerIsStreaming) +CGM.getDiags().Report(CallLoc, diag::err_function_alwaysinline_attribute_mismatch) << Caller->getDeclName() << Callee->getDeclName() << "streaming"; +} + std::unique_ptr CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind) { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 74f8f626fb1637..160637dde448e4 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2998,13 +2998,6 @@ static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, llvm_unreachable("Invalid NeonTypeFlag!"); } -enum ArmStreamingType { - ArmNonStreaming, - ArmStreaming, - ArmStreamingCompatible, - ArmStreamingOrSVE2p1 -}; - bo
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
llvmbot wrote: @llvm/pr-subscribers-backend-aarch64 Author: Sam Tebbs (SamTebbs33) Changes This patch adds an error that is emitted when a streaming function is marked as always_inline and is called from a non-streaming function. --- Full diff: https://github.com/llvm/llvm-project/pull/77936.diff 7 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+2) - (modified) clang/include/clang/Sema/Sema.h (+9) - (modified) clang/lib/CodeGen/CMakeLists.txt (+1) - (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+20) - (modified) clang/lib/Sema/SemaChecking.cpp (+10-17) - (added) clang/test/CodeGen/aarch64-sme-func-attrs-inline-locally-streaming.c (+12) - (added) clang/test/CodeGen/aarch64-sme-func-attrs-inline-streaming.c (+12) ``diff diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 568000106a84dc..dbd92b600a936e 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -279,6 +279,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_function_alwaysinline_attribute_mismatch : Error< + "always_inline function %1 and its caller %0 have mismatched %2 attributes">; def warn_avx_calling_convention : Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' " diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4c464a1ae4c67f..0fed60103c9a2c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13803,8 +13803,17 @@ class Sema final { FormatArgumentPassingKind ArgPassingKind; }; +enum ArmStreamingType { + ArmNonStreaming, + ArmStreaming, + ArmStreamingCompatible, + ArmStreamingOrSVE2p1 +}; + + static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI); + static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 52216d93a302bb..03a6f2f1d7a9d2 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -151,4 +151,5 @@ add_clang_library(clangCodeGen clangFrontend clangLex clangSerialization + clangSema ) diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 7102d190fe008b..ea3d5a97605f1c 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -8,6 +8,8 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" +#include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Sema/Sema.h" using namespace clang; using namespace clang::CodeGen; @@ -153,6 +155,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, +const FunctionDecl *Caller, +const FunctionDecl *Callee, +const CallArgList &Args) const override; }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { @@ -812,6 +819,19 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { +if (!Callee->hasAttr()) + return; + +auto CalleeIsStreaming = Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; +auto CallerIsStreaming = Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + +if (CalleeIsStreaming && !CallerIsStreaming) +CGM.getDiags().Report(CallLoc, diag::err_function_alwaysinline_attribute_mismatch) << Caller->getDeclName() << Callee->getDeclName() << "streaming"; +} + std::unique_ptr CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind) { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 74f8f626fb1637..160637dde448e4 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2998,13 +2998,6 @@ static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, llvm_unreachable("Invalid NeonTypeFlag!"); } -enum ArmStreamingType { - ArmNonStreaming, - ArmStreaming, - ArmStreamingCompatible, - ArmStreamingOrSVE2p1
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 124efcaa973306ce42633cea07ed3cf55d63afde bbc6c11cd3def5acbb2ba2f2ddc45df2c399f9d6 -- clang/test/CodeGen/aarch64-sme-func-attrs-inline-locally-streaming.c clang/test/CodeGen/aarch64-sme-func-attrs-inline-streaming.c clang/include/clang/Sema/Sema.h clang/lib/CodeGen/Targets/AArch64.cpp clang/lib/Sema/SemaChecking.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 0fed60103c..2ff1fcb01c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13803,13 +13803,12 @@ public: FormatArgumentPassingKind ArgPassingKind; }; -enum ArmStreamingType { - ArmNonStreaming, - ArmStreaming, - ArmStreamingCompatible, - ArmStreamingOrSVE2p1 -}; - + enum ArmStreamingType { +ArmNonStreaming, +ArmStreaming, +ArmStreamingCompatible, +ArmStreamingOrSVE2p1 + }; static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI); diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index ea3d5a9760..43555f577f 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -822,14 +822,18 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, void AArch64TargetCodeGenInfo::checkFunctionCallABI( CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, const FunctionDecl *Callee, const CallArgList &Args) const { -if (!Callee->hasAttr()) - return; + if (!Callee->hasAttr()) +return; -auto CalleeIsStreaming = Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; -auto CallerIsStreaming = Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + auto CalleeIsStreaming = + Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; + auto CallerIsStreaming = + Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; -if (CalleeIsStreaming && !CallerIsStreaming) -CGM.getDiags().Report(CallLoc, diag::err_function_alwaysinline_attribute_mismatch) << Caller->getDeclName() << Callee->getDeclName() << "streaming"; + if (CalleeIsStreaming && !CallerIsStreaming) +CGM.getDiags().Report(CallLoc, + diag::err_function_alwaysinline_attribute_mismatch) +<< Caller->getDeclName() << Callee->getDeclName() << "streaming"; } std::unique_ptr `` https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
https://github.com/SamTebbs33 updated https://github.com/llvm/llvm-project/pull/77936 >From bbc6c11cd3def5acbb2ba2f2ddc45df2c399f9d6 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 10 Jan 2024 14:57:04 + Subject: [PATCH 1/2] [Clang][SME] Detect always_inline used with mismatched streaming attributes This patch adds an error that is emitted when a streaming function is marked as always_inline and is called from a non-streaming function. --- .../clang/Basic/DiagnosticFrontendKinds.td| 2 ++ clang/include/clang/Sema/Sema.h | 9 +++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/Targets/AArch64.cpp | 20 ++ clang/lib/Sema/SemaChecking.cpp | 27 +++ ...-sme-func-attrs-inline-locally-streaming.c | 12 + .../aarch64-sme-func-attrs-inline-streaming.c | 12 + 7 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-sme-func-attrs-inline-locally-streaming.c create mode 100644 clang/test/CodeGen/aarch64-sme-func-attrs-inline-streaming.c diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 568000106a84dc..dbd92b600a936e 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -279,6 +279,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_function_alwaysinline_attribute_mismatch : Error< + "always_inline function %1 and its caller %0 have mismatched %2 attributes">; def warn_avx_calling_convention : Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' " diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4c464a1ae4c67f..0fed60103c9a2c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13803,8 +13803,17 @@ class Sema final { FormatArgumentPassingKind ArgPassingKind; }; +enum ArmStreamingType { + ArmNonStreaming, + ArmStreaming, + ArmStreamingCompatible, + ArmStreamingOrSVE2p1 +}; + + static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI); + static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 52216d93a302bb..03a6f2f1d7a9d2 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -151,4 +151,5 @@ add_clang_library(clangCodeGen clangFrontend clangLex clangSerialization + clangSema ) diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 7102d190fe008b..ea3d5a97605f1c 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -8,6 +8,8 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" +#include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Sema/Sema.h" using namespace clang; using namespace clang::CodeGen; @@ -153,6 +155,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, +const FunctionDecl *Caller, +const FunctionDecl *Callee, +const CallArgList &Args) const override; }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { @@ -812,6 +819,19 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { +if (!Callee->hasAttr()) + return; + +auto CalleeIsStreaming = Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; +auto CallerIsStreaming = Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + +if (CalleeIsStreaming && !CallerIsStreaming) +CGM.getDiags().Report(CallLoc, diag::err_function_alwaysinline_attribute_mismatch) << Caller->getDeclName() << Callee->getDeclName() << "streaming"; +} + std::unique_ptr CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind) { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 74f8f626fb1637..160637dde448e4 100644 --- a/clang/lib/Sem
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,23 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeIsStreaming = + Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; + auto CallerIsStreaming = + Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + + if (CalleeIsStreaming && !CallerIsStreaming) jroelofs wrote: What about mismatching the other way? ```suggestion if (CalleeIsStreaming != CallerIsStreaming) ``` https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
https://github.com/jroelofs edited https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,23 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeIsStreaming = + Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; + auto CallerIsStreaming = + Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + + if (CalleeIsStreaming && !CallerIsStreaming) SamTebbs33 wrote: That makes sense, thank you. I also realised that it'll need to check if the caller is streaming_compatible but the callee isn't, so I'll add that too. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,23 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeIsStreaming = MDevereau wrote: nit: I think `bool` is better than `auto` here https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -279,6 +279,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_function_alwaysinline_attribute_mismatch : Error< MDevereau wrote: ```suggestion def err_function_always_inline_attribute_mismatch : Error< ``` https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -0,0 +1,12 @@ +// RUN: %clang --target=aarch64-none-linux-gnu -march=armv9-a+sme -O3 -S -Xclang -verify %s + +// Conflicting attributes when using always_inline +__attribute__((always_inline)) __arm_locally_streaming +int inlined_fn_local(void) { +return 42; +} MDevereau wrote: Do these tests have to return an int? 42 looks like it could possibly be a significant magic number in some way. I think the tests can probably be combined into a single file like `clang/test/CodeGen/aarch64-sme-func-attrs-inline.c` too? https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
https://github.com/SamTebbs33 updated https://github.com/llvm/llvm-project/pull/77936 >From bbc6c11cd3def5acbb2ba2f2ddc45df2c399f9d6 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 10 Jan 2024 14:57:04 + Subject: [PATCH 1/3] [Clang][SME] Detect always_inline used with mismatched streaming attributes This patch adds an error that is emitted when a streaming function is marked as always_inline and is called from a non-streaming function. --- .../clang/Basic/DiagnosticFrontendKinds.td| 2 ++ clang/include/clang/Sema/Sema.h | 9 +++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/Targets/AArch64.cpp | 20 ++ clang/lib/Sema/SemaChecking.cpp | 27 +++ ...-sme-func-attrs-inline-locally-streaming.c | 12 + .../aarch64-sme-func-attrs-inline-streaming.c | 12 + 7 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-sme-func-attrs-inline-locally-streaming.c create mode 100644 clang/test/CodeGen/aarch64-sme-func-attrs-inline-streaming.c diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 568000106a84dc7..dbd92b600a936e2 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -279,6 +279,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_function_alwaysinline_attribute_mismatch : Error< + "always_inline function %1 and its caller %0 have mismatched %2 attributes">; def warn_avx_calling_convention : Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' " diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4c464a1ae4c67fe..0fed60103c9a2c3 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13803,8 +13803,17 @@ class Sema final { FormatArgumentPassingKind ArgPassingKind; }; +enum ArmStreamingType { + ArmNonStreaming, + ArmStreaming, + ArmStreamingCompatible, + ArmStreamingOrSVE2p1 +}; + + static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI); + static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 52216d93a302bbb..03a6f2f1d7a9d26 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -151,4 +151,5 @@ add_clang_library(clangCodeGen clangFrontend clangLex clangSerialization + clangSema ) diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 7102d190fe008bd..ea3d5a97605f1c3 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -8,6 +8,8 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" +#include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Sema/Sema.h" using namespace clang; using namespace clang::CodeGen; @@ -153,6 +155,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, +const FunctionDecl *Caller, +const FunctionDecl *Callee, +const CallArgList &Args) const override; }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { @@ -812,6 +819,19 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { +if (!Callee->hasAttr()) + return; + +auto CalleeIsStreaming = Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; +auto CallerIsStreaming = Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + +if (CalleeIsStreaming && !CallerIsStreaming) +CGM.getDiags().Report(CallLoc, diag::err_function_alwaysinline_attribute_mismatch) << Caller->getDeclName() << Callee->getDeclName() << "streaming"; +} + std::unique_ptr CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind) { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 74f8f626fb1637c..160637dde448e43 100644 --- a/cla
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,23 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeIsStreaming = + Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; + auto CallerIsStreaming = + Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + + if (CalleeIsStreaming && !CallerIsStreaming) SamTebbs33 wrote: Done https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -279,6 +279,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_function_alwaysinline_attribute_mismatch : Error< SamTebbs33 wrote: Much better, thanks. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -0,0 +1,12 @@ +// RUN: %clang --target=aarch64-none-linux-gnu -march=armv9-a+sme -O3 -S -Xclang -verify %s + +// Conflicting attributes when using always_inline +__attribute__((always_inline)) __arm_locally_streaming +int inlined_fn_local(void) { +return 42; +} SamTebbs33 wrote: They actually don't have to return an int. I'll change them to be void. The tests do unfortunately have to be in their own files as each error will stop the compiler from proceeding so we won't see the other errors being tested. The other tests can be combined since those errors are emitted earlier in the pipeline but I don't think that's possible here. Much like how only one error is emitted for this example: __attribute__ ((always_inline, target("+sme2"))) int bar(void) { return 42; } int foo(void) { return bar(); } int foo2(void) { return bar(); } https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,23 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeIsStreaming = SamTebbs33 wrote: Agreed, but it's now auto since I'm assigning it to the streaming mode instead of to a boolean. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -3145,7 +3138,7 @@ bool Sema::ParseSVEImmChecks( return HasError; } -static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) { +Sema::ArmStreamingType Sema::getArmStreamingFnType(const FunctionDecl *FD) { sdesmalen-arm wrote: I don't think this function is worth changing the build configuration to add a dependence of clang::Sema to clang::CodeGen :) You can just inline (duplicate) the functionality here directly into your function in `AArch64TargetCodeGenInfo::checkFunctionCallABI` and map the attributes directly to the `llvm::AArch64::SMEAttrs` class. That way you can also avoid needing the `ArmStreamingType` enum. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,24 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeStreamingMode = Sema::getArmStreamingFnType(Callee); + auto CallerStreamingMode = Sema::getArmStreamingFnType(Caller); + + // The caller can inline the callee if their streaming modes match or the + // callee is streaming compatible + if (CalleeStreamingMode != CallerStreamingMode && sdesmalen-arm wrote: Can you use the llvm::AArch64::SMEAttrs class and reuse some of the same functionality as we have in `AArch64TTIImpl::areInlineCompatible` (ignoring the `hasPossibleIncompatibleOps` part). That way, we can also check for ZA, e.g. ``` __attribute__((always_inline)) __arm_new("za") void bar(void) { } void foo() { bar(); } ``` here `bar` cannot be inlined because that would require making `foo` `__arm_new("za")` as well. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,24 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeStreamingMode = Sema::getArmStreamingFnType(Callee); + auto CallerStreamingMode = Sema::getArmStreamingFnType(Caller); + + // The caller can inline the callee if their streaming modes match or the + // callee is streaming compatible + if (CalleeStreamingMode != CallerStreamingMode && MDevereau wrote: It is valid to inline Callees with ArmStreaming or ArmStreamingCompatible into Callers with the __arm_locally_streaming keyword? What happens currently when you try this? https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
https://github.com/SamTebbs33 updated https://github.com/llvm/llvm-project/pull/77936 >From bbc6c11cd3def5acbb2ba2f2ddc45df2c399f9d6 Mon Sep 17 00:00:00 2001 From: Samuel Tebbs Date: Wed, 10 Jan 2024 14:57:04 + Subject: [PATCH 1/5] [Clang][SME] Detect always_inline used with mismatched streaming attributes This patch adds an error that is emitted when a streaming function is marked as always_inline and is called from a non-streaming function. --- .../clang/Basic/DiagnosticFrontendKinds.td| 2 ++ clang/include/clang/Sema/Sema.h | 9 +++ clang/lib/CodeGen/CMakeLists.txt | 1 + clang/lib/CodeGen/Targets/AArch64.cpp | 20 ++ clang/lib/Sema/SemaChecking.cpp | 27 +++ ...-sme-func-attrs-inline-locally-streaming.c | 12 + .../aarch64-sme-func-attrs-inline-streaming.c | 12 + 7 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-sme-func-attrs-inline-locally-streaming.c create mode 100644 clang/test/CodeGen/aarch64-sme-func-attrs-inline-streaming.c diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 568000106a84dc..dbd92b600a936e 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -279,6 +279,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_function_alwaysinline_attribute_mismatch : Error< + "always_inline function %1 and its caller %0 have mismatched %2 attributes">; def warn_avx_calling_convention : Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' " diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 4c464a1ae4c67f..0fed60103c9a2c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -13803,8 +13803,17 @@ class Sema final { FormatArgumentPassingKind ArgPassingKind; }; +enum ArmStreamingType { + ArmNonStreaming, + ArmStreaming, + ArmStreamingCompatible, + ArmStreamingOrSVE2p1 +}; + + static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI); + static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); private: void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr, diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 52216d93a302bb..03a6f2f1d7a9d2 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -151,4 +151,5 @@ add_clang_library(clangCodeGen clangFrontend clangLex clangSerialization + clangSema ) diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp index 7102d190fe008b..ea3d5a97605f1c 100644 --- a/clang/lib/CodeGen/Targets/AArch64.cpp +++ b/clang/lib/CodeGen/Targets/AArch64.cpp @@ -8,6 +8,8 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" +#include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Sema/Sema.h" using namespace clang; using namespace clang::CodeGen; @@ -153,6 +155,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, +const FunctionDecl *Caller, +const FunctionDecl *Callee, +const CallArgList &Args) const override; }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { @@ -812,6 +819,19 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { +if (!Callee->hasAttr()) + return; + +auto CalleeIsStreaming = Sema::getArmStreamingFnType(Callee) == Sema::ArmStreaming; +auto CallerIsStreaming = Sema::getArmStreamingFnType(Caller) == Sema::ArmStreaming; + +if (CalleeIsStreaming && !CallerIsStreaming) +CGM.getDiags().Report(CallLoc, diag::err_function_alwaysinline_attribute_mismatch) << Caller->getDeclName() << Callee->getDeclName() << "streaming"; +} + std::unique_ptr CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM, AArch64ABIKind Kind) { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 74f8f626fb1637..160637dde448e4 100644 --- a/clang/lib/Sem
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -0,0 +1,12 @@ +// RUN: %clang --target=aarch64-none-linux-gnu -march=armv9-a+sme -O3 -S -Xclang -verify %s + +// Conflicting attributes when using always_inline +__attribute__((always_inline)) __arm_locally_streaming +int inlined_fn_local(void) { +return 42; +} SamTebbs33 wrote: Done https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -279,6 +279,8 @@ def err_builtin_needs_feature : Error<"%0 needs target feature %1">; def err_function_needs_feature : Error< "always_inline function %1 requires target feature '%2', but would " "be inlined into function %0 that is compiled without support for '%2'">; +def err_function_alwaysinline_attribute_mismatch : Error< SamTebbs33 wrote: Done https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -153,6 +155,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, jroelofs wrote: where is this new function called? https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
efriedma-quic wrote: There's no general rule that forbids taking the address of an always_inline function. So if a user really wants to, they can call a mismatched always_inline function anyway. Given that, making this a hard error seems a bit dubious; it should probably be a warning instead. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -15,13 +15,13 @@ #define LLVM_LIB_TARGET_AARCH64_AARCH64ISELLOWERING_H #include "AArch64.h" -#include "Utils/AArch64SMEAttributes.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/TargetLowering.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Instruction.h" +#include "llvm/Support/AArch64SMEAttributes.h" sdesmalen-arm wrote: This change is no longer necessary? https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -814,6 +821,93 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +class SMEAttributes { +public: + bool IsStreaming = false; + bool IsStreamingBody = false; + bool IsStreamingCompatible = false; + bool HasNewZA = false; + + SMEAttributes(const FunctionDecl *F) { +if (F->hasAttr()) + IsStreamingBody = true; +if (auto *NewAttr = F->getAttr()) { + if (NewAttr->isNewZA()) +HasNewZA = true; +} +if (const auto *T = F->getType()->getAs()) { + if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask) +IsStreaming = true; + if (T->getAArch64SMEAttributes() & + FunctionType::SME_PStateSMCompatibleMask) +IsStreamingCompatible = true; +} + } + + bool hasStreamingBody() const { return IsStreamingBody; } + bool hasStreamingInterface() const { return IsStreaming; } + bool hasStreamingCompatibleInterface() const { return IsStreamingCompatible; } + bool hasStreamingInterfaceOrBody() const { +return hasStreamingBody() || hasStreamingInterface(); + } + bool hasNonStreamingInterface() const { +return !hasStreamingInterface() && !hasStreamingCompatibleInterface(); + } + bool hasNonStreamingInterfaceAndBody() const { +return hasNonStreamingInterface() && !hasStreamingBody(); + } + + bool requiresSMChange(const SMEAttributes Callee, +bool BodyOverridesInterface = false) { +// If the transition is not through a call (e.g. when considering inlining) +// and Callee has a streaming body, then we can ignore the interface of +// Callee. +if (BodyOverridesInterface && Callee.hasStreamingBody()) { + return !hasStreamingInterfaceOrBody(); +} + +if (Callee.hasStreamingCompatibleInterface()) + return false; + +if (hasStreamingCompatibleInterface()) + return true; + +// Both non-streaming +if (hasNonStreamingInterfaceAndBody() && Callee.hasNonStreamingInterface()) + return false; + +// Both streaming +if (hasStreamingInterfaceOrBody() && Callee.hasStreamingInterface()) + return false; + +return Callee.hasStreamingInterface(); + } + + bool hasNewZABody() { return HasNewZA; } + bool requiresLazySave() const { return HasNewZA; } sdesmalen-arm wrote: That doesn't look right. A lazy-save is required when the caller has ZA state and the callee does not share ZA state and is a Private-ZA function. That said, I think that we might be too restrictive (here and in LLVM) to not allow inlining of functions that would otherwise require a lazy-save. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
https://github.com/sdesmalen-arm edited https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -814,6 +821,93 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +class SMEAttributes { +public: + bool IsStreaming = false; + bool IsStreamingBody = false; + bool IsStreamingCompatible = false; + bool HasNewZA = false; + + SMEAttributes(const FunctionDecl *F) { +if (F->hasAttr()) + IsStreamingBody = true; +if (auto *NewAttr = F->getAttr()) { + if (NewAttr->isNewZA()) +HasNewZA = true; +} +if (const auto *T = F->getType()->getAs()) { + if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask) +IsStreaming = true; + if (T->getAArch64SMEAttributes() & + FunctionType::SME_PStateSMCompatibleMask) +IsStreamingCompatible = true; +} + } + + bool hasStreamingBody() const { return IsStreamingBody; } + bool hasStreamingInterface() const { return IsStreaming; } + bool hasStreamingCompatibleInterface() const { return IsStreamingCompatible; } + bool hasStreamingInterfaceOrBody() const { +return hasStreamingBody() || hasStreamingInterface(); + } + bool hasNonStreamingInterface() const { +return !hasStreamingInterface() && !hasStreamingCompatibleInterface(); + } + bool hasNonStreamingInterfaceAndBody() const { +return hasNonStreamingInterface() && !hasStreamingBody(); + } + + bool requiresSMChange(const SMEAttributes Callee, +bool BodyOverridesInterface = false) { +// If the transition is not through a call (e.g. when considering inlining) +// and Callee has a streaming body, then we can ignore the interface of +// Callee. +if (BodyOverridesInterface && Callee.hasStreamingBody()) { + return !hasStreamingInterfaceOrBody(); +} + +if (Callee.hasStreamingCompatibleInterface()) + return false; + +if (hasStreamingCompatibleInterface()) + return true; + +// Both non-streaming +if (hasNonStreamingInterfaceAndBody() && Callee.hasNonStreamingInterface()) + return false; + +// Both streaming +if (hasStreamingInterfaceOrBody() && Callee.hasStreamingInterface()) + return false; + +return Callee.hasStreamingInterface(); + } + + bool hasNewZABody() { return HasNewZA; } + bool requiresLazySave() const { return HasNewZA; } SamTebbs33 wrote: Thanks, I've now removed the lazy save checking to loosen that restriction. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,24 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeStreamingMode = Sema::getArmStreamingFnType(Callee); + auto CallerStreamingMode = Sema::getArmStreamingFnType(Caller); + + // The caller can inline the callee if their streaming modes match or the + // callee is streaming compatible + if (CalleeStreamingMode != CallerStreamingMode && SamTebbs33 wrote: Done, thanks for the idea. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -153,6 +155,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, SamTebbs33 wrote: It's called from CodeGenFunction::EmitCall in CGCall.cpp. x86 implements this function as well. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
https://github.com/jroelofs approved this pull request. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -812,6 +819,24 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto CalleeStreamingMode = Sema::getArmStreamingFnType(Callee); + auto CallerStreamingMode = Sema::getArmStreamingFnType(Caller); + + // The caller can inline the callee if their streaming modes match or the + // callee is streaming compatible + if (CalleeStreamingMode != CallerStreamingMode && SamTebbs33 wrote: It is indeed valid to inline a streaming function into a locally streaming function since at the inline point streaming is guaranteed to be on. We don't need the streaming mode save and restore that would come from a locally streaming function's prologue and epilogue. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
https://github.com/SamTebbs33 edited https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
sdesmalen-arm wrote: It seems wrong to move the header files to llvm/include/llvm/Support, but to leave the implementation in llvm/lib/AArch64 (which ends up in a different library). If you move the corresponding .cpp file to llvm/lib/Support then you don't need to link with `AArch64Utils`. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
sdesmalen-arm wrote: > > Separately, it's probably worth ensuring that the LLVM inlining passes > > don't actually perform illegal inlining for functions marked always_inline; > > looking at the code, it looks like we might end up skipping the relevant > > checks. > > The `TargetTransformInfo::areInlineCompatible` function in llvm makes these > checks. I think that Eli's point is that at the moment `areInlineCompatible` is not being called when using `always_inline`, which is something that needs changing. https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)
@@ -814,6 +821,42 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, /*allowHigherAlign*/ false); } +void AArch64TargetCodeGenInfo::checkFunctionCallABI( +CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, +const FunctionDecl *Callee, const CallArgList &Args) const { + if (!Callee->hasAttr()) +return; + + auto GetSMEAttrs = [](const FunctionDecl *F) { +llvm::SMEAttrs FAttrs; +if (F->hasAttr()) + FAttrs.set(llvm::SMEAttrs::Mask::SM_Enabled); +if (auto *NewAttr = F->getAttr()) { + if (NewAttr->isNewZA()) +FAttrs.set(llvm::SMEAttrs::Mask::ZA_New); +} +if (const auto *T = F->getType()->getAs()) { + if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask) +FAttrs.set(llvm::SMEAttrs::Mask::SM_Enabled); + if (T->getAArch64SMEAttributes() & + FunctionType::SME_PStateSMCompatibleMask) +FAttrs.set(llvm::SMEAttrs::Mask::SM_Compatible); +} +return FAttrs; + }; + + auto CalleeAttrs = GetSMEAttrs(Callee); + auto CallerAttrs = GetSMEAttrs(Caller); + + if (CallerAttrs.requiresSMChange(CalleeAttrs, true)) +CGM.getDiags().Report(CallLoc, + diag::err_function_always_inline_attribute_mismatch) +<< Caller->getDeclName() << Callee->getDeclName() << "streaming"; + if (CalleeAttrs.hasNewZABody()) +CGM.getDiags().Report(CallLoc, diag::err_function_always_inline_new_za) +<< Callee->getDeclName(); +} SamTebbs33 wrote: It is, thanks! https://github.com/llvm/llvm-project/pull/77936 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits