[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-14 Thread Sam Tebbs via cfe-commits

SamTebbs33 wrote:

New PR at https://github.com/llvm/llvm-project/pull/75487

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-14 Thread Sam Tebbs via cfe-commits

SamTebbs33 wrote:

Thanks for reporting that Nico. I've reverted the patch and will work on 
improving compile time. I like your idea Sander.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-14 Thread Sander de Smalen via cfe-commits

sdesmalen-arm wrote:

> On my system, this increases the compilation time of SemaChecking.cpp from 7 
> seconds to 2 minutes 46 seconds (using clang as a host compiler). That seems 
> excessive. Let's please find a way to not make compilation so slow, and let's 
> consider reverting this until a faster approach is found.

I see the same with GCC. It seems that changing the generated table from:
```
case SVE::BI__builtin_sve_svaba_n_s16: 
  BuiltinType = ArmStreamingCompatible;
  break;
case SVE::BI__builtin_sve_svaba_n_s32: 
  BuiltinType = ArmStreamingCompatible;
  break;
case SVE::BI__builtin_sve_svaba_n_s64: 
  BuiltinType = ArmStreamingCompatible;
  break;
...
```
to
```
case SVE::BI__builtin_sve_svacge_n_f16:
case SVE::BI__builtin_sve_svacge_n_f32:
case SVE::BI__builtin_sve_svacge_n_f64:
...
  BuiltinType = ArmStreamingCompatible;
  break;
```
resolves most of the issue without changing behaviours.

Additionally, it might be good to make the most common streaming-mode for this 
file the default (which for arm_sve.h is streaming-compatible), so that the 
table only has to capture the intrinsics which are explicitly non-streaming or 
streaming.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-13 Thread Nico Weber via cfe-commits

nico wrote:

On my system, this increases the compilation time of SemaChecking.cpp from 7 
seconds to 2 minutes 46 seconds (using clang as a host compiler). That seems 
excessive. Let's please find a way to not make compilation so slow, and let's 
consider reverting this until a faster approach is found.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-13 Thread Sam Tebbs via cfe-commits

https://github.com/SamTebbs33 closed 
https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-13 Thread Sander de Smalen via cfe-commits

https://github.com/sdesmalen-arm approved this pull request.


https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-13 Thread Sam Tebbs via cfe-commits


@@ -3168,9 +3167,60 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+ArmStreamingType BuiltinType;
+
+switch (BuiltinID) {
+default:
+  BuiltinType = ArmNonStreaming;
+  break;
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"
+#undef GET_SME_STREAMING_ATTRS
+#define GET_SVE_STREAMING_ATTRS
+#include "clang/Basic/arm_sve_streaming_attrs.inc"

SamTebbs33 wrote:

Good spot, thanks.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-13 Thread Sam Tebbs via cfe-commits


@@ -1694,6 +1697,61 @@ void SVEEmitter::createSMERangeChecks(raw_ostream ) {
   OS << "#endif\n\n";
 }
 
+void SVEEmitter::createStreamingAttrs(raw_ostream , ACLEKind Kind) {
+  std::vector RV = Records.getAllDerivedDefinitions("Inst");
+  SmallVector, 128> Defs;
+  for (auto *R : RV)
+createIntrinsic(R, Defs);
+
+  // The mappings must be sorted based on BuiltinID.
+  llvm::sort(Defs, [](const std::unique_ptr ,
+  const std::unique_ptr ) {
+return A->getMangledName() < B->getMangledName();
+  });
+
+  switch (Kind) {

SamTebbs33 wrote:

That looks nice and clean to me. Thanks for the suggestion.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-13 Thread Sander de Smalen via cfe-commits


@@ -3168,9 +3167,60 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+ArmStreamingType BuiltinType;
+
+switch (BuiltinID) {
+default:
+  BuiltinType = ArmNonStreaming;
+  break;
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"
+#undef GET_SME_STREAMING_ATTRS
+#define GET_SVE_STREAMING_ATTRS
+#include "clang/Basic/arm_sve_streaming_attrs.inc"
+#undef GET_SVE_STREAMING_ATTRS
+}
+
+if (BuiltinType)
+  checkArmStreamingBuiltin(*this, TheCall, FD, BuiltinType);
+  }
+
+  // Range check SME intrinsics that take immediate values.
+  SmallVector, 3> ImmChecks;
+
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_IMMEDIATE_CHECK
+#include "clang/Basic/arm_sme_sema_rangechecks.inc"

sdesmalen-arm wrote:

The SME range checks should be removed from `CheckSVEBuiltinFunctionCall` now.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-13 Thread Sander de Smalen via cfe-commits


@@ -3168,9 +3167,60 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+ArmStreamingType BuiltinType;
+
+switch (BuiltinID) {
+default:
+  BuiltinType = ArmNonStreaming;
+  break;
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"
+#undef GET_SME_STREAMING_ATTRS
+#define GET_SVE_STREAMING_ATTRS
+#include "clang/Basic/arm_sve_streaming_attrs.inc"

sdesmalen-arm wrote:

The SVE streaming-mode attributes already checked in 
`CheckSVEBuiltinFunctionCall`, there is no need to include them here again.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-13 Thread Sander de Smalen via cfe-commits


@@ -1694,6 +1697,61 @@ void SVEEmitter::createSMERangeChecks(raw_ostream ) {
   OS << "#endif\n\n";
 }
 
+void SVEEmitter::createStreamingAttrs(raw_ostream , ACLEKind Kind) {
+  std::vector RV = Records.getAllDerivedDefinitions("Inst");
+  SmallVector, 128> Defs;
+  for (auto *R : RV)
+createIntrinsic(R, Defs);
+
+  // The mappings must be sorted based on BuiltinID.
+  llvm::sort(Defs, [](const std::unique_ptr ,
+  const std::unique_ptr ) {
+return A->getMangledName() < B->getMangledName();
+  });
+
+  switch (Kind) {

sdesmalen-arm wrote:

nit: Rather than having two of these switch statements, you could do:

```
StringRef ExtensionKind;
switch (Kind) {
case ACLEKind::SME:
  ExtensionKind = "SME";
  break;
case ACLEKind::SVE:
  ExtensionKind = "SVE";
  break;
}

OS << "#ifdef GET_" << ExtensionKind << "_STREAMING_ATTRS\n";
...
for (...) {
  ...
  OS << "case " << ExtensionKind << "::BI_builtin_" << ExtensionKind.lower() << 
"_";
  ...
}
```

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -500,6 +506,12 @@ bool ClangTableGenMain(raw_ostream , RecordKeeper 
) {
   case GenArmSmeRangeChecks:
 EmitSmeRangeChecks(Records, OS);
 break;
+  case GenArmSmeStreamingAttrs:

SamTebbs33 wrote:

Done

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -20,3 +21,23 @@ int16x8_t incompat_neon_smc(int16x8_t splat) 
__arm_streaming_compatible {
   // expected-warning@+1 {{builtin call has undefined behaviour when called 
from a streaming compatible function}}
   return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, 
(int8x16_t)splat, 33);
 }
+
+void incompat_sme_norm(svbool_t pg, void const *ptr) __arm_shared_za {
+  // expected-warning@+1 {{builtin call has undefined behaviour when called 
from a non-streaming function}}
+  return __builtin_sme_svld1_hor_za128(0, 0, pg, ptr);

SamTebbs33 wrote:

I removed this test since, as you said, it wasn't testing anything different 
and after adding the SVE changes we have tests for SVE builtins anyway.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -3168,11 +3168,70 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}

SamTebbs33 wrote:

I've removed the ZA state changes and added the SVE changes. Let me know what 
you think.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -500,6 +506,12 @@ bool ClangTableGenMain(raw_ostream , RecordKeeper 
) {
   case GenArmSmeRangeChecks:
 EmitSmeRangeChecks(Records, OS);
 break;
+  case GenArmSmeStreamingAttrs:

SamTebbs33 wrote:

I remember you suggesting that we have the SME and SVE changes in separate PRs 
but I can bring the SVE changes into this one.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -1375,6 +1381,12 @@ void SVEEmitter::createHeader(raw_ostream ) {
   OS << "#define __aio static __inline__ __attribute__((__always_inline__, "
 "__nodebug__, __overloadable__))\n\n";
 
+  OS << "#ifdef __ARM_FEATURE_SME\n";
+  OS << "#define __asc __attribute__((arm_streaming_compatible))\n";

SamTebbs33 wrote:

Omitting it works for me, cheers.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -3168,11 +3168,70 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+static bool hasSMEZAState(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return true;
+  if (const auto *T = FD->getType()->getAs())
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask)
+  return true;
+  return false;
+}
+
+static bool hasSMEZAState(unsigned BuiltinID) {
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_BUILTIN_HAS_ZA_STATE
+#include "clang/Basic/arm_sme_builtins_za_state.inc"
+#undef GET_SME_BUILTIN_HAS_ZA_STATE
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+std::optional BuiltinType;

SamTebbs33 wrote:

Sure thing.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -18,7 +18,7 @@
 // CHECK-CXX-NEXT:tail call void @llvm.aarch64.sme.zero(i32 0)
 // CHECK-CXX-NEXT:ret void
 //
-void test_svzero_mask_za() {
+__arm_new_za void test_svzero_mask_za() {

SamTebbs33 wrote:

I did try `__arm_shared_za` but got 

> '__arm_shared_za' only applies to non-K functions

and

> error: '__arm_shared_za' only applies to function types; type here is 'void 
> ()'

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -6,20 +6,21 @@
 #include 
 
 __attribute__((target("sme")))
-void test_sme(svbool_t pg, void *ptr) {
+void test_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za {
   svld1_hor_za8(0, 0, pg, ptr);
 }
 
 __attribute__((target("arch=armv8-a+sme")))
-void test_arch_sme(svbool_t pg, void *ptr) {
+void test_arch_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za {
   svld1_hor_vnum_za32(0, 0, pg, ptr, 0);
 }
 
 __attribute__((target("+sme")))
-void test_plus_sme(svbool_t pg, void *ptr) {
+void test_plus_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za {
   svst1_ver_za16(0, 0, pg, ptr);
 }
 
-void undefined(svbool_t pg, void *ptr) {
-  svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-error 
{{'svst1_ver_vnum_za64' needs target feature sme}}
+__attribute__((target("+sme")))
+void undefined(svbool_t pg, void *ptr) __arm_shared_za {
+  svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-warning {{builtin call 
has undefined behaviour when called from a non-streaming function}}

SamTebbs33 wrote:

In a previous review you asked me to do so:

> I think instead you want to compile this test with 
> __attribute__((target("+sme"))) but without the __arm_streaming to ensure you 
> get a diagnostic on the builtin call that the behaviour is undefined when the 
> (parent) function is not a streaming function.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -20,3 +21,23 @@ int16x8_t incompat_neon_smc(int16x8_t splat) 
__arm_streaming_compatible {
   // expected-warning@+1 {{builtin call has undefined behaviour when called 
from a streaming compatible function}}
   return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, 
(int8x16_t)splat, 33);
 }
+
+void incompat_sme_norm(svbool_t pg, void const *ptr) __arm_shared_za {
+  // expected-warning@+1 {{builtin call has undefined behaviour when called 
from a non-streaming function}}
+  return __builtin_sme_svld1_hor_za128(0, 0, pg, ptr);

SamTebbs33 wrote:

> nit: returning a `void` value from a `void` function doesn't seem right.

Agreed, I'll fix that.
> Also, is `incompat_sme_norm` testing anything that `incompat_sme_sm` isn't 
> testing?
> Or should this be a test where we'd call a non-streaming SVE/SME builtin from 
> a streaming-function?

Yeah it doesn't look like it is. That would be better!





https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sam Tebbs via cfe-commits


@@ -3058,6 +3058,11 @@ bool Sema::ParseSVEImmChecks(
   if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, 7))
 HasError = true;
   break;
+case SVETypeFlags::ImmCheck2_4_Mul2:

SamTebbs33 wrote:

I think you were looking at an old commit as I fixed that in 
[48ee745](https://github.com/llvm/llvm-project/pull/74064/commits/48ee745a815f0fda41cb1791f91d73db73e4aeba)

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sander de Smalen via cfe-commits


@@ -3168,11 +3168,70 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+static bool hasSMEZAState(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return true;
+  if (const auto *T = FD->getType()->getAs())
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask)
+  return true;
+  return false;
+}
+
+static bool hasSMEZAState(unsigned BuiltinID) {
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_BUILTIN_HAS_ZA_STATE
+#include "clang/Basic/arm_sme_builtins_za_state.inc"
+#undef GET_SME_BUILTIN_HAS_ZA_STATE
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+std::optional BuiltinType;

sdesmalen-arm wrote:

Why is this `std::optional` rather than `ArmStreamingType` ?
We could just set the `default:` case below to be `ArmNonStreaming`.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sander de Smalen via cfe-commits


@@ -18,7 +18,7 @@
 // CHECK-CXX-NEXT:tail call void @llvm.aarch64.sme.zero(i32 0)
 // CHECK-CXX-NEXT:ret void
 //
-void test_svzero_mask_za() {
+__arm_new_za void test_svzero_mask_za() {

sdesmalen-arm wrote:

Why are these `__arm_new_za` rather than `__arm_shared_za`?

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sander de Smalen via cfe-commits


@@ -6,20 +6,21 @@
 #include 
 
 __attribute__((target("sme")))
-void test_sme(svbool_t pg, void *ptr) {
+void test_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za {
   svld1_hor_za8(0, 0, pg, ptr);
 }
 
 __attribute__((target("arch=armv8-a+sme")))
-void test_arch_sme(svbool_t pg, void *ptr) {
+void test_arch_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za {
   svld1_hor_vnum_za32(0, 0, pg, ptr, 0);
 }
 
 __attribute__((target("+sme")))
-void test_plus_sme(svbool_t pg, void *ptr) {
+void test_plus_sme(svbool_t pg, void *ptr) __arm_streaming __arm_shared_za {
   svst1_ver_za16(0, 0, pg, ptr);
 }
 
-void undefined(svbool_t pg, void *ptr) {
-  svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-error 
{{'svst1_ver_vnum_za64' needs target feature sme}}
+__attribute__((target("+sme")))
+void undefined(svbool_t pg, void *ptr) __arm_shared_za {
+  svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-warning {{builtin call 
has undefined behaviour when called from a non-streaming function}}

sdesmalen-arm wrote:

This test should not have changed.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sander de Smalen via cfe-commits


@@ -3058,6 +3058,11 @@ bool Sema::ParseSVEImmChecks(
   if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, 7))
 HasError = true;
   break;
+case SVETypeFlags::ImmCheck2_4_Mul2:

sdesmalen-arm wrote:

This shouldn't have moved.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sander de Smalen via cfe-commits


@@ -500,6 +506,12 @@ bool ClangTableGenMain(raw_ostream , RecordKeeper 
) {
   case GenArmSmeRangeChecks:
 EmitSmeRangeChecks(Records, OS);
 break;
+  case GenArmSmeStreamingAttrs:

sdesmalen-arm wrote:

We also need to do this for SVE (you seem to have added the logic for it in 
SveEmitter.cpp, but are not using it otherwise).

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sander de Smalen via cfe-commits


@@ -20,3 +21,23 @@ int16x8_t incompat_neon_smc(int16x8_t splat) 
__arm_streaming_compatible {
   // expected-warning@+1 {{builtin call has undefined behaviour when called 
from a streaming compatible function}}
   return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, 
(int8x16_t)splat, 33);
 }
+
+void incompat_sme_norm(svbool_t pg, void const *ptr) __arm_shared_za {
+  // expected-warning@+1 {{builtin call has undefined behaviour when called 
from a non-streaming function}}
+  return __builtin_sme_svld1_hor_za128(0, 0, pg, ptr);

sdesmalen-arm wrote:

nit: returning a `void` value from a `void` function doesn't seem right.

Also, is `incompat_sme_norm` testing anything that `incompat_sme_sm` isn't 
testing?

Or should this be a test where we'd call a non-streaming SVE/SME builtin from a 
streaming-function?

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sander de Smalen via cfe-commits


@@ -1375,6 +1381,12 @@ void SVEEmitter::createHeader(raw_ostream ) {
   OS << "#define __aio static __inline__ __attribute__((__always_inline__, "
 "__nodebug__, __overloadable__))\n\n";
 
+  OS << "#ifdef __ARM_FEATURE_SME\n";
+  OS << "#define __asc __attribute__((arm_streaming_compatible))\n";

sdesmalen-arm wrote:

A few things:
* The `__attribute__((arm_streaming_compatible))` syntax is not supported.
* `__asc` is not used/emitted anywhere
* I'm not sure adding the attribute to the function prototype in the header 
file adds much value anyway. Better to just omit it.


https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-08 Thread Sander de Smalen via cfe-commits


@@ -3168,11 +3168,70 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}

sdesmalen-arm wrote:

I think this functionality is big enough to warrant it own PR, such that we 
have:
* One PR for testing the compatibility of streaming-mode for both SVE and SME.
* One PR for testing that the calling function of a ZA-using builtin has ZA 
state.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-07 Thread Sam Tebbs via cfe-commits


@@ -3183,6 +3140,114 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   return HasError;
 }
 
+static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return ArmStreaming;
+  if (const auto *T = FD->getType()->getAs()) {
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask)
+  return ArmStreaming;
+if (T->getAArch64SMEAttributes() & 
FunctionType::SME_PStateSMCompatibleMask)
+  return ArmStreamingCompatible;
+  }
+  return ArmNonStreaming;
+}
+
+static void checkArmStreamingBuiltin(Sema , CallExpr *TheCall,
+ const FunctionDecl *FD,
+ ArmStreamingType BuiltinType) {
+  ArmStreamingType FnType = getArmStreamingFnType(FD);
+
+  if (FnType == ArmStreaming && BuiltinType == ArmNonStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "streaming";
+  }
+
+  if (FnType == ArmStreamingCompatible &&
+  BuiltinType != ArmStreamingCompatible) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "streaming compatible";
+return;
+  }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+static bool hasSMEZAState(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return true;
+  if (const auto *T = FD->getType()->getAs())
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask)
+  return true;
+  return false;
+}
+
+static bool hasSMEZAState(unsigned BuiltinID) {
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_BUILTIN_HAS_ZA_STATE
+#include "clang/Basic/arm_sme_builtins_za_state.inc"
+#undef GET_SME_BUILTIN_HAS_ZA_STATE
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+std::optional BuiltinType;
+
+switch (BuiltinID) {
+default:
+  break;
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"
+#undef GET_SME_STREAMING_ATTRS
+}
+
+if (BuiltinType)
+  checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType);
+
+if (hasSMEZAState(BuiltinID) && !hasSMEZAState(FD))
+  Diag(TheCall->getBeginLoc(),
+   diag::warn_attribute_arm_za_builtin_no_za_state)
+  << TheCall->getSourceRange();
+  }
+
+  // Range check SME intrinsics that take immediate values.
+  SmallVector, 3> ImmChecks;
+
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_IMMEDIATE_CHECK
+#include "clang/Basic/arm_sme_sema_rangechecks.inc"
+#undef GET_SME_IMMEDIATE_CHECK
+  }
+
+  return ParseSVEImmChecks(TheCall, ImmChecks);
+}
+
+bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {

SamTebbs33 wrote:

Done! Rebased and should be ready for review again now.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-06 Thread Sam Tebbs via cfe-commits


@@ -3172,6 +3117,18 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 255))
 HasError = true;
   break;
+case SVETypeFlags::ImmCheck1_1:

SamTebbs33 wrote:

I'm actually not sure. When building the compiler was telling me that these 
cases weren't being checked for so I added them. I'm not sure what caused them 
to disappear in the first place. I'll revert this chunk.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-06 Thread Sam Tebbs via cfe-commits


@@ -3183,6 +3140,114 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   return HasError;
 }
 
+static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return ArmStreaming;
+  if (const auto *T = FD->getType()->getAs()) {
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask)
+  return ArmStreaming;
+if (T->getAArch64SMEAttributes() & 
FunctionType::SME_PStateSMCompatibleMask)
+  return ArmStreamingCompatible;
+  }
+  return ArmNonStreaming;
+}
+
+static void checkArmStreamingBuiltin(Sema , CallExpr *TheCall,
+ const FunctionDecl *FD,
+ ArmStreamingType BuiltinType) {
+  ArmStreamingType FnType = getArmStreamingFnType(FD);
+
+  if (FnType == ArmStreaming && BuiltinType == ArmNonStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "streaming";
+  }
+
+  if (FnType == ArmStreamingCompatible &&
+  BuiltinType != ArmStreamingCompatible) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "streaming compatible";
+return;
+  }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+static bool hasSMEZAState(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return true;
+  if (const auto *T = FD->getType()->getAs())
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask)
+  return true;
+  return false;
+}
+
+static bool hasSMEZAState(unsigned BuiltinID) {
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_BUILTIN_HAS_ZA_STATE
+#include "clang/Basic/arm_sme_builtins_za_state.inc"
+#undef GET_SME_BUILTIN_HAS_ZA_STATE
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+std::optional BuiltinType;
+
+switch (BuiltinID) {
+default:
+  break;
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"
+#undef GET_SME_STREAMING_ATTRS
+}
+
+if (BuiltinType)
+  checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType);
+
+if (hasSMEZAState(BuiltinID) && !hasSMEZAState(FD))
+  Diag(TheCall->getBeginLoc(),
+   diag::warn_attribute_arm_za_builtin_no_za_state)
+  << TheCall->getSourceRange();
+  }
+
+  // Range check SME intrinsics that take immediate values.
+  SmallVector, 3> ImmChecks;
+
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_IMMEDIATE_CHECK
+#include "clang/Basic/arm_sme_sema_rangechecks.inc"
+#undef GET_SME_IMMEDIATE_CHECK
+  }
+
+  return ParseSVEImmChecks(TheCall, ImmChecks);
+}
+
+bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {

SamTebbs33 wrote:

Sure thing

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-06 Thread Sander de Smalen via cfe-commits


@@ -3172,6 +3117,18 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 255))
 HasError = true;
   break;
