https://github.com/marykass-arm updated https://github.com/llvm/llvm-project/pull/159131
>From 035aafb13cff57bfd266c8266bbbbccebe4be685 Mon Sep 17 00:00:00 2001 From: Mary Kassayova <mary.kassay...@arm.com> Date: Tue, 16 Sep 2025 15:59:14 +0000 Subject: [PATCH 1/3] [Sema][AArch64] Emit error for mismatched VLs on streaming mode transitions --- .../clang/Basic/DiagnosticSemaKinds.td | 3 + clang/lib/Sema/SemaChecking.cpp | 28 ++++- ...h64-sme-streaming-nonstreaming-vl-checks.c | 110 ++++++++++++++++++ 3 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 409a8202d8a09..eec5047e56334 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3976,6 +3976,9 @@ def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning< "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different" " streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime">, InGroup<AArch64SMEAttributes>, DefaultIgnore; +def err_sme_streaming_transition_vl_mismatch : Error< + "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different" + " streaming-mode is invalid because the non-streaming vector length (%1) and streaming vector length (%2) differ">; def warn_sme_locally_streaming_has_vl_args_returns : Warning< "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a locally streaming function is undefined" " behaviour when the streaming and non-streaming vector lengths are different at runtime">, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 05ee51913aec1..c031d74596fa8 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3756,6 +3756,8 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, // If the call requires a streaming-mode change and has scalable vector // arguments or return values, then warn the user that the streaming and // non-streaming vector lengths may be different. + // When both streaming and non-streaming vector lengths are defined and + // mismatched, produce an error. const auto *CallerFD = dyn_cast<FunctionDecl>(CurContext); if (CallerFD && (!FD || !FD->getBuiltinID()) && (IsScalableArg || IsScalableRet)) { @@ -3768,12 +3770,26 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, if (!IsCalleeStreamingCompatible && (CallerFnType == SemaARM::ArmStreamingCompatible || ((CallerFnType == SemaARM::ArmStreaming) ^ IsCalleeStreaming))) { - if (IsScalableArg) - Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) - << /*IsArg=*/true; - if (IsScalableRet) - Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) - << /*IsArg=*/false; + const LangOptions &LO = getLangOpts(); + auto VL = LO.VScaleMin * 128; + auto SVL = LO.VScaleStreamingMin * 128; + + if (IsScalableArg) { + if (VL && SVL && VL != SVL) + Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch) + << /*IsArg=*/true << VL << SVL; + else + Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) + << /*IsArg=*/true; + } + if (IsScalableRet) { + if (VL && SVL && VL != SVL) + Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch) + << /*IsArg=*/false << VL << SVL; + else + Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) + << /*IsArg=*/false; + } } } diff --git a/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c b/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c new file mode 100644 index 0000000000000..78473df82d309 --- /dev/null +++ b/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c @@ -0,0 +1,110 @@ +// Case 1: No vscale flags — should only produce warnings +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sme -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify=expected-noflags %s + +// Case 2: Explicit mismatch in vscale flags — should produce errors +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sme -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -mvscale-min=1 -mvscale-max=1 -mvscale-streaming-min=2 -mvscale-streaming-max=2 -verify=expected-flags %s + +void sme_streaming_with_vl_arg(__SVInt8_t a) __arm_streaming { } + +__SVInt8_t sme_streaming_returns_vl(void) __arm_streaming { __SVInt8_t r; return r; } + +void sme_streaming_compatible_with_vl_arg(__SVInt8_t a) __arm_streaming_compatible { } + +__SVInt8_t sme_streaming_compatible_returns_vl(void) __arm_streaming_compatible { __SVInt8_t r; return r; } + +void sme_no_streaming_with_vl_arg(__SVInt8_t a) { } + +__SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; } + + +void sme_no_streaming_calling_streaming_with_vl_args() { + __SVInt8_t a; + // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + sme_streaming_with_vl_arg(a); +} + +void sme_no_streaming_calling_streaming_with_return_vl() { + // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + __SVInt8_t r = sme_streaming_returns_vl(); +} + +void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming { + __SVInt8_t a; + // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + sme_no_streaming_with_vl_arg(a); +} + +void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming { + // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + __SVInt8_t r = sme_no_streaming_returns_vl(); +} + +void sme_streaming_compatible_calling_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { + // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + sme_streaming_with_vl_arg(arg); +} + +void sme_streaming_compatible_calling_sme_streaming_return_vl(void) __arm_streaming_compatible { + // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + __SVInt8_t r = sme_streaming_returns_vl(); +} + +void sme_streaming_compatible_calling_no_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { + // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + sme_no_streaming_with_vl_arg(arg); +} + +void sme_streaming_compatible_calling_no_sme_streaming_return_vl(void) __arm_streaming_compatible { + // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + __SVInt8_t r = sme_no_streaming_returns_vl(); +} + +void sme_streaming_calling_streaming_with_vl_args(__SVInt8_t a) __arm_streaming { + sme_streaming_with_vl_arg(a); +} + +void sme_streaming_calling_streaming_with_return_vl(void) __arm_streaming { + __SVInt8_t r = sme_streaming_returns_vl(); +} + +void sme_streaming_calling_streaming_compatible_with_vl_args(__SVInt8_t a) __arm_streaming { + sme_streaming_compatible_with_vl_arg(a); +} + +void sme_streaming_calling_streaming_compatible_with_return_vl(void) __arm_streaming { + __SVInt8_t r = sme_streaming_compatible_returns_vl(); +} + +void sme_no_streaming_calling_streaming_compatible_with_vl_args() { + __SVInt8_t a; + sme_streaming_compatible_with_vl_arg(a); +} + +void sme_no_streaming_calling_streaming_compatible_with_return_vl() { + __SVInt8_t r = sme_streaming_compatible_returns_vl(); +} + +void sme_no_streaming_calling_non_streaming_compatible_with_vl_args() { + __SVInt8_t a; + sme_no_streaming_with_vl_arg(a); +} + +void sme_no_streaming_calling_non_streaming_compatible_with_return_vl() { + __SVInt8_t r = sme_no_streaming_returns_vl(); +} + +void sme_streaming_compatible_calling_streaming_compatible_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { + sme_streaming_compatible_with_vl_arg(arg); +} + +void sme_streaming_compatible_calling_streaming_compatible_with_return_vl(void) __arm_streaming_compatible { + __SVInt8_t r = sme_streaming_compatible_returns_vl(); +} >From a933ca96f231756e28bf7fe6df6adb09f0b58258 Mon Sep 17 00:00:00 2001 From: Mary Kassayova <mary.kassay...@arm.com> Date: Wed, 17 Sep 2025 15:48:17 +0000 Subject: [PATCH 2/3] Removed error for SC callers, addressed other comments --- .../clang/Basic/DiagnosticSemaKinds.td | 6 ++-- clang/lib/Sema/SemaChecking.cpp | 30 +++++++++---------- ...h64-sme-streaming-nonstreaming-vl-checks.c | 19 ++++++------ 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index eec5047e56334..56b73f4cc355b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3976,13 +3976,13 @@ def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning< "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different" " streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime">, InGroup<AArch64SMEAttributes>, DefaultIgnore; -def err_sme_streaming_transition_vl_mismatch : Error< - "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different" - " streaming-mode is invalid because the non-streaming vector length (%1) and streaming vector length (%2) differ">; def warn_sme_locally_streaming_has_vl_args_returns : Warning< "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a locally streaming function is undefined" " behaviour when the streaming and non-streaming vector lengths are different at runtime">, InGroup<AArch64SMEAttributes>, DefaultIgnore; +def err_sme_streaming_transition_vl_mismatch : Error< + "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different" + " streaming-mode is invalid because the non-streaming vector length (%1 bit) and streaming vector length (%2 bit) differ">; def err_conflicting_attributes_arm_agnostic : Error< "__arm_agnostic(\"sme_za_state\") cannot share ZA state with its caller">; def err_conflicting_attributes_arm_state : Error< diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index c031d74596fa8..f3201a692f4c0 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3771,25 +3771,25 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, (CallerFnType == SemaARM::ArmStreamingCompatible || ((CallerFnType == SemaARM::ArmStreaming) ^ IsCalleeStreaming))) { const LangOptions &LO = getLangOpts(); - auto VL = LO.VScaleMin * 128; - auto SVL = LO.VScaleStreamingMin * 128; + unsigned VL = LO.VScaleMin * 128; + unsigned SVL = LO.VScaleStreamingMin * 128; - if (IsScalableArg) { - if (VL && SVL && VL != SVL) - Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch) - << /*IsArg=*/true << VL << SVL; - else - Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) - << /*IsArg=*/true; - } - if (IsScalableRet) { - if (VL && SVL && VL != SVL) + bool IsVLError = CallerFnType != SemaARM::ArmStreamingCompatible && + (VL && SVL && VL != SVL); + + auto EmitDiag = [&](bool IsArg) { + if (IsVLError) Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch) - << /*IsArg=*/false << VL << SVL; + << IsArg << VL << SVL; else Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) - << /*IsArg=*/false; - } + << IsArg; + }; + + if (IsScalableArg) + EmitDiag(true); + if (IsScalableRet) + EmitDiag(false); } } diff --git a/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c b/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c index 78473df82d309..e9639ecbdfef3 100644 --- a/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c +++ b/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c @@ -1,7 +1,8 @@ // Case 1: No vscale flags — should only produce warnings // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sme -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -verify=expected-noflags %s -// Case 2: Explicit mismatch in vscale flags — should produce errors +// Case 2: Explicit mismatch in vscale flags — should produce errors for +// streaming and non-streaming callers // RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +bf16 -target-feature +sme -target-feature +sme2 -target-feature +sve -Waarch64-sme-attributes -fsyntax-only -mvscale-min=1 -mvscale-max=1 -mvscale-streaming-min=2 -mvscale-streaming-max=2 -verify=expected-flags %s void sme_streaming_with_vl_arg(__SVInt8_t a) __arm_streaming { } @@ -20,50 +21,50 @@ __SVInt8_t sme_no_streaming_returns_vl(void) { __SVInt8_t r; return r; } void sme_no_streaming_calling_streaming_with_vl_args() { __SVInt8_t a; // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128 bit) and streaming vector length (256 bit) differ}} sme_streaming_with_vl_arg(a); } void sme_no_streaming_calling_streaming_with_return_vl() { // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128 bit) and streaming vector length (256 bit) differ}} __SVInt8_t r = sme_streaming_returns_vl(); } void sme_streaming_calling_non_streaming_with_vl_args(void) __arm_streaming { __SVInt8_t a; // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128 bit) and streaming vector length (256 bit) differ}} sme_no_streaming_with_vl_arg(a); } void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming { // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128 bit) and streaming vector length (256 bit) differ}} __SVInt8_t r = sme_no_streaming_returns_vl(); } void sme_streaming_compatible_calling_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + // expected-flags-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} sme_streaming_with_vl_arg(arg); } void sme_streaming_compatible_calling_sme_streaming_return_vl(void) __arm_streaming_compatible { // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + // expected-flags-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} __SVInt8_t r = sme_streaming_returns_vl(); } void sme_streaming_compatible_calling_no_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-error@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + // expected-flags-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} sme_no_streaming_with_vl_arg(arg); } void sme_streaming_compatible_calling_no_sme_streaming_return_vl(void) __arm_streaming_compatible { // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-error@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is invalid because the non-streaming vector length (128) and streaming vector length (256) differ}} + // expected-flags-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} __SVInt8_t r = sme_no_streaming_returns_vl(); } >From 7bfa51bb0e7adb2f81f019c4c18a5bee7adf77a0 Mon Sep 17 00:00:00 2001 From: Mary Kassayova <mary.kassay...@arm.com> Date: Thu, 18 Sep 2025 12:16:15 +0000 Subject: [PATCH 3/3] Added SC warning --- .../include/clang/Basic/DiagnosticSemaKinds.td | 5 +++++ clang/lib/Sema/SemaChecking.cpp | 17 +++++++++++------ ...rch64-sme-streaming-nonstreaming-vl-checks.c | 8 ++++---- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 56b73f4cc355b..0b086c22f108b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3980,6 +3980,11 @@ def warn_sme_locally_streaming_has_vl_args_returns : Warning< "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a locally streaming function is undefined" " behaviour when the streaming and non-streaming vector lengths are different at runtime">, InGroup<AArch64SMEAttributes>, DefaultIgnore; +def warn_sme_streaming_compatible_vl_mismatch : Warning< + "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a streaming-compatible function" + " is undefined behaviour when the callee is in a different streaming mode because the streaming vector" + " length (%1 bit) and non-streaming vector length (%2 bit) differ">, + InGroup<AArch64SMEAttributes>, DefaultIgnore; def err_sme_streaming_transition_vl_mismatch : Error< "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different" " streaming-mode is invalid because the non-streaming vector length (%1 bit) and streaming vector length (%2 bit) differ">; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f3201a692f4c0..e60b28a249e4a 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3774,14 +3774,19 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, unsigned VL = LO.VScaleMin * 128; unsigned SVL = LO.VScaleStreamingMin * 128; - bool IsVLError = CallerFnType != SemaARM::ArmStreamingCompatible && - (VL && SVL && VL != SVL); + bool IsVLMismatch = VL && SVL && VL != SVL; auto EmitDiag = [&](bool IsArg) { - if (IsVLError) - Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch) - << IsArg << VL << SVL; - else + if (IsVLMismatch) { + if (CallerFnType == SemaARM::ArmStreamingCompatible) + // Emit warning for streaming-compatible callers + Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch) + << IsArg << VL << SVL; + else + // Emit error otherwise + Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch) + << IsArg << VL << SVL; + } else Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) << IsArg; }; diff --git a/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c b/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c index e9639ecbdfef3..24d76c5930653 100644 --- a/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c +++ b/clang/test/Sema/aarch64-sme-streaming-nonstreaming-vl-checks.c @@ -46,25 +46,25 @@ void sme_streaming_calling_non_streaming_with_return_vl(void) __arm_streaming { void sme_streaming_compatible_calling_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-warning@+1 {{passing a VL-dependent argument to a streaming-compatible function is undefined behaviour when the callee is in a different streaming mode because the streaming vector length (128 bit) and non-streaming vector length (256 bit) differ}} sme_streaming_with_vl_arg(arg); } void sme_streaming_compatible_calling_sme_streaming_return_vl(void) __arm_streaming_compatible { // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-warning@+1 {{returning a VL-dependent argument from a streaming-compatible function is undefined behaviour when the callee is in a different streaming mode because the streaming vector length (128 bit) and non-streaming vector length (256 bit) differ}} __SVInt8_t r = sme_streaming_returns_vl(); } void sme_streaming_compatible_calling_no_streaming_with_vl_args(__SVInt8_t arg) __arm_streaming_compatible { // expected-noflags-warning@+2 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-warning@+1 {{passing a VL-dependent argument to a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-warning@+1 {{passing a VL-dependent argument to a streaming-compatible function is undefined behaviour when the callee is in a different streaming mode because the streaming vector length (128 bit) and non-streaming vector length (256 bit) differ}} sme_no_streaming_with_vl_arg(arg); } void sme_streaming_compatible_calling_no_sme_streaming_return_vl(void) __arm_streaming_compatible { // expected-noflags-warning@+2 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} - // expected-flags-warning@+1 {{returning a VL-dependent argument from a function with a different streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime}} + // expected-flags-warning@+1 {{returning a VL-dependent argument from a streaming-compatible function is undefined behaviour when the callee is in a different streaming mode because the streaming vector length (128 bit) and non-streaming vector length (256 bit) differ}} __SVInt8_t r = sme_no_streaming_returns_vl(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits