[llvm] [clang] [RFC][RISCV] Support RISC-V Profiles in -march option (PR #76357)

Wang Pengcheng via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 27 01:45:03 PST 2023


https://github.com/wangpc-pp updated https://github.com/llvm/llvm-project/pull/76357

>From 965c1c682d16a3f47c563a301c89e3717bf4d1c5 Mon Sep 17 00:00:00 2001
From: wangpc <wangpengcheng.pp at bytedance.com>
Date: Mon, 25 Dec 2023 18:52:36 +0800
Subject: [PATCH] [RFC][RISCV] Support RISC-V Profiles in -march option

This PR implements the draft
https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/36.

Currently, we replace specified profile in `-march` with standard
arch string.

We may need to pass it to backend so that we can emit an ELF attr
proposed by
https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/409.
---
 clang/test/Driver/riscv-profiles.c     | 105 +++++++++++++++++++++++++
 llvm/lib/Support/RISCVISAInfo.cpp      |  43 ++++++++++
 llvm/lib/Target/RISCV/RISCV.td         |   6 ++
 llvm/lib/Target/RISCV/RISCVProfiles.td |  70 +++++++++++++++++
 llvm/lib/Target/RISCV/RISCVSubtarget.h |  14 ++++
 5 files changed, 238 insertions(+)
 create mode 100644 clang/test/Driver/riscv-profiles.c
 create mode 100644 llvm/lib/Target/RISCV/RISCVProfiles.td

diff --git a/clang/test/Driver/riscv-profiles.c b/clang/test/Driver/riscv-profiles.c
new file mode 100644
index 00000000000000..7f54d0d885c7d7
--- /dev/null
+++ b/clang/test/Driver/riscv-profiles.c
@@ -0,0 +1,105 @@
+// RUN: %clang -### -c %s 2>&1 -march=rvi20u32 | FileCheck -check-prefix=RVI20U32 %s
+// RVI20U32: "-target-cpu" "generic-rv64"
+// RVI20U32: "-target-feature" "-a"
+// RVI20U32: "-target-feature" "-c"
+// RVI20U32: "-target-feature" "-d"
+// RVI20U32: "-target-feature" "-f"
+// RVI20U32: "-target-feature" "-m"
+// RVI20U32: "-target-abi" "ilp32"
+
+// RUN: %clang -### -c %s 2>&1 -march=rvi20u64 | FileCheck -check-prefix=RVI20U64 %s
+// RVI20U64: "-target-cpu" "generic-rv64"
+// RVI20U64: "-target-feature" "-a"
+// RVI20U64: "-target-feature" "-c"
+// RVI20U64: "-target-feature" "-d"
+// RVI20U64: "-target-feature" "-f"
+// RVI20U64: "-target-feature" "-m"
+// RVI20U64: "-target-abi" "lp64"
+
+// RUN: %clang -### -c %s 2>&1 -march=rva20u64 | FileCheck -check-prefix=RVA20U64 %s
+// RVA20U64: "-target-cpu" "generic-rv64"
+// RVA20U64: "-target-feature" "+m"
+// RVA20U64: "-target-feature" "+a"
+// RVA20U64: "-target-feature" "+f"
+// RVA20U64: "-target-feature" "+d"
+// RVA20U64: "-target-feature" "+c"
+// RVA20U64: "-target-feature" "+zicsr"
+// RVA20U64: "-target-abi" "lp64d"
+
+// RUN: %clang -### -c %s 2>&1 -march=rva20s64 | FileCheck -check-prefix=RVA20S64 %s
+// RVA20S64: "-target-cpu" "generic-rv64"
+// RVA20S64: "-target-feature" "+m"
+// RVA20S64: "-target-feature" "+a"
+// RVA20S64: "-target-feature" "+f"
+// RVA20S64: "-target-feature" "+d"
+// RVA20S64: "-target-feature" "+c"
+// RVA20S64: "-target-feature" "+zicsr"
+// RVA20S64: "-target-feature" "+zifencei"
+// RVA20S64: "-target-abi" "lp64d"
+
+// RUN: %clang -### -c %s 2>&1 -march=rva22u64 | FileCheck -check-prefix=RVA22U64 %s
+// RVA22U64: "-target-cpu" "generic-rv64"
+// RVA22U64: "-target-feature" "+m"
+// RVA22U64: "-target-feature" "+a"
+// RVA22U64: "-target-feature" "+f"
+// RVA22U64: "-target-feature" "+d"
+// RVA22U64: "-target-feature" "+c"
+// RVA22U64: "-target-feature" "+zicbom"
+// RVA22U64: "-target-feature" "+zicbop"
+// RVA22U64: "-target-feature" "+zicboz"
+// RVA22U64: "-target-feature" "+zicsr"
+// RVA22U64: "-target-feature" "+zihintpause"
+// RVA22U64: "-target-feature" "+zfhmin" 
+// RVA22U64: "-target-feature" "+zba"
+// RVA22U64: "-target-feature" "+zbb"
+// RVA22U64: "-target-feature" "+zbs"
+// RVA22U64: "-target-feature" "+zkt"
+// RVA22U64: "-target-abi" "lp64d"
+
+// RUN: %clang -### -c %s 2>&1 -march=rva22s64 | FileCheck -check-prefix=RVA22S64 %s
+// RVA22S64: "-target-cpu" "generic-rv64"
+// RVA22S64: "-target-feature" "+m"
+// RVA22S64: "-target-feature" "+a"
+// RVA22S64: "-target-feature" "+f"
+// RVA22S64: "-target-feature" "+d"
+// RVA22S64: "-target-feature" "+c"
+// RVA22S64: "-target-feature" "+zicbom"
+// RVA22S64: "-target-feature" "+zicbop"
+// RVA22S64: "-target-feature" "+zicboz"
+// RVA22S64: "-target-feature" "+zicsr"
+// RVA22S64: "-target-feature" "+zifencei"
+// RVA22S64: "-target-feature" "+zihintpause"
+// RVA22S64: "-target-feature" "+zfhmin" 
+// RVA22S64: "-target-feature" "+zba"
+// RVA22S64: "-target-feature" "+zbb"
+// RVA22S64: "-target-feature" "+zbs"
+// RVA22S64: "-target-feature" "+zkt"
+// RVA22S64: "-target-feature" "+svinval"
+// RVA22S64: "-target-feature" "+svpbmt"
+// RVA22S64: "-target-abi" "lp64d"
+
+// RUN: %clang -### -c %s 2>&1 -march=rva22u64_zfa | FileCheck -check-prefix=PROFILE-WITH-ADDITIONAL %s
+// PROFILE-WITH-ADDITIONAL: "-target-cpu" "generic-rv64"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+m"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+a"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+f"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+d"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+c"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zicbom"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zicbop"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zicboz"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zicsr"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zihintpause"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zfa"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zfhmin"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zba"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zbb"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zbs"
+// PROFILE-WITH-ADDITIONAL: "-target-feature" "+zkt"
+// PROFILE-WITH-ADDITIONAL: "-target-abi" "lp64d"
+
+// RUN: not %clang -### -c %s 2>&1 -march=rva19u64_zfa | FileCheck -check-prefix=INVALID-PROFILE %s
+// INVALID-PROFILE: error: invalid arch name 'rva19u64_zfa', unsupported profile
+
+// RUN: not %clang -### -c %s 2>&1 -march=rva22u64zfa | FileCheck -check-prefix=INVALID-ADDITIONAL %s
+// INVALID-ADDITIONAL: error: invalid arch name 'rva22u64zfa', additional extensions must be after separator '_'
diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index e71e96e3417e46..15eaaa23cc6c4c 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -39,6 +39,10 @@ struct RISCVSupportedExtension {
     return StringRef(Name) < StringRef(RHS.Name);
   }
 };