+case SVETypeFlags::ImmCheck1_1:

sdesmalen-arm wrote:

Why have these case statements moved?

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-06 Thread Sander de Smalen via cfe-commits


@@ -3183,6 +3140,114 @@ bool Sema::CheckSVEBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   return HasError;
 }
 
+static ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return ArmStreaming;
+  if (const auto *T = FD->getType()->getAs()) {
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask)
+  return ArmStreaming;
+if (T->getAArch64SMEAttributes() & 
FunctionType::SME_PStateSMCompatibleMask)
+  return ArmStreamingCompatible;
+  }
+  return ArmNonStreaming;
+}
+
+static void checkArmStreamingBuiltin(Sema , CallExpr *TheCall,
+ const FunctionDecl *FD,
+ ArmStreamingType BuiltinType) {
+  ArmStreamingType FnType = getArmStreamingFnType(FD);
+
+  if (FnType == ArmStreaming && BuiltinType == ArmNonStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "streaming";
+  }
+
+  if (FnType == ArmStreamingCompatible &&
+  BuiltinType != ArmStreamingCompatible) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "streaming compatible";
+return;
+  }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+static bool hasSMEZAState(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return true;
+  if (const auto *T = FD->getType()->getAs())
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask)
+  return true;
+  return false;
+}
+
+static bool hasSMEZAState(unsigned BuiltinID) {
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_BUILTIN_HAS_ZA_STATE
+#include "clang/Basic/arm_sme_builtins_za_state.inc"
+#undef GET_SME_BUILTIN_HAS_ZA_STATE
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+std::optional BuiltinType;
+
+switch (BuiltinID) {
+default:
+  break;
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"
+#undef GET_SME_STREAMING_ATTRS
+}
+
+if (BuiltinType)
+  checkArmStreamingBuiltin(*this, TheCall, FD, *BuiltinType);
+
+if (hasSMEZAState(BuiltinID) && !hasSMEZAState(FD))
+  Diag(TheCall->getBeginLoc(),
+   diag::warn_attribute_arm_za_builtin_no_za_state)
+  << TheCall->getSourceRange();
+  }
+
+  // Range check SME intrinsics that take immediate values.
+  SmallVector, 3> ImmChecks;
+
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_IMMEDIATE_CHECK
+#include "clang/Basic/arm_sme_sema_rangechecks.inc"
+#undef GET_SME_IMMEDIATE_CHECK
+  }
+
+  return ParseSVEImmChecks(TheCall, ImmChecks);
+}
+
+bool Sema::CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {

sdesmalen-arm wrote:

Can you commit the change to move the immediate checks to `ParseSVEImmChecks` 
as an NFC patch and rebase this one?

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-05 Thread Sam Tebbs via cfe-commits


@@ -3023,6 +3151,66 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+static bool hasSMEZAState(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return true;
+  if (const auto *T = FD->getType()->getAs())
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask)
+  return true;
+  return false;
+}
+
+static bool hasSMEZAState(unsigned BuiltinID) {
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_BUILTIN_HAS_ZA_STATE
+#include "clang/Basic/arm_sme_builtins_za_state.inc"
+#undef GET_SME_BUILTIN_HAS_ZA_STATE
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+bool debug = FD->getDeclName().getAsString() == "incompat_sve_sm";
+std::optional BuiltinType;
+
+switch (BuiltinID) {
+default:
+  break;
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"

SamTebbs33 wrote:

Kept the function separate as per our offline discussion.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-05 Thread Sam Tebbs via cfe-commits


@@ -289,7 +283,7 @@ ARM_STREAMING_ATTR void test_svst1_ver_vnum_za64(uint32_t 
slice_base, svbool_t p
 // CHECK-CXX-NEXT:tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]])
 // CHECK-CXX-NEXT:ret void
 //
-ARM_STREAMING_ATTR void test_svst1_ver_vnum_za128(uint32_t slice_base, 
svbool_t pg, void *ptr, int64_t vnum) {
+void test_svst1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, 
int64_t vnum) __arm_streaming {

SamTebbs33 wrote:

Done

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-05 Thread Sander de Smalen via cfe-commits


@@ -6,20 +6,20 @@
 #include 
 
 __attribute__((target("sme")))
-void test_sme(svbool_t pg, void *ptr) {
+void test_sme(svbool_t pg, void *ptr) __arm_streaming {
   svld1_hor_za8(0, 0, pg, ptr);
 }
 
 __attribute__((target("arch=armv8-a+sme")))
-void test_arch_sme(svbool_t pg, void *ptr) {
+void test_arch_sme(svbool_t pg, void *ptr) __arm_streaming {
   svld1_hor_vnum_za32(0, 0, pg, ptr, 0);
 }
 
 __attribute__((target("+sme")))
-void test_plus_sme(svbool_t pg, void *ptr) {
+void test_plus_sme(svbool_t pg, void *ptr) __arm_streaming {
   svst1_ver_za16(0, 0, pg, ptr);
 }
 
-void undefined(svbool_t pg, void *ptr) {
-  svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-error 
{{'svst1_ver_vnum_za64' needs target feature sme}}
+void undefined(svbool_t pg, void *ptr) __arm_streaming { // expected-error 
{{function executed in streaming-SVE mode requires 'sme'}}

sdesmalen-arm wrote:

Ah, I see that the actual message changed too. It's now complaining about 
`__arm_streaming` on a non-SME function, whereas before it was testing that the 
builtin was predicated with the correct attribute.

This is already tested in `aarch64-sme-func-attrs-without-target-feature.cpp`.

I think instead you want to compile this test with 
`__attribute__((target("+sme")))` but without the `__arm_streaming` to ensure 
you get a diagnostic on the builtin call that the behaviour is undefined when 
the (parent) function is not a streaming function.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-05 Thread Sam Tebbs via cfe-commits


@@ -2995,6 +2995,134 @@ static QualType getNeonEltType(NeonTypeFlags Flags, 
ASTContext ,
 
 enum ArmStreamingType { ArmNonStreaming, ArmStreaming, ArmStreamingCompatible 
};
 
+bool Sema::ParseSVEImmChecks(
+CallExpr *TheCall, SmallVector, 3> ) {
+  // Perform all the immediate checks for this builtin call.
+  bool HasError = false;
+  for (auto  : ImmChecks) {
+int ArgNum, CheckTy, ElementSizeInBits;
+std::tie(ArgNum, CheckTy, ElementSizeInBits) = I;
+
+typedef bool (*OptionSetCheckFnTy)(int64_t Value);
+
+// Function that checks whether the operand (ArgNum) is an immediate
+// that is one of the predefined values.
+auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm,
+   int ErrDiag) -> bool {
+  // We can't check the value of a dependent argument.
+  Expr *Arg = TheCall->getArg(ArgNum);
+  if (Arg->isTypeDependent() || Arg->isValueDependent())
+return false;
+
+  // Check constant-ness first.
+  llvm::APSInt Imm;
+  if (SemaBuiltinConstantArg(TheCall, ArgNum, Imm))
+return true;
+
+  if (!CheckImm(Imm.getSExtValue()))
+return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange();
+  return false;
+};
+
+switch ((SVETypeFlags::ImmCheckType)CheckTy) {
+case SVETypeFlags::ImmCheck0_31:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 31))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_13:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 13))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck1_16:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, 16))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_7:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 7))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckExtract:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  (2048 / ElementSizeInBits) - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckShiftRight:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, ElementSizeInBits))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckShiftRightNarrow:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1,
+  ElementSizeInBits / 2))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckShiftLeft:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  ElementSizeInBits - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckLaneIndex:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  (128 / (1 * ElementSizeInBits)) - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckLaneIndexCompRotate:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  (128 / (2 * ElementSizeInBits)) - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckLaneIndexDot:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  (128 / (4 * ElementSizeInBits)) - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckComplexRot90_270:
+  if (CheckImmediateInSet([](int64_t V) { return V == 90 || V == 270; },
+  diag::err_rotation_argument_to_cadd))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckComplexRotAll90:
+  if (CheckImmediateInSet(
+  [](int64_t V) {
+return V == 0 || V == 90 || V == 180 || V == 270;
+  },
+  diag::err_rotation_argument_to_cmla))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_1:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_2:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 2))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_3:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 3))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_0:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 0))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_15:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 15))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_255:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 255))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck2_4_Mul2:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 2, 4) ||
+  SemaBuiltinConstantArgMultiple(TheCall, ArgNum, 2))
+HasError = true;
+  break;

