Skip to content

Commit 325b6b4

Browse files
- Split pseudo into VGSavePseudo & VGRestorePseudo.
- Check for noexcept or nothrow when emitting Clang errors.
1 parent 53520f7 commit 325b6b4

9 files changed

+126
-71
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,12 +3740,6 @@ def warn_gnu_inline_cplusplus_without_extern : Warning<
37403740
"'gnu_inline' attribute without 'extern' in C++ treated as externally"
37413741
" available, this changed in Clang 10">,
37423742
InGroup<DiagGroup<"gnu-inline-cpp-without-extern">>;
3743-
def warn_sme_streaming_mode_change_no_sve : Warning<
3744-
"function requires a streaming-mode change, unwinding is not possible without 'sve'">,
3745-
InGroup<AArch64SMEAttributes>;
3746-
def warn_sme_locally_streaming_no_sve : Warning<
3747-
"unwinding is not possible for locally-streaming functions without 'sve'">,
3748-
InGroup<AArch64SMEAttributes>;
37493743
def err_attribute_vecreturn_only_vector_member : Error<
37503744
"the vecreturn attribute can only be used on a class or structure with one member, which must be a vector">;
37513745
def err_attribute_vecreturn_only_pod_record : Error<
@@ -3782,6 +3776,12 @@ def err_conflicting_attributes_arm_state : Error<
37823776
"conflicting attributes for state '%0'">;
37833777
def err_sme_streaming_cannot_be_multiversioned : Error<
37843778
"streaming function cannot be multi-versioned">;
3779+
def err_sme_streaming_mode_change_no_sve : Error<
3780+
"function requires a streaming-mode change, unwinding is not possible without 'sve'. "
3781+
"Consider marking this function as 'noexcept' or '__attribute__((nothrow))'">;
3782+
def err_sme_locally_streaming_no_sve : Error<
3783+
"unwinding is not possible for locally-streaming functions without 'sve'. "
3784+
"Consider marking this function as 'noexcept' or '__attribute__((nothrow))'">;
37853785
def err_unknown_arm_state : Error<
37863786
"unknown state '%0'">;
37873787
def err_missing_arm_state : Error<

clang/lib/Sema/SemaChecking.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3920,17 +3920,22 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto,
39203920
ExtInfo.AArch64SMEAttributes &
39213921
FunctionType::SME_PStateSMCompatibleMask;
39223922
SemaARM::ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD);
3923+
bool NoThrow =
3924+
!getLangOpts().Exceptions ||
3925+
(Proto && !isUnresolvedExceptionSpec(Proto->getExceptionSpecType()) &&
3926+
Proto->isNothrow()) ||
3927+
(FD && FD->hasAttr<NoThrowAttr>());
39233928