+struct RISCVProfile{
+  const char * Name;
+  const char * MArch;
+};
 
 } // end anonymous namespace
 
@@ -204,6 +208,17 @@ static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
     {"zvfbfwma", RISCVExtensionVersion{0, 8}},
 };
 
+static const RISCVProfile SupportedProfiles[] = {
+    {"rvi20u64", "rv64i"},
+    {"rvi20u32", "rv32i"},
+    {"rva20u64", "rv64imafdc_zicsr"},
+    {"rva20s64", "rv64imafdc_zicsr_zifencei"},
+    {"rva22u64", "rv64imafdc_zicsr_zihintpause_zba_zbb_zbs_zicbom_zicbop_"
+                 "zicboz_zfhmin_zkt"},
+    {"rva22s64", "rv64imafdc_zicsr_zifencei_zihintpause_zba_zbb_zbs_zicbom_"
+                 "zicbop_zicboz_zfhmin_zkt_svpbmt_svinval"},
+};
+
 static void verifyTables() {
 #ifndef NDEBUG
   static std::atomic<bool> TableChecked(false);
@@ -708,6 +723,34 @@ RISCVISAInfo::parseArchString(StringRef Arch, bool EnableExperimentalExtension,
                              "string must be lowercase");
   }
 
+  bool IsProfile = Arch.starts_with("rvi") || Arch.starts_with("rva") ||
+                   Arch.starts_with("rvb") || Arch.starts_with("rvm");
+  std::string NewArch = Arch.str();
+  if (IsProfile) {
+    const RISCVProfile *FoundProfile = nullptr;
+    for (const RISCVProfile &Profile : SupportedProfiles) {
+      if (Arch.starts_with(Profile.Name)) {
+        FoundProfile = &Profile;
+        break;
+      }
+    }
+
+    if (!FoundProfile)
+      return createStringError(errc::invalid_argument, "unsupported profile");
+
+    StringRef ProfilleName = FoundProfile->Name;
+    StringRef ArchWithoutProfile = Arch.substr(ProfilleName.size());
+    NewArch = FoundProfile->MArch;
+
+    if (!ArchWithoutProfile.empty()) {
+      if (!ArchWithoutProfile.starts_with("_"))
+        return createStringError(errc::invalid_argument,
+                                 "additional extensions must be after separator '_'");
+      NewArch = NewArch + ArchWithoutProfile.str();
+    }
+    Arch = NewArch;
+  }
+
   bool HasRV64 = Arch.starts_with("rv64");
   // ISA string must begin with rv32 or rv64.
   if (!(Arch.starts_with("rv32") || HasRV64) || (Arch.size() < 5)) {
diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index be93d5933d3329..b08a7686ff1265 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -44,6 +44,12 @@ include "RISCVSchedSyntacoreSCR1.td"
 
 include "RISCVProcessors.td"
 
+//===----------------------------------------------------------------------===//
+// RISC-V profiles supported.
+//===----------------------------------------------------------------------===//
+
+include "RISCVProfiles.td"
+
 //===----------------------------------------------------------------------===//
 // Define the RISC-V target.
 //===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVProfiles.td b/llvm/lib/Target/RISCV/RISCVProfiles.td
new file mode 100644
index 00000000000000..91e1064da4e76e
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVProfiles.td
@@ -0,0 +1,70 @@
+//===------ RISCVProfiles.td - RISC-V Profiles -------------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+class RISCVProfile<string name, list<SubtargetFeature> features>
+  : SubtargetFeature<name, "RISCVProfile", NAME,
+                     "RISC-V " # name # " profile",
+                     features>;
+
+def RVI20U32 : RISCVProfile<"rvi20u32", [Feature32Bit]>;
+
+def RVI20U64 : RISCVProfile<"rvi20u64", [Feature64Bit]>;
+
+def RVA20U64 : RISCVProfile<"rva20u64", [Feature64Bit,
+                                         FeatureStdExtM,
+                                         FeatureStdExtA,
+                                         FeatureStdExtF,
+                                         FeatureStdExtD,
+                                         FeatureStdExtC,
+                                         FeatureStdExtZicsr]>;
+
+def RVA20S64 : RISCVProfile<"rva20s64", [Feature64Bit,
+                                         FeatureStdExtM,
+                                         FeatureStdExtA,
+                                         FeatureStdExtF,
+                                         FeatureStdExtD,
+                                         FeatureStdExtC,
+                                         FeatureStdExtZicsr,
+                                         FeatureStdExtZifencei]>;
+
+def RVA22U64 : RISCVProfile<"rva22u64", [Feature64Bit,
+                                         FeatureStdExtM,
+                                         FeatureStdExtA,
+                                         FeatureStdExtF,
+                                         FeatureStdExtD,
+                                         FeatureStdExtC,
+                                         FeatureStdExtZba,
+                                         FeatureStdExtZbb,
+                                         FeatureStdExtZbs,
+                                         FeatureStdExtZfhmin,
+                                         FeatureStdExtZicbom,
+                                         FeatureStdExtZicbop,
+                                         FeatureStdExtZicboz,
+                                         FeatureStdExtZkt,
+                                         FeatureStdExtZicsr,
+                                         FeatureStdExtZihintpause]>;
+
+def RVA22S64 : RISCVProfile<"rva22s64", [Feature64Bit,
+                                         FeatureStdExtM,
+                                         FeatureStdExtA,
+                                         FeatureStdExtF,
+                                         FeatureStdExtD,
+                                         FeatureStdExtC,
+                                         FeatureStdExtZba,
+                                         FeatureStdExtZbb,
+                                         FeatureStdExtZbs,
+                                         FeatureStdExtZfhmin,
+                                         FeatureStdExtZicbom,
+                                         FeatureStdExtZicbop,
+                                         FeatureStdExtZicboz,
+                                         FeatureStdExtZkt,
+                                         FeatureStdExtZicsr,
+                                         FeatureStdExtZifencei,
+                                         FeatureStdExtZihintpause,
+                                         FeatureStdExtSvpbmt,
+                                         FeatureStdExtSvinval]>;
diff --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index 26320b05d9be29..dbb10c5b2d6f59 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -53,6 +53,16 @@ struct RISCVTuneInfo {
 #include "RISCVGenSearchableTables.inc"
 } // namespace RISCVTuneInfoTable
 
+enum RISCVProfileEnum : uint8_t {
+  Unspecified,
+  RVA20S64,
+  RVA20U64,
+  RVA22S64,
+  RVA22U64,
+  RVI20U32,
+  RVI20U64,
+};
+
 class RISCVSubtarget : public RISCVGenSubtargetInfo {
 public:
   // clang-format off
@@ -67,6 +77,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
 
   RISCVProcFamilyEnum RISCVProcFamily = Others;
 
+  RISCVProfileEnum RISCVProfile = Unspecified;
+
 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
   bool ATTRIBUTE = DEFAULT;
 #include "RISCVGenSubtargetInfo.inc"
@@ -135,6 +147,8 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   /// initializeProperties().
   RISCVProcFamilyEnum getProcFamily() const { return RISCVProcFamily; }
 
+  RISCVProfileEnum getRISCVProfile() const { return RISCVProfile; }
+
 #define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
   bool GETTER() const { return ATTRIBUTE; }
 #include "RISCVGenSubtargetInfo.inc"



More information about the cfe-commits mailing list