SamTebbs33 wrote:

I think it can :+1: 


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-05 Thread Sam Tebbs via cfe-commits


@@ -6,20 +6,20 @@
 #include 
 
 __attribute__((target("sme")))
-void test_sme(svbool_t pg, void *ptr) {
+void test_sme(svbool_t pg, void *ptr) __arm_streaming {
   svld1_hor_za8(0, 0, pg, ptr);
 }
 
 __attribute__((target("arch=armv8-a+sme")))
-void test_arch_sme(svbool_t pg, void *ptr) {
+void test_arch_sme(svbool_t pg, void *ptr) __arm_streaming {
   svld1_hor_vnum_za32(0, 0, pg, ptr, 0);
 }
 
 __attribute__((target("+sme")))
-void test_plus_sme(svbool_t pg, void *ptr) {
+void test_plus_sme(svbool_t pg, void *ptr) __arm_streaming {
   svst1_ver_za16(0, 0, pg, ptr);
 }
 
-void undefined(svbool_t pg, void *ptr) {
-  svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-error 
{{'svst1_ver_vnum_za64' needs target feature sme}}
+void undefined(svbool_t pg, void *ptr) __arm_streaming { // expected-error 
{{function executed in streaming-SVE mode requires 'sme'}}

SamTebbs33 wrote:

With the streaming attribute added, the error is thrown for the function 
signature line, so it has to be on this line.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-05 Thread Sam Tebbs via cfe-commits


@@ -289,7 +283,7 @@ ARM_STREAMING_ATTR void test_svst1_ver_vnum_za64(uint32_t 
slice_base, svbool_t p
 // CHECK-CXX-NEXT:tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]])
 // CHECK-CXX-NEXT:ret void
 //
-ARM_STREAMING_ATTR void test_svst1_ver_vnum_za128(uint32_t slice_base, 
svbool_t pg, void *ptr, int64_t vnum) {
+void test_svst1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, 
int64_t vnum) __arm_streaming {

SamTebbs33 wrote:

Sure thing.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-01 Thread Sander de Smalen via cfe-commits

https://github.com/sdesmalen-arm edited 
https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-01 Thread Sander de Smalen via cfe-commits


@@ -289,7 +283,7 @@ ARM_STREAMING_ATTR void test_svst1_ver_vnum_za64(uint32_t 
slice_base, svbool_t p
 // CHECK-CXX-NEXT:tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]])
 // CHECK-CXX-NEXT:ret void
 //
-ARM_STREAMING_ATTR void test_svst1_ver_vnum_za128(uint32_t slice_base, 
svbool_t pg, void *ptr, int64_t vnum) {
+void test_svst1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, 
int64_t vnum) __arm_streaming {

sdesmalen-arm wrote:

Could you commit these test changes (where you remove the __attribute__ syntax 
and the macro) separately and rebase this patch?

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-01 Thread Sander de Smalen via cfe-commits


@@ -3023,6 +3151,66 @@ static void checkArmStreamingBuiltin(Sema , CallExpr 
*TheCall,
 << TheCall->getSourceRange() << "streaming compatible";
 return;
   }
+
+  if (FnType == ArmNonStreaming && BuiltinType == ArmStreaming) {
+S.Diag(TheCall->getBeginLoc(), 
diag::warn_attribute_arm_sm_incompat_builtin)
+<< TheCall->getSourceRange() << "non-streaming";
+  }
+}
+
+static bool hasSMEZAState(const FunctionDecl *FD) {
+  if (FD->hasAttr())
+return true;
+  if (const auto *T = FD->getType()->getAs())
+if (T->getAArch64SMEAttributes() & FunctionType::SME_PStateZASharedMask)
+  return true;
+  return false;
+}
+
+static bool hasSMEZAState(unsigned BuiltinID) {
+  switch (BuiltinID) {
+  default:
+return false;
+#define GET_SME_BUILTIN_HAS_ZA_STATE
+#include "clang/Basic/arm_sme_builtins_za_state.inc"
+#undef GET_SME_BUILTIN_HAS_ZA_STATE
+  }
+}
+
+bool Sema::CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
+  if (const FunctionDecl *FD = getCurFunctionDecl()) {
+bool debug = FD->getDeclName().getAsString() == "incompat_sve_sm";
+std::optional BuiltinType;
+
+switch (BuiltinID) {
+default:
+  break;
+#define GET_SME_STREAMING_ATTRS
+#include "clang/Basic/arm_sme_streaming_attrs.inc"

sdesmalen-arm wrote:

Is it not worth merging this into `CheckSVEBuitinFunctionCall` ?
That avoids the need to move out the immediate checks altogether.

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-01 Thread Sander de Smalen via cfe-commits


@@ -6,20 +6,20 @@
 #include 
 
 __attribute__((target("sme")))
-void test_sme(svbool_t pg, void *ptr) {
+void test_sme(svbool_t pg, void *ptr) __arm_streaming {
   svld1_hor_za8(0, 0, pg, ptr);
 }
 
 __attribute__((target("arch=armv8-a+sme")))
-void test_arch_sme(svbool_t pg, void *ptr) {
+void test_arch_sme(svbool_t pg, void *ptr) __arm_streaming {
   svld1_hor_vnum_za32(0, 0, pg, ptr, 0);
 }
 
 __attribute__((target("+sme")))
-void test_plus_sme(svbool_t pg, void *ptr) {
+void test_plus_sme(svbool_t pg, void *ptr) __arm_streaming {
   svst1_ver_za16(0, 0, pg, ptr);
 }
 
-void undefined(svbool_t pg, void *ptr) {
-  svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-error 
{{'svst1_ver_vnum_za64' needs target feature sme}}
+void undefined(svbool_t pg, void *ptr) __arm_streaming { // expected-error 
{{function executed in streaming-SVE mode requires 'sme'}}

sdesmalen-arm wrote:

Should the `// expected-error {{ ... }}` not be on the next line? (I would 
expect the test fails now, because the line doesn't match up)

https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-01 Thread Kerry McLaughlin via cfe-commits


@@ -2995,6 +2995,134 @@ static QualType getNeonEltType(NeonTypeFlags Flags, 
ASTContext ,
 
 enum ArmStreamingType { ArmNonStreaming, ArmStreaming, ArmStreamingCompatible 
};
 
+bool Sema::ParseSVEImmChecks(
+CallExpr *TheCall, SmallVector, 3> ) {
+  // Perform all the immediate checks for this builtin call.
+  bool HasError = false;
+  for (auto  : ImmChecks) {
+int ArgNum, CheckTy, ElementSizeInBits;
+std::tie(ArgNum, CheckTy, ElementSizeInBits) = I;
+
+typedef bool (*OptionSetCheckFnTy)(int64_t Value);
+
+// Function that checks whether the operand (ArgNum) is an immediate
+// that is one of the predefined values.
+auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm,
+   int ErrDiag) -> bool {
+  // We can't check the value of a dependent argument.
+  Expr *Arg = TheCall->getArg(ArgNum);
+  if (Arg->isTypeDependent() || Arg->isValueDependent())
+return false;
+
+  // Check constant-ness first.
+  llvm::APSInt Imm;
+  if (SemaBuiltinConstantArg(TheCall, ArgNum, Imm))
+return true;
+
+  if (!CheckImm(Imm.getSExtValue()))
+return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange();
+  return false;
+};
+
+switch ((SVETypeFlags::ImmCheckType)CheckTy) {
+case SVETypeFlags::ImmCheck0_31:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 31))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_13:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 13))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck1_16:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, 16))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_7:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 7))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckExtract:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  (2048 / ElementSizeInBits) - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckShiftRight:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1, ElementSizeInBits))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckShiftRightNarrow:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 1,
+  ElementSizeInBits / 2))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckShiftLeft:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  ElementSizeInBits - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckLaneIndex:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  (128 / (1 * ElementSizeInBits)) - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckLaneIndexCompRotate:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  (128 / (2 * ElementSizeInBits)) - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckLaneIndexDot:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0,
+  (128 / (4 * ElementSizeInBits)) - 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckComplexRot90_270:
+  if (CheckImmediateInSet([](int64_t V) { return V == 90 || V == 270; },
+  diag::err_rotation_argument_to_cadd))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheckComplexRotAll90:
+  if (CheckImmediateInSet(
+  [](int64_t V) {
+return V == 0 || V == 90 || V == 180 || V == 270;
+  },
+  diag::err_rotation_argument_to_cmla))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_1:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 1))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_2:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 2))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_3:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 3))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_0:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 0))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_15:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 15))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck0_255:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 255))
+HasError = true;
+  break;
+case SVETypeFlags::ImmCheck2_4_Mul2:
+  if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 2, 4) ||
+  SemaBuiltinConstantArgMultiple(TheCall, ArgNum, 2))
+HasError = true;
+  break;

