-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang][RISCV] Support norelax attribute for RISCV
#115981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-clang Author: Piyou Chen (BeMg) ChangesBase on riscv-non-isa/riscv-c-api-doc#94. This patch support the Full diff: https://github.com/llvm/llvm-project/pull/115981.diff 9 Files Affected:
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}}
|
|
@llvm/pr-subscribers-clang-codegen Author: Piyou Chen (BeMg) ChangesBase on riscv-non-isa/riscv-c-api-doc#94. This patch support the Full diff: https://github.com/llvm/llvm-project/pull/115981.diff 9 Files Affected:
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}}
|
|
cc @cyyself |
|
I disagree that this is a thing which should exist. It's solving the problem in the wrong place. |
Since a clean solution needs GLIBC update, I think this can be a workaround now for some generated IFUNC resolvers, such as target_clones or target_versions. |
|
Two comments:
|
I agree. I also changed my mind now through the discussion from the c-api-doc PR. |
|
Seem we don't support this attribute. |
Base on riscv-non-isa/riscv-c-api-doc#94.
This patch support the
norelaxattribute for RISC-V target in clang.