[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)

2024-01-30 Thread Sam Tebbs via cfe-commits


@@ -814,6 +821,93 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction , 
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)

2024-01-26 Thread Sander de Smalen via cfe-commits

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)

2024-01-26 Thread Sander de Smalen via cfe-commits


@@ -814,6 +821,93 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction , 
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)

2024-01-26 Thread Sander de Smalen via cfe-commits


@@ -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)

2024-01-19 Thread Sam Tebbs via cfe-commits


@@ -814,6 +821,42 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction , 
Address VAListAddr,
   /*allowHigherAlign*/ false);
 }
 
+void AArch64TargetCodeGenInfo::checkFunctionCallABI(
+CodeGenModule , SourceLocation CallLoc, const FunctionDecl *Caller,
+const FunctionDecl *Callee, const CallArgList ) 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


[llvm] [clang] [Clang][SME] Detect always_inline used with mismatched streaming attributes (PR #77936)

2024-01-19 Thread Sander de Smalen via cfe-commits

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)

2024-01-19 Thread Sander de Smalen via cfe-commits




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)

2024-01-19 Thread Sam Tebbs via cfe-commits

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)

2024-01-18 Thread Sam Tebbs via cfe-commits


@@ -812,6 +819,24 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction , 
Address VAListAddr,
   /*allowHigherAlign*/ false);
 }
 
+void AArch64TargetCodeGenInfo::checkFunctionCallABI(
+CodeGenModule , SourceLocation CallLoc, const FunctionDecl *Caller,
+const FunctionDecl *Callee, const CallArgList ) 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)

2024-01-18 Thread Jon Roelofs via cfe-commits

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)

2024-01-18 Thread Sam Tebbs via cfe-commits


@@ -153,6 +155,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
 }
 return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty);
   }
+
+  void checkFunctionCallABI(CodeGenModule , 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)

2024-01-18 Thread Sam Tebbs via cfe-commits


@@ -812,6 +819,24 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction , 
Address VAListAddr,
   /*allowHigherAlign*/ false);
 }
 
+void AArch64TargetCodeGenInfo::checkFunctionCallABI(
+CodeGenModule , SourceLocation CallLoc, const FunctionDecl *Caller,
+const FunctionDecl *Callee, const CallArgList ) 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