Skip to content

Commit 1644a31

Browse files
[Clang][AArch64] Generalise streaming mode checks for builtins. (#93802)
PR #76975 added 'IsStreamingOrSVE2p1' to emit a diagnostic when a builtin marked with 'IsStreamingOrSVE2p1' is used in a non-streaming function that is not compiled with `+sve2p1`. The problem is a bit more complex than only this case. For example, we've marked lots of builtins with 'IsStreamingCompatible', meaning it can be used in either streaming, streaming-compatible or non-streaming functions. But the code in SemaChecking, doesn't check the appropriate target guards. This issue becomes relevant when SVE builtins are only available in streaming mode, e.g. when compiling for SME without SVE. If we were to add the appropriate target guards, we'd have to add many more combinations, e.g.: IsStreamingSMEOrSVE IsStreamingSME2OrSVE2 IsStreamingSMEOrSVE2p1 IsStreamingSME2OrSVE2p1 etc. To avoid having to add more combinations (and avoid having to add more in the future for new extensions), we use a single 'IsSVEOrStreamingSVE' flag for all builtins that are available in streaming mode for the appropriate SME flags, or in non-streaming mode for the appropriate SVE flags, or both. The code in SemaChecking will then verify for which mode (or both) the builtin would be defined, given the target features of the function/compilation unit. For example: 'svclamp' is enabled under FEAT_SVE2p1 and FEAT_SME2 * When we compile for SVE2p1 and SME (but not SME2), the builtin is undefined behaviour when called from a streaming function. * When we compile for SME2 and SVE2 (but not SVE2p1), the builtin is undefined behaviour when called from a non-streaming function. * When we compile for _both_ SVE2p1 and SME2, the builtin can be used in either mode (non-streaming, streaming or streaming-compatible)
1 parent 5548ea3 commit 1644a31

File tree

13 files changed

+983
-899
lines changed

13 files changed

+983
-899
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3200,9 +3200,8 @@ def err_attribute_bad_sve_vector_size : Error<
32003200
def err_attribute_arm_feature_sve_bits_unsupported : Error<
32013201
"%0 is only supported when '-msve-vector-bits=<bits>' is specified with a "
32023202
"value of 128, 256, 512, 1024 or 2048">;
3203-
def warn_attribute_arm_sm_incompat_builtin : Warning<
3204-
"builtin call has undefined behaviour when called from a %0 function">,
3205-
InGroup<DiagGroup<"undefined-arm-streaming">>;
3203+
def err_attribute_arm_sm_incompat_builtin : Error<
3204+
"builtin can only be called from a %0 function">;
32063205
def warn_attribute_arm_za_builtin_no_za_state : Warning<
32073206
"builtin call is not valid when calling from a function without active ZA state">,
32083207
InGroup<DiagGroup<"undefined-arm-za">>;

clang/include/clang/Basic/arm_sve.td

Lines changed: 781 additions & 769 deletions
Large diffs are not rendered by default.

clang/include/clang/Basic/arm_sve_sme_incl.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ def IsStreamingCompatible : FlagType<0x4000000000>;
225225
def IsReadZA : FlagType<0x8000000000>;
226226
def IsWriteZA : FlagType<0x10000000000>;
227227
def IsReductionQV : FlagType<0x20000000000>;
228-
def IsStreamingOrSVE2p1 : FlagType<0x40000000000>; // Use for intrinsics that are common between sme/sme2 and sve2p1.
228+
def VerifyRuntimeMode : FlagType<0x40000000000>; // Use for intrinsics that are common between SVE and SME.
229229
def IsInZA : FlagType<0x80000000000>;
230230
def IsOutZA : FlagType<0x100000000000>;
231231
def IsInOutZA : FlagType<0x200000000000>;

clang/include/clang/Sema/SemaARM.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,13 @@ class SemaARM : public SemaBase {
2828
SemaARM(Sema &S);
2929

3030
enum ArmStreamingType {
31-
ArmNonStreaming,
32-
ArmStreaming,
33-
ArmStreamingCompatible,
34-
ArmStreamingOrSVE2p1
31+
ArmNonStreaming, /// Intrinsic is only available in normal mode
32+
ArmStreaming, /// Intrinsic is only available in Streaming-SVE mode.
33+
ArmStreamingCompatible, /// Intrinsic is available both in normal and
34+
/// Streaming-SVE mode.
35+
VerifyRuntimeMode /// Intrinsic is available in normal mode with
36+
/// SVE flags, or in Streaming-SVE mode with SME
37+
/// flags. Do Sema checks for the runtime mode.
3538
};
3639

3740
bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall,

clang/lib/Sema/SemaARM.cpp

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -560,31 +560,76 @@ SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD) {
560560
return SemaARM::ArmNonStreaming;
561561
}
562562

563-
static void checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
563+
static bool checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
564564
const FunctionDecl *FD,
565-
SemaARM::ArmStreamingType BuiltinType) {
565+
SemaARM::ArmStreamingType BuiltinType,
566+
unsigned BuiltinID) {
566567
SemaARM::ArmStreamingType FnType = getArmStreamingFnType(FD);
567-
if (BuiltinType == SemaARM::ArmStreamingOrSVE2p1) {
568-
// Check intrinsics that are available in [sve2p1 or sme/sme2].
569-
llvm::StringMap<bool> CallerFeatureMap;
570-
S.Context.getFunctionFeatureMap(CallerFeatureMap, FD);
571-
if (Builtin::evaluateRequiredTargetFeatures("sve2p1", CallerFeatureMap))
572-
BuiltinType = SemaARM::ArmStreamingCompatible;
573-
else
568+
569+
// Check if the intrinsic is available in the right mode, i.e.
570+
// * When compiling for SME only, the caller must be in streaming mode.
571+
// * When compiling for SVE only, the caller must be in non-streaming mode.
572+
// * When compiling for both SVE and SME, the caller can be in either mode.
573+
if (BuiltinType == SemaARM::VerifyRuntimeMode) {
574+
auto DisableFeatures = [](llvm::StringMap<bool> &Map, StringRef S) {
575+
for (StringRef K : Map.keys())
576+
if (K.starts_with(S))
577+
Map[K] = false;
578+
};
579+
580+
llvm::StringMap<bool> CallerFeatureMapWithoutSVE;
581+
S.Context.getFunctionFeatureMap(CallerFeatureMapWithoutSVE, FD);
582+
DisableFeatures(CallerFeatureMapWithoutSVE, "sve");
583+
584+
// Avoid emitting diagnostics for a function that can never compile.
585+
if (FnType == SemaARM::ArmStreaming && !CallerFeatureMapWithoutSVE["sme"])
586+
return false;
587+
588+
llvm::StringMap<bool> CallerFeatureMapWithoutSME;
589+
S.Context.getFunctionFeatureMap(CallerFeatureMapWithoutSME, FD);
590+
DisableFeatures(CallerFeatureMapWithoutSME, "sme");
591+
592+
// We know the builtin requires either some combination of SVE flags, or
593+
// some combination of SME flags, but we need to figure out which part
594+
// of the required features is satisfied by the target features.
595+
//
596+
// For a builtin with target guard 'sve2p1|sme2', if we compile with
597+
// '+sve2p1,+sme', then we know that it satisfies the 'sve2p1' part if we
598+
// evaluate the features for '+sve2p1,+sme,+nosme'.
599+
//
600+
// Similarly, if we compile with '+sve2,+sme2', then we know it satisfies
601+
// the 'sme2' part if we evaluate the features for '+sve2,+sme2,+nosve'.
602+
StringRef BuiltinTargetGuards(
603+
S.Context.BuiltinInfo.getRequiredFeatures(BuiltinID));
604+
bool SatisfiesSVE = Builtin::evaluateRequiredTargetFeatures(
605+
BuiltinTargetGuards, CallerFeatureMapWithoutSME);
606+
bool SatisfiesSME = Builtin::evaluateRequiredTargetFeatures(
607+
BuiltinTargetGuards, CallerFeatureMapWithoutSVE);
608+
609+
if ((SatisfiesSVE && SatisfiesSME) ||
610+
(SatisfiesSVE && FnType == SemaARM::ArmStreamingCompatible))
611+
return false;
612+
else if (SatisfiesSVE)
613+
BuiltinType = SemaARM::ArmNonStreaming;
614+
else if (SatisfiesSME)
574615
BuiltinType = SemaARM::ArmStreaming;
616+
else
617+
// This should be diagnosed by CodeGen
618+
return false;
575619
}
576620

577-
if (FnType == SemaARM::ArmStreaming &&
621+
if (FnType != SemaARM::ArmNonStreaming &&
578622
BuiltinType == SemaARM::ArmNonStreaming)
579-
S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin)
580-
<< TheCall->getSourceRange() << "streaming";
581-
else if (FnType == SemaARM::ArmNonStreaming && BuiltinType == SemaARM::ArmStreaming)
582-
S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin)
623+
S.Diag(TheCall->getBeginLoc(), diag::err_attribute_arm_sm_incompat_builtin)
583624
<< TheCall->getSourceRange() << "non-streaming";
584-
else if (FnType == SemaARM::ArmStreamingCompatible &&
585-
BuiltinType != SemaARM::ArmStreamingCompatible)
586-
S.Diag(TheCall->getBeginLoc(), diag::warn_attribute_arm_sm_incompat_builtin)
587-
<< TheCall->getSourceRange() << "streaming compatible";
625+
else if (FnType != SemaARM::ArmStreaming &&
626+
BuiltinType == SemaARM::ArmStreaming)
627+
S.Diag(TheCall->getBeginLoc(), diag::err_attribute_arm_sm_incompat_builtin)
628+
<< TheCall->getSourceRange() << "streaming";
629+
else
630+
return false;
631+
632+
return true;
588633
}
589634

