[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