[clang] [llvm] [RISCV] Teach .option arch to support experimental extensions. (PR #89727)

Yeting Kuo via llvm-commits llvm-commits at lists.llvm.org
Sat May 4 17:27:23 PDT 2024


https://github.com/yetingk updated https://github.com/llvm/llvm-project/pull/89727

>From a43014cf3daa1b0fd9092bfe41da979205ba64aa Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 23 Apr 2024 02:16:04 -0700
Subject: [PATCH 1/6] [RISCV] Teach .option arch to support experimental
 extensions.

Previously .option arch denied extenions are not belongs to RISC-V features. But
experimental features have experimental- prefix, so .option arch can not
serve for experimental extension.
This patch uses the features of extensions to identify extension
existance.
---
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 7 ++++---
 llvm/test/MC/RISCV/option-arch.s                   | 9 ++++++++-
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 3f4a73ad89bf8a..80ff70f1095f4c 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2824,8 +2824,9 @@ bool RISCVAsmParser::parseDirectiveOption() {
         break;
       }
 
-      auto Ext = llvm::lower_bound(RISCVFeatureKV, Arch);
-      if (Ext == std::end(RISCVFeatureKV) || StringRef(Ext->Key) != Arch ||
+      std::string &&Feature = RISCVISAInfo::getTargetFeatureForExtension(Arch);
+      auto Ext = llvm::lower_bound(RISCVFeatureKV, Feature);
+      if (Ext == std::end(RISCVFeatureKV) || StringRef(Ext->Key) != Feature ||
           !RISCVISAInfo::isSupportedExtension(Arch)) {
         if (isDigit(Arch.back()))
           return Error(
@@ -2834,7 +2835,7 @@ bool RISCVAsmParser::parseDirectiveOption() {
         return Error(Loc, "unknown extension feature");
       }
 
-      Args.emplace_back(Type, Ext->Key);
+      Args.emplace_back(Type, Arch.str());
 
       if (Type == RISCVOptionArchArgType::Plus) {
         FeatureBitset OldFeatureBits = STI->getFeatureBits();
diff --git a/llvm/test/MC/RISCV/option-arch.s b/llvm/test/MC/RISCV/option-arch.s
index 6ee133c7159a27..40675f9e4b434b 100644
--- a/llvm/test/MC/RISCV/option-arch.s
+++ b/llvm/test/MC/RISCV/option-arch.s
@@ -1,7 +1,7 @@
 # RUN: llvm-mc -triple riscv32 -show-encoding < %s \
 # RUN:   | FileCheck -check-prefixes=CHECK %s
 # RUN: llvm-mc -triple riscv32 -filetype=obj < %s \
-# RUN:   | llvm-objdump  --triple=riscv32 --mattr=+c,+m,+a,+f,+zba -d -M no-aliases - \
+# RUN:   | llvm-objdump  --triple=riscv32 --mattr=+c,+m,+a,+f,+zba,+experimental-zicfiss -d -M no-aliases - \
 # RUN:   | FileCheck -check-prefixes=CHECK-INST %s
 
 # Test '.option arch, +' and '.option arch, -' directive
@@ -78,6 +78,13 @@ lr.w t0, (t1)
 # CHECK: encoding: [0xb3,0x22,0x73,0x20]
 sh1add t0, t1, t2
 
+# Test experimental extension
+# CHECK: .option arch, +zicfiss
+.option arch, +zicfiss
+# CHECK-INST: sspopchk ra
+# CHECK: encoding: [0x73,0xc0,0xc0,0xcd]
+sspopchk ra
+
 # Test '.option arch, <arch-string>' directive
 # CHECK: .option arch, rv32i2p1_m2p0_a2p1_c2p0
 .option arch, rv32i2p1_m2p0_a2p1_c2p0

>From 471abce617a9d18ef91370303eef90bab228d9d3 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 23 Apr 2024 21:55:12 -0700
Subject: [PATCH 2/6] Make this pr obey menable-experimental-extensions.

---
 clang/lib/Driver/ToolChains/Clang.cpp              | 5 +++++
 clang/test/Driver/riscv-option-arch.s              | 5 +++++
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 6 ++++++
 3 files changed, 16 insertions(+)
 create mode 100644 clang/test/Driver/riscv-option-arch.s

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 5894a48e0e378b..8b0f523763486f 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8449,6 +8449,11 @@ void ClangAs::AddRISCVTargetArgs(const ArgList &Args,
       CmdArgs.push_back("-mllvm");
       CmdArgs.push_back("-riscv-add-build-attributes");
   }
+
+  if (!Args.hasArg(options::OPT_menable_experimental_extensions)) {
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back("-riscv-disable-experimental-ext");
+  }
 }
 
 void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
diff --git a/clang/test/Driver/riscv-option-arch.s b/clang/test/Driver/riscv-option-arch.s
new file mode 100644
index 00000000000000..8ce84dd8ffe79d
--- /dev/null
+++ b/clang/test/Driver/riscv-option-arch.s
@@ -0,0 +1,5 @@
+# RUN: %clang --target=riscv64 -menable-experimental-extensions -c -o /dev/null %s
+# RUN: ! %clang --target=riscv64 -c -o /dev/null %s 2>&1 | FileCheck -check-prefixes=CHECK-ERR %s
+
+.option arch, +zicfiss
+# CHECK-ERR: Unexpected experimental extensions.
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 80ff70f1095f4c..6225e0707015fe 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -51,6 +51,9 @@ STATISTIC(RISCVNumInstrsCompressed,
 
 static cl::opt<bool> AddBuildAttributes("riscv-add-build-attributes",
                                         cl::init(false));
+static cl::opt<bool>
+    DisableExperimentalExtension("riscv-disable-experimental-ext",
+                                 cl::init(false));
 
 namespace llvm {
 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
@@ -2825,6 +2828,9 @@ bool RISCVAsmParser::parseDirectiveOption() {
       }
 
       std::string &&Feature = RISCVISAInfo::getTargetFeatureForExtension(Arch);
+      if (DisableExperimentalExtension &&
+          StringRef(Feature).starts_with("experimental-"))
+        return Error(Loc, "Unexpected experimental extensions.");
       auto Ext = llvm::lower_bound(RISCVFeatureKV, Feature);
       if (Ext == std::end(RISCVFeatureKV) || StringRef(Ext->Key) != Feature ||
           !RISCVISAInfo::isSupportedExtension(Arch)) {

>From 066445e8df415373b2f115e9b36b166b6b8ccfa9 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 23 Apr 2024 23:09:52 -0700
Subject: [PATCH 3/6] Remove unneeded rvalue reference.

---
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 6225e0707015fe..5b601f33b3e55d 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2827,7 +2827,7 @@ bool RISCVAsmParser::parseDirectiveOption() {
         break;
       }
 
-      std::string &&Feature = RISCVISAInfo::getTargetFeatureForExtension(Arch);
+      std::string Feature = RISCVISAInfo::getTargetFeatureForExtension(Arch);
       if (DisableExperimentalExtension &&
           StringRef(Feature).starts_with("experimental-"))
         return Error(Loc, "Unexpected experimental extensions.");

>From a27e003c7d97de6c15f57f7c6bad3ddd0d6f92c4 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Thu, 25 Apr 2024 21:59:40 -0700
Subject: [PATCH 4/6] Use feature to allow/disallow experimental extensions.

---
 clang/lib/Driver/ToolChains/Clang.cpp              | 5 -----
 clang/test/Driver/riscv-option-arch.c              | 7 +++++++
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 9 ++++-----
 llvm/test/MC/RISCV/option-arch.s                   | 4 ++--
 4 files changed, 13 insertions(+), 12 deletions(-)
 create mode 100644 clang/test/Driver/riscv-option-arch.c

diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 8b0f523763486f..5894a48e0e378b 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8449,11 +8449,6 @@ void ClangAs::AddRISCVTargetArgs(const ArgList &Args,
       CmdArgs.push_back("-mllvm");
       CmdArgs.push_back("-riscv-add-build-attributes");
   }
-
-  if (!Args.hasArg(options::OPT_menable_experimental_extensions)) {
-    CmdArgs.push_back("-mllvm");
-    CmdArgs.push_back("-riscv-disable-experimental-ext");
-  }
 }
 
 void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,
diff --git a/clang/test/Driver/riscv-option-arch.c b/clang/test/Driver/riscv-option-arch.c
new file mode 100644
index 00000000000000..e583e9fd62b08c
--- /dev/null
+++ b/clang/test/Driver/riscv-option-arch.c
@@ -0,0 +1,7 @@
+// RUN: %clang --target=riscv64 -menable-experimental-extensions -c -o /dev/null %s
+// RUN: ! %clang --target=riscv64 -c -o /dev/null %s 2>&1 | FileCheck -check-prefixes=CHECK-ERR %s
+
+void foo() {
+  asm volatile (".option arch, +zicfiss");
+  // CHECK-ERR: Unexpected experimental extensions.
+}
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 5b601f33b3e55d..4771d91ec64629 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -51,10 +51,6 @@ STATISTIC(RISCVNumInstrsCompressed,
 
 static cl::opt<bool> AddBuildAttributes("riscv-add-build-attributes",
                                         cl::init(false));
-static cl::opt<bool>
-    DisableExperimentalExtension("riscv-disable-experimental-ext",
-                                 cl::init(false));
-
 namespace llvm {
 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
 } // namespace llvm
@@ -87,6 +83,9 @@ class RISCVAsmParser : public MCTargetAsmParser {
   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
   bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
   bool isRVE() const { return getSTI().hasFeature(RISCV::FeatureStdExtE); }
+  bool enableExperimentalExtension() const {
+    return getSTI().hasFeature(RISCV::Experimental);
+  }
 
   RISCVTargetStreamer &getTargetStreamer() {
     assert(getParser().getStreamer().getTargetStreamer() &&
@@ -2828,7 +2827,7 @@ bool RISCVAsmParser::parseDirectiveOption() {
       }
 
       std::string Feature = RISCVISAInfo::getTargetFeatureForExtension(Arch);
-      if (DisableExperimentalExtension &&
+      if (!enableExperimentalExtension() &&
           StringRef(Feature).starts_with("experimental-"))
         return Error(Loc, "Unexpected experimental extensions.");
       auto Ext = llvm::lower_bound(RISCVFeatureKV, Feature);
diff --git a/llvm/test/MC/RISCV/option-arch.s b/llvm/test/MC/RISCV/option-arch.s
index 40675f9e4b434b..7826252f66e6c8 100644
--- a/llvm/test/MC/RISCV/option-arch.s
+++ b/llvm/test/MC/RISCV/option-arch.s
@@ -1,6 +1,6 @@
-# RUN: llvm-mc -triple riscv32 -show-encoding < %s \
+# RUN: llvm-mc -triple riscv32 -mattr=+experimental -show-encoding < %s \
 # RUN:   | FileCheck -check-prefixes=CHECK %s
-# RUN: llvm-mc -triple riscv32 -filetype=obj < %s \
+# RUN: llvm-mc -triple riscv32 -mattr=+experimental -filetype=obj < %s \
 # RUN:   | llvm-objdump  --triple=riscv32 --mattr=+c,+m,+a,+f,+zba,+experimental-zicfiss -d -M no-aliases - \
 # RUN:   | FileCheck -check-prefixes=CHECK-INST %s
 

>From 8d098cb5b30fd36a84669206e5d1e03892518eb8 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Wed, 1 May 2024 20:09:31 -0700
Subject: [PATCH 5/6] Address Craig's comment.

---
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 4771d91ec64629..feba84b471e2b9 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -51,6 +51,7 @@ STATISTIC(RISCVNumInstrsCompressed,
 
 static cl::opt<bool> AddBuildAttributes("riscv-add-build-attributes",
                                         cl::init(false));
+
 namespace llvm {
 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
 } // namespace llvm
@@ -2831,8 +2832,7 @@ bool RISCVAsmParser::parseDirectiveOption() {
           StringRef(Feature).starts_with("experimental-"))
         return Error(Loc, "Unexpected experimental extensions.");
       auto Ext = llvm::lower_bound(RISCVFeatureKV, Feature);
-      if (Ext == std::end(RISCVFeatureKV) || StringRef(Ext->Key) != Feature ||
-          !RISCVISAInfo::isSupportedExtension(Arch)) {
+      if (Ext == std::end(RISCVFeatureKV) || StringRef(Ext->Key) != Feature) {
         if (isDigit(Arch.back()))
           return Error(
               Loc,

>From 5b4035cde423f278598b69129a27130128025f2f Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Sat, 4 May 2024 17:26:13 -0700
Subject: [PATCH 6/6] fix: deny extensions with version number.

---
 llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index feba84b471e2b9..c6795dd8613509 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2827,18 +2827,17 @@ bool RISCVAsmParser::parseDirectiveOption() {
         break;
       }
 
+      if (isDigit(Arch.back()))
+        return Error(
+            Loc, "Extension version number parsing not currently implemented");
+
       std::string Feature = RISCVISAInfo::getTargetFeatureForExtension(Arch);
       if (!enableExperimentalExtension() &&
           StringRef(Feature).starts_with("experimental-"))
         return Error(Loc, "Unexpected experimental extensions.");
       auto Ext = llvm::lower_bound(RISCVFeatureKV, Feature);
-      if (Ext == std::end(RISCVFeatureKV) || StringRef(Ext->Key) != Feature) {
-        if (isDigit(Arch.back()))
-          return Error(
-              Loc,
-              "Extension version number parsing not currently implemented");
+      if (Ext == std::end(RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
         return Error(Loc, "unknown extension feature");
-      }
 
       Args.emplace_back(Type, Arch.str());
 



More information about the llvm-commits mailing list