Skip to content

Commit 9dc14ca

Browse files
committed
[clang][RISCV] Support norelax attribute for RISCV
1 parent 37143fe commit 9dc14ca

File tree

9 files changed

+87
-0
lines changed

9 files changed

+87
-0
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3220,6 +3220,14 @@ def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr<TargetRISCV> {
32203220
let Documentation = [RISCVVectorCCDocs];
32213221
}
32223222

3223+
def RISCVNoRelax: DeclOrTypeAttr, TargetSpecificAttr<TargetRISCV> {
3224+
let Spellings = [CXX11<"riscv", "norelax">,
3225+
C23<"riscv", "norelax">,
3226+
Clang<"norelax">];
3227+
let Documentation = [RISCVNoRelaxDocs];
3228+
}
3229+
3230+
32233231
def Target : InheritableAttr {
32243232
let Spellings = [GCC<"target">];
32253233
let Args = [StringArgument<"featuresStr">];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5818,6 +5818,15 @@ them if they use them.
58185818
}];
58195819
}
58205820

5821+
def RISCVNoRelaxDocs : Documentation {
5822+
let Category = DocCatFunction;
5823+
let Content = [{
5824+
The ``riscv_norelax`` attribute can be applied to a function to disable the
5825+
relax optimization for that specific function.
5826+
}];
5827+
}
5828+
5829+
58215830
def PreferredNameDocs : Documentation {
58225831
let Category = DocCatDecl;
58235832
let Content = [{

clang/include/clang/Sema/SemaRISCV.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class SemaRISCV : public SemaBase {
4444
void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
4545
bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
4646
bool isValidFMVExtension(StringRef Ext);
47+
void handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL);
4748

4849
/// Indicate RISC-V vector builtin functions enabled or not.
4950
bool DeclareRVVBuiltins = false;

clang/lib/CodeGen/Targets/RISCV.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,11 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
599599
if (CGM.getCodeGenOpts().CFProtectionReturn)
600600
Fn->addFnAttr("hw-shadow-stack");
601601

602+
const auto *NoRelaxAttr = FD->getAttr<RISCVNoRelaxAttr>();
603+
604+
if (NoRelaxAttr)
605+
Fn->addFnAttr("norelax");
606+
602607
const auto *Attr = FD->getAttr<RISCVInterruptAttr>();
603608
if (!Attr)
604609
return;

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6911,6 +6911,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
69116911
case ParsedAttr::AT_RISCVVectorCC:
69126912
handleCallConvAttr(S, D, AL);
69136913
break;
6914+
case ParsedAttr::AT_RISCVNoRelax:
6915+
S.RISCV().handleRISCVNoRelaxAttr(S, D, AL);
6916+
break;
69146917
case ParsedAttr::AT_Suppress:
69156918
handleSuppressAttr(S, D, AL);
69166919
break;

clang/lib/Sema/SemaRISCV.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,6 +1494,17 @@ bool SemaRISCV::isValidFMVExtension(StringRef Ext) {
14941494
return -1 != RISCVISAInfo::getRISCVFeaturesBitsInfo(Ext).second;
14951495
}
14961496

1497+
void SemaRISCV::handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1498+
1499+
if (!isa<FunctionDecl>(D)) {
1500+
S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
1501+
<< AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;
1502+
return;
1503+
}
1504+
1505+
D->addAttr(::new (S.Context) RISCVNoRelaxAttr(S.Context, AL));
1506+
}
1507+
14971508
SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {}
14981509

14991510
} // namespace clang
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// REQUIRES: riscv-registered-target
2+
// RUN: %clang_cc1 -triple riscv64 \
3+
// RUN: -emit-llvm -o - %s | FileCheck %s
4+
5+
// CHECK-LABEL: define dso_local void @func1(
6+
// CHECK-SAME: ) #0 {
7+
// CHECK-NEXT: [[ENTRY:.*:]]
8+
// CHECK-NEXT: ret void
9+
//
10+
__attribute__((norelax)) void func1() {}
11+
12+
// CHECK-LABEL: define dso_local void @func2(
13+
// CHECK-SAME: ) #0 {
14+
// CHECK-NEXT: [[ENTRY:.*:]]
15+
// CHECK-NEXT: ret void
16+
//
17+
[[riscv::norelax]] void func2() {}
18+
19+
// CHECK: attributes #0 = { {{.*}} "norelax" {{.*}} }
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// REQUIRES: riscv-registered-target
2+
// RUN: %clang_cc1 -std=c++11 -triple riscv64 \
3+
// RUN: -emit-llvm -o - %s | FileCheck %s
4+
5+
// CHECK-LABEL: define dso_local void @_Z5func1v(
6+
// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
7+
// CHECK-NEXT: [[ENTRY:.*:]]
8+
// CHECK-NEXT: ret void
9+
//
10+
__attribute__((norelax)) void func1() {}
11+
12+
// CHECK-LABEL: define dso_local void @_Z5func2v(
13+
// CHECK-SAME: ) #[[ATTR0]] {
14+
// CHECK-NEXT: [[ENTRY:.*:]]
15+
// CHECK-NEXT: ret void
16+
//
17+
[[riscv::norelax]] void func2() {}
18+
19+
// CHECK: attributes #0 = { {{.*}} "norelax" {{.*}} }

clang/test/Sema/riscv-norelax.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// REQUIRES: riscv-registered-target
2+
// RUN: %clang_cc1 %s -triple riscv64 -verify
3+
4+
__attribute__((norelax)) int var; // expected-warning {{'norelax' attribute only applies to functions and methods}}
5+
6+
__attribute__((norelax)) void func() {}
7+
__attribute__((norelax(1))) void func_invalid(); // expected-error {{'norelax' attribute takes no arguments}}
8+
9+
[[riscv::norelax]] int var2; // expected-warning {{'norelax' attribute only applies to functions and methods}}
10+
11+
[[riscv::norelax]] void func2() {}
12+
[[riscv::norelax(1)]] void func_invalid2(); // expected-error {{'norelax' attribute takes no arguments}}

0 commit comments

Comments
 (0)