kmclaughlin-arm wrote:

Can 

[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-01 Thread via cfe-commits

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 9468de48fcd413aa0895a78bd6f1aeb161b39294 
f6a990a000b555d7f8ef0b2a99e3fea98420e899 -- clang/include/clang/Sema/Sema.h 
clang/lib/Sema/SemaChecking.cpp 
clang/test/Sema/aarch64-incompat-sm-builtin-calls.c 
clang/utils/TableGen/SveEmitter.cpp clang/utils/TableGen/TableGen.cpp 
clang/utils/TableGen/TableGenBackends.h
``





View the diff from clang-format here.


``diff
diff --git a/clang/utils/TableGen/TableGen.cpp 
b/clang/utils/TableGen/TableGen.cpp
index 9ba2fb07f1..3031a0dd5e 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -285,11 +285,14 @@ cl::opt Action(
"Generate riscv_vector_builtin_cg.inc for clang"),
 clEnumValN(GenRISCVVectorBuiltinSema, "gen-riscv-vector-builtin-sema",
"Generate riscv_vector_builtin_sema.inc for clang"),
-clEnumValN(GenRISCVSiFiveVectorBuiltins, 
"gen-riscv-sifive-vector-builtins",
+clEnumValN(GenRISCVSiFiveVectorBuiltins,
+   "gen-riscv-sifive-vector-builtins",
"Generate riscv_sifive_vector_builtins.inc for clang"),
-clEnumValN(GenRISCVSiFiveVectorBuiltinCG, 
"gen-riscv-sifive-vector-builtin-codegen",
+clEnumValN(GenRISCVSiFiveVectorBuiltinCG,
+   "gen-riscv-sifive-vector-builtin-codegen",
"Generate riscv_sifive_vector_builtin_cg.inc for clang"),
-clEnumValN(GenRISCVSiFiveVectorBuiltinSema, 
"gen-riscv-sifive-vector-builtin-sema",
+clEnumValN(GenRISCVSiFiveVectorBuiltinSema,
+   "gen-riscv-sifive-vector-builtin-sema",
"Generate riscv_sifive_vector_builtin_sema.inc for clang"),
 clEnumValN(GenAttrDocs, "gen-attr-docs",
"Generate attribute documentation"),

``




https://github.com/llvm/llvm-project/pull/74064
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-01 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Sam Tebbs (SamTebbs33)


Changes

This PR adds a warning that's emitted when a non-streaming or 
non-streaming-compatible builtin is called in an unsuitable function.

Uses work by Kerry McLaughlin.

---
Full diff: https://github.com/llvm/llvm-project/pull/74064.diff


8 Files Affected:

- (modified) clang/include/clang/Basic/CMakeLists.txt (+6) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3) 
- (modified) clang/include/clang/Sema/Sema.h (+3) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+191) 
- (modified) clang/test/Sema/aarch64-incompat-sm-builtin-calls.c (+21) 
- (modified) clang/utils/TableGen/SveEmitter.cpp (+68) 
- (modified) clang/utils/TableGen/TableGen.cpp (+9) 
- (modified) clang/utils/TableGen/TableGenBackends.h (+1) 


``diff
diff --git a/clang/include/clang/Basic/CMakeLists.txt 
b/clang/include/clang/Basic/CMakeLists.txt
index 085e316fcc671df..bdd72d1d63c431b 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -97,6 +97,12 @@ clang_tablegen(arm_sme_builtin_cg.inc 
-gen-arm-sme-builtin-codegen
 clang_tablegen(arm_sme_sema_rangechecks.inc -gen-arm-sme-sema-rangechecks
   SOURCE arm_sme.td
   TARGET ClangARMSmeSemaRangeChecks)
+clang_tablegen(arm_sme_streaming_attrs.inc -gen-arm-sme-streaming-attrs
+  SOURCE arm_sme.td
+  TARGET ClangARMSmeStreamingAttrs)
+clang_tablegen(arm_sme_builtins_za_state.inc -gen-arm-sme-builtin-za-state
+  SOURCE arm_sme.td
+  TARGET ClangARMSmeBuiltinsZAState)
 clang_tablegen(arm_cde_builtins.inc -gen-arm-cde-builtin-def
   SOURCE arm_cde.td
   TARGET ClangARMCdeBuiltinsDef)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6dfb2d7195203a3..c7036fc881a13e1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3151,6 +3151,9 @@ def err_attribute_arm_feature_sve_bits_unsupported : 
Error<
 def warn_attribute_arm_sm_incompat_builtin : Warning<
   "builtin call has undefined behaviour when called from a %0 function">,
   InGroup>;
+def warn_attribute_arm_za_builtin_no_za_state : Warning<
+  "builtin call is not valid when calling from a function without active ZA 
state">,
+  InGroup>;
 def err_sve_vector_in_non_sve_target : Error<
   "SVE vector type %0 cannot be used in a target without sve">;
 def err_attribute_riscv_rvv_bits_unsupported : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6de1a098e067a38..c13c6942c219700 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13845,7 +13845,10 @@ class Sema final {
   bool CheckNeonBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
 CallExpr *TheCall);
   bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool ParseSVEImmChecks(CallExpr *TheCall,
+ SmallVector, 3> );
   bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckCDEBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckARMCoprocessorImmediate(const TargetInfo , const Expr 
*CoprocArg,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 77c8334f3ca25d3..f27eb8ad95cc703 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2995,6 +2995,134 @@ static QualType getNeonEltType(NeonTypeFlags Flags, 
ASTContext ,
 
 enum ArmStreamingType { ArmNonStreaming, ArmStreaming, ArmStreamingCompatible 
};
 
+bool Sema::ParseSVEImmChecks(
+CallExpr *TheCall, SmallVector, 3> ) {
+  // Perform all the immediate checks for this builtin call.
+  bool HasError = false;
+  for (auto  : ImmChecks) {
+int ArgNum, CheckTy, ElementSizeInBits;
+std::tie(ArgNum, CheckTy, ElementSizeInBits) = I;
+
+typedef bool (*OptionSetCheckFnTy)(int64_t Value);
+
+// Function that checks whether the operand (ArgNum) is an immediate
+// that is one of the predefined values.
+auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm,
+   int ErrDiag) -> bool {
+  // We can't check the value of a dependent argument.
+  Expr *Arg = TheCall->getArg(ArgNum);
+  if (Arg->isTypeDependent() || Arg->isValueDependent())
+return false;
+
+  // Check constant-ness first.
+  llvm::APSInt Imm;
+  if (SemaBuiltinConstantArg(TheCall, ArgNum, Imm))
+return true;
+
+  if (!CheckImm(Imm.getSExtValue()))
+return Diag(TheCall->getBeginLoc(), ErrDiag) << Arg->getSourceRange();
+  return false;
+};
+
+switch ((SVETypeFlags::ImmCheckType)CheckTy) {
+case SVETypeFlags::ImmCheck0_31:
+  if 

[clang] [AArch64][SME] Warn when using a streaming builtin from a non-streaming function (PR #74064)

2023-12-01 Thread Sam Tebbs via cfe-commits

https://github.com/SamTebbs33 created 
https://github.com/llvm/llvm-project/pull/74064

This PR adds a warning that's emitted when a non-streaming or 
non-streaming-compatible builtin is called in an unsuitable function.

Uses work by Kerry McLaughlin.

>From f6a990a000b555d7f8ef0b2a99e3fea98420e899 Mon Sep 17 00:00:00 2001
From: Samuel Tebbs 
Date: Thu, 30 Nov 2023 13:42:50 +
Subject: [PATCH] [AArch64][SME] Warn when using a streaming builtin from a
 non-streaming function

This PR adds a warning that's emitted when a non-streaming or
non-streaming-compatible builtin is called in an unsuitable function.

Uses work by Kerry McLaughlin.
---
 clang/include/clang/Basic/CMakeLists.txt  |   6 +
 .../clang/Basic/DiagnosticSemaKinds.td|   3 +
 clang/include/clang/Sema/Sema.h   |   3 +
 clang/lib/Sema/SemaChecking.cpp   | 191 ++
 .../Sema/aarch64-incompat-sm-builtin-calls.c  |  21 ++
 clang/utils/TableGen/SveEmitter.cpp   |  68 +++
 clang/utils/TableGen/TableGen.cpp |   9 +
 clang/utils/TableGen/TableGenBackends.h   |   1 +
 8 files changed, 302 insertions(+)

diff --git a/clang/include/clang/Basic/CMakeLists.txt 
b/clang/include/clang/Basic/CMakeLists.txt
index 085e316fcc671df..bdd72d1d63c431b 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -97,6 +97,12 @@ clang_tablegen(arm_sme_builtin_cg.inc 
-gen-arm-sme-builtin-codegen
 clang_tablegen(arm_sme_sema_rangechecks.inc -gen-arm-sme-sema-rangechecks
   SOURCE arm_sme.td
   TARGET ClangARMSmeSemaRangeChecks)
+clang_tablegen(arm_sme_streaming_attrs.inc -gen-arm-sme-streaming-attrs
+  SOURCE arm_sme.td
+  TARGET ClangARMSmeStreamingAttrs)
+clang_tablegen(arm_sme_builtins_za_state.inc -gen-arm-sme-builtin-za-state
+  SOURCE arm_sme.td
+  TARGET ClangARMSmeBuiltinsZAState)
 clang_tablegen(arm_cde_builtins.inc -gen-arm-cde-builtin-def
   SOURCE arm_cde.td
   TARGET ClangARMCdeBuiltinsDef)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6dfb2d7195203a3..c7036fc881a13e1 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3151,6 +3151,9 @@ def err_attribute_arm_feature_sve_bits_unsupported : 
Error<
 def warn_attribute_arm_sm_incompat_builtin : Warning<
   "builtin call has undefined behaviour when called from a %0 function">,
   InGroup>;
+def warn_attribute_arm_za_builtin_no_za_state : Warning<
+  "builtin call is not valid when calling from a function without active ZA 
state">,
+  InGroup>;
 def err_sve_vector_in_non_sve_target : Error<
   "SVE vector type %0 cannot be used in a target without sve">;
 def err_attribute_riscv_rvv_bits_unsupported : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6de1a098e067a38..c13c6942c219700 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13845,7 +13845,10 @@ class Sema final {
   bool CheckNeonBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
 CallExpr *TheCall);
   bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool ParseSVEImmChecks(CallExpr *TheCall,
+ SmallVector, 3> );
   bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
+  bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
   bool CheckCDEBuiltinFunctionCall(const TargetInfo , unsigned BuiltinID,
CallExpr *TheCall);
   bool CheckARMCoprocessorImmediate(const TargetInfo , const Expr 
*CoprocArg,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 77c8334f3ca25d3..f27eb8ad95cc703 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2995,6 +2995,134 @@ static QualType getNeonEltType(NeonTypeFlags Flags, 
ASTContext ,
 
 enum ArmStreamingType { ArmNonStreaming, ArmStreaming, ArmStreamingCompatible 
};
 
+bool Sema::ParseSVEImmChecks(
+CallExpr *TheCall, SmallVector, 3> ) {
+  // Perform all the immediate checks for this builtin call.
+  bool HasError = false;
+  for (auto  : ImmChecks) {
+int ArgNum, CheckTy, ElementSizeInBits;
+std::tie(ArgNum, CheckTy, ElementSizeInBits) = I;
+
+typedef bool (*OptionSetCheckFnTy)(int64_t Value);
+
+// Function that checks whether the operand (ArgNum) is an immediate
+// that is one of the predefined values.
+auto CheckImmediateInSet = [&](OptionSetCheckFnTy CheckImm,
+   int ErrDiag) -> bool {
+  // We can't check the value of a dependent argument.
+  Expr *Arg = TheCall->getArg(ArgNum);
+  if (Arg->isTypeDependent() || Arg->isValueDependent())
+return false;
+
+  // Check constant-ness first.
+  llvm::APSInt Imm;
+  if (SemaBuiltinConstantArg(TheCall,