590635
static bool hasArmZAState(const FunctionDecl *FD) {
@@ -622,8 +667,9 @@ bool SemaARM::CheckSMEBuiltinFunctionCall(unsigned BuiltinID,
622667
#undef GET_SME_STREAMING_ATTRS
623668
}
624669

625-
if (BuiltinType)
626-
checkArmStreamingBuiltin(SemaRef, TheCall, FD, *BuiltinType);
670+
if (BuiltinType &&
671+
checkArmStreamingBuiltin(SemaRef, TheCall, FD, *BuiltinType, BuiltinID))
672+
return true;
627673

628674
if ((getSMEState(BuiltinID) & ArmZAMask) && !hasArmZAState(FD))
629675
Diag(TheCall->getBeginLoc(),
@@ -660,8 +706,9 @@ bool SemaARM::CheckSVEBuiltinFunctionCall(unsigned BuiltinID,
660706
#include "clang/Basic/arm_sve_streaming_attrs.inc"
661707
#undef GET_SVE_STREAMING_ATTRS
662708
}
663-
if (BuiltinType)
664-
checkArmStreamingBuiltin(SemaRef, TheCall, FD, *BuiltinType);
709+
if (BuiltinType &&
710+
checkArmStreamingBuiltin(SemaRef, TheCall, FD, *BuiltinType, BuiltinID))
711+
return true;
665712
}
666713
// Range check SVE intrinsics that take immediate values.
667714
SmallVector<std::tuple<int, int, int>, 3> ImmChecks;
@@ -689,7 +736,9 @@ bool SemaARM::CheckNeonBuiltinFunctionCall(const TargetInfo &TI,
689736
#define TARGET_BUILTIN(id, ...) case NEON::BI##id:
690737
#define BUILTIN(id, ...) case NEON::BI##id:
691738
#include "clang/Basic/arm_neon.inc"
692-
checkArmStreamingBuiltin(SemaRef, TheCall, FD, ArmNonStreaming);
739+
if (checkArmStreamingBuiltin(SemaRef, TheCall, FD, ArmNonStreaming,
740+
BuiltinID))
741+
return true;
693742
break;
694743
#undef TARGET_BUILTIN
695744
#undef BUILTIN

clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_pext.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// RUN: %clang_cc1 -triple aarch64 -target-feature +bf16 -target-feature +sme -target-feature +sve -target-feature +sme2 -O1 -Werror -emit-llvm -o - %s | FileCheck %s
44
// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -target-feature +sve2 -target-feature +sve2p1 -O1 -Werror -emit-llvm -o - %s | FileCheck %s
55
// RUN: %clang_cc1 -triple aarch64 -target-feature +sve -target-feature +sve2 -target-feature +sve2p1 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
6-
// RUN: %clang_cc1 -triple aarch64 -target-feature +bf16 -target-feature +sve -target-feature +sve2 -target-feature +sme -target-feature +sve2p1 -O1 -Werror -emit-llvm -o - %s | FileCheck %s
6+
// RUN: %clang_cc1 -triple aarch64 -target-feature +bf16 -target-feature +sve -target-feature +sve2 -target-feature +sve2p1 -O1 -Werror -emit-llvm -o - %s | FileCheck %s
77
// RUN: %clang_cc1 -triple aarch64 -target-feature +bf16 -target-feature +sme -target-feature +sme2 -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK
88
// RUN: %clang_cc1 -triple aarch64 -target-feature +bf16 -target-feature +sme -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
99

clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_qrshr.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010

1111
#include <arm_sve.h>
1212

13+
#ifdef __ARM_FEATURE_SME
14+
#define ATTR __arm_streaming
15+
#else
16+
#define ATTR
17+
#endif
18+
1319
#ifdef SVE_OVERLOADED_FORMS
1420
// A simple used,unused... macro, long enough to represent any SVE builtin.
1521
#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED,A5) A1##A3##A5
@@ -34,7 +40,7 @@
3440
// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrn.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
3541
// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
3642
//
37-
svint16_t test_svqrshrn_s16_s32_x2(svint32x2_t zn) __arm_streaming_compatible {
43+
svint16_t test_svqrshrn_s16_s32_x2(svint32x2_t zn) ATTR {
3844
return SVE_ACLE_FUNC(svqrshrn,_n,_s16,_s32_x2,)(zn, 16);
3945
}
4046

@@ -54,7 +60,7 @@ svint16_t test_svqrshrn_s16_s32_x2(svint32x2_t zn) __arm_streaming_compatible {
5460
// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.uqrshrn.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
5561
// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
5662
//
57-
svuint16_t test_svqrshrn_u16_u32_x2(svuint32x2_t zn) __arm_streaming_compatible {
63+
svuint16_t test_svqrshrn_u16_u32_x2(svuint32x2_t zn) ATTR {
5864
return SVE_ACLE_FUNC(svqrshrn,_n,_u16,_u32_x2,)(zn, 16);
5965
}
6066

@@ -74,6 +80,6 @@ svuint16_t test_svqrshrn_u16_u32_x2(svuint32x2_t zn) __arm_streaming_compatible
7480
// CPP-CHECK-NEXT: [[TMP2:%.*]] = tail call <vscale x 8 x i16> @llvm.aarch64.sve.sqrshrun.x2.nxv4i32(<vscale x 4 x i32> [[TMP0]], <vscale x 4 x i32> [[TMP1]], i32 16)
7581
// CPP-CHECK-NEXT: ret <vscale x 8 x i16> [[TMP2]]
7682
//
77-
svuint16_t test_svqrshrun_u16_s32_x2(svint32x2_t zn) __arm_streaming_compatible {
83+
svuint16_t test_svqrshrun_u16_s32_x2(svint32x2_t zn) ATTR {
7884
return SVE_ACLE_FUNC(svqrshrun,_n,_u16,_s32_x2,)(zn, 16);
7985
}

clang/test/Sema/aarch64-incompat-sm-builtin-calls.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,100 +9,93 @@
99
#include "arm_sve.h"
1010

1111
int16x8_t incompat_neon_sm(int16x8_t splat) __arm_streaming {
12-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}}
12+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
1313
return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33);
1414
}
1515

1616
__arm_locally_streaming int16x8_t incompat_neon_ls(int16x8_t splat) {
17-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}}
17+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
1818
return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33);
1919
}
2020

