[clang] [clang][RISCV] Support `norelax` attribute for RISCV (PR #115981)
Piyou Chen via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 12 19:09:24 PST 2024
https://github.com/BeMg created https://github.com/llvm/llvm-project/pull/115981
Base on https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94.
This patch support the `norelax` attribute for RISC-V target in clang.
>From 9dc14ca1e5d026c05390c728c9512994e05d8be7 Mon Sep 17 00:00:00 2001
From: Piyou Chen <piyou.chen at sifive.com>
Date: Mon, 11 Nov 2024 02:43:35 -0800
Subject: [PATCH] [clang][RISCV] Support `norelax` attribute for RISCV
---
clang/include/clang/Basic/Attr.td | 8 ++++++++
clang/include/clang/Basic/AttrDocs.td | 9 +++++++++
clang/include/clang/Sema/SemaRISCV.h | 1 +
clang/lib/CodeGen/Targets/RISCV.cpp | 5 +++++
clang/lib/Sema/SemaDeclAttr.cpp | 3 +++
clang/lib/Sema/SemaRISCV.cpp | 11 +++++++++++
clang/test/CodeGen/RISCV/riscv-norelax.c | 19 +++++++++++++++++++
clang/test/CodeGen/RISCV/riscv-norelax.cpp | 19 +++++++++++++++++++
clang/test/Sema/riscv-norelax.c | 12 ++++++++++++
9 files changed, 87 insertions(+)
create mode 100644 clang/test/CodeGen/RISCV/riscv-norelax.c
create mode 100644 clang/test/CodeGen/RISCV/riscv-norelax.cpp
create mode 100644 clang/test/Sema/riscv-norelax.c
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index a631e81d40aa68..74ba9c7a730066 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -3220,6 +3220,14 @@ def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr<TargetRISCV> {
let Documentation = [RISCVVectorCCDocs];
}
+def RISCVNoRelax: DeclOrTypeAttr, TargetSpecificAttr<TargetRISCV> {
+ let Spellings = [CXX11<"riscv", "norelax">,
+ C23<"riscv", "norelax">,
+ Clang<"norelax">];
+ let Documentation = [RISCVNoRelaxDocs];
+}
+
+
def Target : InheritableAttr {
let Spellings = [GCC<"target">];
let Args = [StringArgument<"featuresStr">];
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index b64dbef6332e6a..3df8af853b8665 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -5818,6 +5818,15 @@ them if they use them.
}];
}
+def RISCVNoRelaxDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``riscv_norelax`` attribute can be applied to a function to disable the
+relax optimization for that specific function.
+ }];
+}
+
+
def PreferredNameDocs : Documentation {
let Category = DocCatDecl;
let Content = [{
diff --git a/clang/include/clang/Sema/SemaRISCV.h b/clang/include/clang/Sema/SemaRISCV.h
index d7f17797283b86..51d6b8540b80a8 100644
--- a/clang/include/clang/Sema/SemaRISCV.h
+++ b/clang/include/clang/Sema/SemaRISCV.h
@@ -44,6 +44,7 @@ class SemaRISCV : public SemaBase {
void handleInterruptAttr(Decl *D, const ParsedAttr &AL);
bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName);
bool isValidFMVExtension(StringRef Ext);
+ void handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL);
/// Indicate RISC-V vector builtin functions enabled or not.
bool DeclareRVVBuiltins = false;
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index b04e436c665f52..d982fb4f83e907 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -599,6 +599,11 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo {
if (CGM.getCodeGenOpts().CFProtectionReturn)
Fn->addFnAttr("hw-shadow-stack");
+ const auto *NoRelaxAttr = FD->getAttr<RISCVNoRelaxAttr>();
+
+ if (NoRelaxAttr)
+ Fn->addFnAttr("norelax");
+
const auto *Attr = FD->getAttr<RISCVInterruptAttr>();
if (!Attr)
return;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index d05d326178e1b8..7045e765cf9fa6 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6911,6 +6911,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_RISCVVectorCC:
handleCallConvAttr(S, D, AL);
break;
+ case ParsedAttr::AT_RISCVNoRelax:
+ S.RISCV().handleRISCVNoRelaxAttr(S, D, AL);
+ break;
case ParsedAttr::AT_Suppress:
handleSuppressAttr(S, D, AL);
break;
diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp
index 163f7129a7b42b..86b7539b0c80d2 100644
--- a/clang/lib/Sema/SemaRISCV.cpp
+++ b/clang/lib/Sema/SemaRISCV.cpp
@@ -1494,6 +1494,17 @@ bool SemaRISCV::isValidFMVExtension(StringRef Ext) {
return -1 != RISCVISAInfo::getRISCVFeaturesBitsInfo(Ext).second;
}
+void SemaRISCV::handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+
+ if (!isa<FunctionDecl>(D)) {
+ S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
+ << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;
+ return;
+ }
+
+ D->addAttr(::new (S.Context) RISCVNoRelaxAttr(S.Context, AL));
+}
+
SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {}
} // namespace clang
diff --git a/clang/test/CodeGen/RISCV/riscv-norelax.c b/clang/test/CodeGen/RISCV/riscv-norelax.c
new file mode 100644
index 00000000000000..e9a2db1c05aae7
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-norelax.c
@@ -0,0 +1,19 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define dso_local void @func1(
+// CHECK-SAME: ) #0 {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+__attribute__((norelax)) void func1() {}
+
+// CHECK-LABEL: define dso_local void @func2(
+// CHECK-SAME: ) #0 {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+[[riscv::norelax]] void func2() {}
+
+// CHECK: attributes #0 = { {{.*}} "norelax" {{.*}} }
diff --git a/clang/test/CodeGen/RISCV/riscv-norelax.cpp b/clang/test/CodeGen/RISCV/riscv-norelax.cpp
new file mode 100644
index 00000000000000..5c31efabdd5ed7
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/riscv-norelax.cpp
@@ -0,0 +1,19 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -std=c++11 -triple riscv64 \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define dso_local void @_Z5func1v(
+// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+__attribute__((norelax)) void func1() {}
+
+// CHECK-LABEL: define dso_local void @_Z5func2v(
+// CHECK-SAME: ) #[[ATTR0]] {
+// CHECK-NEXT: [[ENTRY:.*:]]
+// CHECK-NEXT: ret void
+//
+[[riscv::norelax]] void func2() {}
+
+// CHECK: attributes #0 = { {{.*}} "norelax" {{.*}} }
diff --git a/clang/test/Sema/riscv-norelax.c b/clang/test/Sema/riscv-norelax.c
new file mode 100644
index 00000000000000..9337a57a563d6d
--- /dev/null
+++ b/clang/test/Sema/riscv-norelax.c
@@ -0,0 +1,12 @@
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 %s -triple riscv64 -verify
+
+__attribute__((norelax)) int var; // expected-warning {{'norelax' attribute only applies to functions and methods}}
+
+__attribute__((norelax)) void func() {}
+__attribute__((norelax(1))) void func_invalid(); // expected-error {{'norelax' attribute takes no arguments}}
+
+[[riscv::norelax]] int var2; // expected-warning {{'norelax' attribute only applies to functions and methods}}
+
+[[riscv::norelax]] void func2() {}
+[[riscv::norelax(1)]] void func_invalid2(); // expected-error {{'norelax' attribute takes no arguments}}
More information about the cfe-commits
mailing list