39243929
// SME functions may require SVE to be available for unwinding, as the
39253930
// value of VG needs to be preserved across streaming-mode changes.
3926-
if (!Context.getTargetInfo().hasFeature("sve")) {
3931+
if (!NoThrow && !Context.getTargetInfo().hasFeature("sve")) {
39273932
if (CallerFD->hasAttr<ArmLocallyStreamingAttr>())
3928-
Diag(Loc, diag::warn_sme_locally_streaming_no_sve);
3933+
Diag(Loc, diag::err_sme_locally_streaming_no_sve);
39293934

39303935
if ((CallerFnType == SemaARM::ArmStreaming ||
39313936
CallerFnType == SemaARM::ArmStreamingCompatible) &&
39323937
(!IsCalleeStreaming && !IsCalleeStreamingCompatible))
3933-
Diag(Loc, diag::warn_sme_streaming_mode_change_no_sve);
3938+
Diag(Loc, diag::err_sme_streaming_mode_change_no_sve);
39343939
}
39353940

39363941
// If the call requires a streaming-mode change and has scalable vector

clang/test/Sema/aarch64-sme-func-attrs-without-target-feature.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void non_streaming_def(void (*streaming_fn_ptr)(void) __arm_streaming,
3838
void streaming_compatible_def2(void (*streaming_fn_ptr)(void) __arm_streaming,
3939
void (*streaming_compatible_fn_ptr)(void) __arm_streaming_compatible)
4040
__arm_streaming_compatible {
41-
non_streaming_decl(); // expected-warning {{function requires a streaming-mode change, unwinding is not possible without 'sve'}}
41+
non_streaming_decl();
4242
streaming_compatible_decl(); // OK
4343
streaming_compatible_fn_ptr(); // OK
4444
streaming_decl(); // expected-error {{call to a streaming function requires 'sme'}}

clang/test/Sema/aarch64-streaming-mode-changes-no-sve.c

Lines changed: 0 additions & 45 deletions
This file was deleted.
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme \
2+
// RUN: -target-feature -sve -fexceptions -DNO_THROW -fsyntax-only -verify %s
3+
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme \
4+
// RUN: -target-feature -sve -fexceptions -DNO_EXCEPT -fsyntax-only -verify %s
5+
// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme \
6+
// RUN: -target-feature -sve -DNO_EXCEPT_FLAG -fsyntax-only -verify %s
7+
8+
// REQUIRES: aarch64-registered-target
9+
10+
#include "arm_sme.h"
11+
12+
int non_streaming_decl(void);
13+
int streaming_decl(void) __arm_streaming;
14+
int streaming_compatible_decl(void) __arm_streaming_compatible;
15+
16+
#ifdef NO_THROW
17+
#define NOTHROW_ATTR __attribute__((__nothrow__))
18+
#else
19+
#define NOTHROW_ATTR
20+
#endif
21+
22+
#ifdef NO_EXCEPT
23+
#define NOEXCEPT_ATTR noexcept
24+
#else
25+
#define NOEXCEPT_ATTR
26+
#endif
27+
28+
#ifdef NO_EXCEPT_FLAG
29+
// expected-no-diagnostics
30+
#endif
31+
32+
NOTHROW_ATTR int nothrow_non_streaming_decl(void) NOEXCEPT_ATTR;
33+
NOTHROW_ATTR int nothrow_streaming_decl(void) NOEXCEPT_ATTR;
34+
NOTHROW_ATTR int nothrow_streaming_compatible_decl(void) NOEXCEPT_ATTR;
35+
36+
// Streaming-mode changes which would require spilling VG if unwinding is possible, unsupported without SVE
37+
38+
int streaming_caller_no_sve(void) __arm_streaming {
39+
#ifndef NO_EXCEPT_FLAG
40+
// expected-error@+2 {{function requires a streaming-mode change, unwinding is not possible without 'sve'. Consider marking this function as 'noexcept' or '__attribute__((nothrow))'}}
41+
#endif
42+
return non_streaming_decl();
43+
}
44+
45+
int sc_caller_non_streaming_callee(void) __arm_streaming_compatible {
46+
#ifndef NO_EXCEPT_FLAG
47+
// expected-error@+2 {{function requires a streaming-mode change, unwinding is not possible without 'sve'. Consider marking this function as 'noexcept' or '__attribute__((nothrow))'}}
48+
#endif
49+
return non_streaming_decl();
50+
}
51+
52+
__arm_locally_streaming int locally_streaming_no_sve(void) {
53+
#ifndef NO_EXCEPT_FLAG
54+
// expected-error@+2 {{unwinding is not possible for locally-streaming functions without 'sve'. Consider marking this function as 'noexcept' or '__attribute__((nothrow))'}}
55+
#endif
56+
return streaming_decl();
57+
}
58+
59+
// Nothrow / noexcept attribute on callee - warnings not expected
60+
61+
int nothrow_streaming_caller_no_sve(void) __arm_streaming {
62+
return nothrow_non_streaming_decl();
63+
}
64+
65+
int nothrow_sc_caller_non_streaming_callee(void) __arm_streaming_compatible {
66+
return nothrow_non_streaming_decl();
67+
}
68+
69+
__arm_locally_streaming int nothrow_locally_streaming_no_sve(void) {
70+
return nothrow_streaming_decl();
71+
}
72+
73+
// No warnings expected, even if unwinding is possible
74+
75+
int normal_caller_streaming_callee(void) {
76+
return streaming_decl();
77+
}
78+
79+
int normal_caller_streaming_compatible_callee(void) {
80+
return streaming_compatible_decl();
81+
}
82+
83+
int sc_caller_streaming_callee(void) __arm_streaming_compatible {
84+
return streaming_decl();
85+
}
86+
87+
int sc_caller_sc_callee(void) __arm_streaming_compatible {
88+
return streaming_compatible_decl();
89+
}

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,8 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
15991599
case AArch64::COALESCER_BARRIER_FPR128:
16001600
MI.eraseFromParent();
16011601
return true;
1602-
case AArch64::VGUnwindInfoPseudo: {
1602+
case AArch64::VGSavePseudo:
1603+
case AArch64::VGRestorePseudo: {
16031604
MachineFunction &MF = *MBB.getParent();
16041605
SMEAttrs FuncAttrs(MF.getFunction());
16051606
bool LocallyStreaming =
@@ -1617,7 +1618,8 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
16171618
const TargetSubtargetInfo &STI = MF.getSubtarget();
16181619
const TargetInstrInfo &TII = *STI.getInstrInfo();
16191620
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
1620-
if (MI.getOperand(0).getImm() == 1) {
1621+
1622+
if (Opcode == AArch64::VGSavePseudo) {
16211623
// This pseudo has been inserted after a streaming-mode change
16221624
// to save the streaming value of VG before a call.
16231625
// Calculate and emit the CFI offset using VGFrameIdx.

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,7 +2489,8 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
24892489
case AArch64ISD::FIRST_NUMBER:
24902490
break;
24912491
MAKE_CASE(AArch64ISD::COALESCER_BARRIER)
2492-
MAKE_CASE(AArch64ISD::VG_UNWIND)
2492+
MAKE_CASE(AArch64ISD::VG_SAVE)
2493+
MAKE_CASE(AArch64ISD::VG_RESTORE)
24932494
MAKE_CASE(AArch64ISD::SMSTART)
24942495
MAKE_CASE(AArch64ISD::SMSTOP)
24952496
MAKE_CASE(AArch64ISD::RESTORE_ZA)
@@ -8513,9 +8514,8 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
85138514
if (RequiresSMChange) {
85148515

85158516
if (Subtarget->hasSVE()) {
8516-
Chain = DAG.getNode(
8517-
AArch64ISD::VG_UNWIND, DL, DAG.getVTList(MVT::Other, MVT::Glue),
8518-
{Chain, DAG.getTargetConstant(/*Save*/ 1, DL, MVT::i64)});
8517+
Chain = DAG.getNode(AArch64ISD::VG_SAVE, DL,
8518+
DAG.getVTList(MVT::Other, MVT::Glue), Chain);
85198519
InGlue = Chain.getValue(1);
85208520
}
85218521

@@ -8700,9 +8700,9 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
87008700
InGlue = Result.getValue(1);
87018701

87028702
if (Subtarget->hasSVE())
8703-
Result = DAG.getNode(
8704-
AArch64ISD::VG_UNWIND, DL, DAG.getVTList(MVT::Other, MVT::Glue),
8705-
{Result, DAG.getTargetConstant(/*Restore*/ 0, DL, MVT::i64), InGlue});
8703+
Result =
8704+
DAG.getNode(AArch64ISD::VG_RESTORE, DL,
8705+
DAG.getVTList(MVT::Other, MVT::Glue), {Result, InGlue});
87068706
}
87078707

87088708
if (CallerAttrs.requiresEnablingZAAfterCall(CalleeAttrs))

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ enum NodeType : unsigned {
7070

7171
COALESCER_BARRIER,
7272

73-
VG_UNWIND,
73+
VG_SAVE,
74+
VG_RESTORE,
7475

7576
SMSTART,
7677
SMSTOP,

llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ def AArch64_save_zt : SDNode<"AArch64ISD::SAVE_ZT", SDTypeProfile<0, 2,
3131
def AArch64CoalescerBarrier
3232
: SDNode<"AArch64ISD::COALESCER_BARRIER", SDTypeProfile<1, 1, []>, [SDNPOptInGlue, SDNPOutGlue]>;
3333

34-
def AArch64VGUnwind : SDNode<"AArch64ISD::VG_UNWIND", SDTypeProfile<0, 1, []>,
35-
[SDNPHasChain, SDNPSideEffect, SDNPOptInGlue, SDNPOutGlue]>;
34+
def AArch64VGSave : SDNode<"AArch64ISD::VG_SAVE", SDTypeProfile<0, 0, []>,
35+
[SDNPHasChain, SDNPSideEffect, SDNPOptInGlue, SDNPOutGlue]>;
36+
37+
def AArch64VGRestore : SDNode<"AArch64ISD::VG_RESTORE", SDTypeProfile<0, 0, []>,
38+
[SDNPHasChain, SDNPSideEffect, SDNPOptInGlue, SDNPOutGlue]>;
3639

3740
//===----------------------------------------------------------------------===//
3841
// Instruction naming conventions.
@@ -227,11 +230,11 @@ def : Pat<(AArch64_smstop (i32 svcr_op:$pstate), (i64 /*AArch64SME::Always*/0)),
227230
// Pseudo to insert cfi_offset/cfi_restore instructions. Used to save or restore
228231
// the streaming value of VG around streaming-mode changes in locally-streaming
229232
// functions.
230-
def VGUnwindInfoPseudo :
231-
Pseudo<(outs), (ins timm0_1:$save_restore), []>, Sched<[]>;
233+
def VGSavePseudo : Pseudo<(outs), (ins), []>, Sched<[]>;
234+
def : Pat<(AArch64VGSave), (VGSavePseudo)>;
232235

233-
def : Pat<(AArch64VGUnwind (i64 timm0_1:$save_restore)),
234-
(VGUnwindInfoPseudo timm0_1:$save_restore)>;
236+
def VGRestorePseudo : Pseudo<(outs), (ins), []>, Sched<[]>;
237+
def : Pat<(AArch64VGRestore), (VGRestorePseudo)>;
235238

236239
//===----------------------------------------------------------------------===//
237240
// SME2 Instructions

0 commit comments

Comments
 (0)