2121
int16x8_t incompat_neon_smc(int16x8_t splat) __arm_streaming_compatible {
22-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming compatible function}}
22+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
2323
return (int16x8_t)__builtin_neon_vqaddq_v((int8x16_t)splat, (int8x16_t)splat, 33);
2424
}
2525

2626
void incompat_sme_smc(svbool_t pg, void const *ptr) __arm_streaming_compatible __arm_inout("za") {
27-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming compatible function}}
27+
// expected-error@+1 {{builtin can only be called from a streaming function}}
2828
return __builtin_sme_svld1_hor_za128(0, 0, pg, ptr);
2929
}
3030

3131
svuint32_t incompat_sve_sm(svbool_t pg, svuint32_t a, int16_t b) __arm_streaming {
32-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}}
32+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
3333
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
3434
}
3535

3636
// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
3737
// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
3838
__arm_locally_streaming svuint32_t incompat_sve_ls(svbool_t pg, svuint32_t a, int64_t b) {
39-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}}
39+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
4040
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
4141
}
4242

4343
svuint32_t incompat_sve_smc(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming_compatible {
44-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming compatible function}}
44+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
4545
return __builtin_sve_svld1_gather_u32base_index_u32(pg, a, b);
4646
}
4747

4848
svuint32_t incompat_sve2_sm(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming {
49-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}}
49+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
5050
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
5151
}
5252

5353
// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
5454
// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
5555
__arm_locally_streaming svuint32_t incompat_sve2_ls(svbool_t pg, svuint32_t a, int64_t b) {
56-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming function}}
56+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
5757
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
5858
}
5959

6060
svuint32_t incompat_sve2_smc(svbool_t pg, svuint32_t a, int64_t b) __arm_streaming_compatible {
61-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a streaming compatible function}}
61+
// expected-error@+1 {{builtin can only be called from a non-streaming function}}
6262
return __builtin_sve_svldnt1_gather_u32base_index_u32(pg, a, b);
6363
}
6464

6565
void incompat_sme_sm(svbool_t pn, svbool_t pm, svfloat32_t zn, svfloat32_t zm) __arm_inout("za") {
66-
// expected-warning@+1 {{builtin call has undefined behaviour when called from a non-streaming function}}
66+
// expected-error@+1 {{builtin can only be called from a streaming function}}
6767
svmops_za32_f32_m(0, pn, pm, zn, zm);
6868
}
6969

7070
svfloat64_t streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_streaming {
71-
// expected-no-warning
7271
return svadd_n_f64_m(pg, a, b);
7372
}
7473

7574
// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
7675
// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
7776
__arm_locally_streaming svfloat64_t locally_streaming_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) {
78-
// expected-no-warning
7977
return svadd_n_f64_m(pg, a, b);
8078
}
8179

8280
svfloat64_t streaming_compatible_caller_sve(svbool_t pg, svfloat64_t a, float64_t b) __arm_streaming_compatible {
83-
// expected-no-warning
8481
return svadd_n_f64_m(pg, a, b);
8582
}
8683

8784
svint16_t streaming_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming {
88-
// expected-no-warning
8985
return svmul_lane_s16(op1, op2, 0);
9086
}
9187

9288
// expected-warning@+2 {{returning a VL-dependent argument from a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
9389
// expected-warning@+1 {{passing a VL-dependent argument to a locally streaming function is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}}
9490
__arm_locally_streaming svint16_t locally_streaming_caller_sve2(svint16_t op1, svint16_t op2) {
95-
// expected-no-warning
9691
return svmul_lane_s16(op1, op2, 0);
9792
}
9893

9994
svint16_t streaming_compatible_caller_sve2(svint16_t op1, svint16_t op2) __arm_streaming_compatible {
100-
// expected-no-warning
10195
return svmul_lane_s16(op1, op2, 0);
10296
}
10397

10498
svbool_t streaming_caller_ptrue(void) __arm_streaming {
105-
// expected-no-warning
10699
return svand_z(svptrue_b16(), svptrue_pat_b16(SV_ALL), svptrue_pat_b16(SV_VL4));
107100
}
108101

@@ -113,7 +106,6 @@ svint8_t missing_za(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streami
113106

114107
__arm_new("za")
115108
svint8_t new_za(svint8_t zd, svbool_t pg, uint32_t slice_base) __arm_streaming {
116-
// expected-no-warning
117109
return svread_hor_za8_s8_m(zd, pg, 0, slice_base);
118110
}
119111

@@ -123,4 +115,4 @@ void missing_zt0(void) __arm_streaming {
123115
}
124116

125117
__arm_new("zt0")
126-
void new_zt0(void) __arm_streaming { svzero_zt(0); } // no warning
118+
void new_zt0(void) __arm_streaming { svzero_zt(0); }

clang/test/Sema/aarch64-sme-intrinsics/acle_sme_target.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@ void test_plus_sme(svbool_t pg, void *ptr) __arm_streaming __arm_inout("za") {
2222

2323
__attribute__((target("+sme")))
2424
void undefined(svbool_t pg, void *ptr) __arm_inout("za") {
25-
svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-warning {{builtin call has undefined behaviour when called from a non-streaming function}}
25+
svst1_ver_vnum_za64(0, 0, pg, ptr, 0); // expected-error {{builtin can only be called from a streaming function}}
2626
}

0 commit comments

Comments
 (0)