achieveartificialintelligence updated this revision to Diff 394174.
achieveartificialintelligence added a comment.

Support both i2p0 and i2p1


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113237/new/

https://reviews.llvm.org/D113237

Files:
  clang/lib/Basic/Targets/RISCV.cpp
  clang/test/Driver/riscv-arch.c
  clang/test/Driver/riscv-cpus.c
  llvm/include/llvm/Support/RISCVISAInfo.h
  llvm/lib/Support/RISCVISAInfo.cpp
  llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
  llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
  llvm/lib/Target/RISCV/RISCV.td
  llvm/lib/Target/RISCV/RISCVInstrInfo.td
  llvm/lib/Target/RISCV/RISCVSubtarget.h
  llvm/test/MC/RISCV/attribute-arch.s
  llvm/test/MC/RISCV/rv32zicsr-invalid.s
  llvm/test/MC/RISCV/rv32zicsr-valid.s
  llvm/test/MC/RISCV/rv32zifencei-valid.s

Index: llvm/test/MC/RISCV/rv32zifencei-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zifencei-valid.s
@@ -0,0 +1,8 @@
+# RUN: llvm-mc %s -triple=riscv32  -mattr=+zifencei -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple riscv64 -mattr=+zifencei -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: fence.i
+# CHECK-ASM: encoding: [0x0f,0x10,0x00,0x00]
+fence.i
Index: llvm/test/MC/RISCV/rv32zicsr-valid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zicsr-valid.s
@@ -0,0 +1,32 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zicsr -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple riscv64 -mattr=+zicsr -riscv-no-aliases -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: csrrw t0, 4095, t1
+# CHECK-ASM: encoding: [0xf3,0x12,0xf3,0xff]
+csrrw t0, 0xfff, t1
+# CHECK-ASM-AND-OBJ: csrrw s0, 4095, s1
+# CHECK-ASM: encoding: [0x73,0x94,0xf4,0xff]
+csrrw s0, ~(-4096), s1
+# CHECK-ASM-AND-OBJ: csrrw s0, fflags, s1
+# CHECK-ASM: encoding: [0x73,0x94,0x14,0x00]
+csrrw s0, !0, s1
+# CHECK-ASM-AND-OBJ: csrrs s0, cycle, zero
+# CHECK-ASM: encoding: [0x73,0x24,0x00,0xc0]
+csrrs s0, 0xc00, x0
+# CHECK-ASM-AND-OBJ: csrrs s3, fflags, s5
+# CHECK-ASM: encoding: [0xf3,0xa9,0x1a,0x00]
+csrrs s3, 0x001, s5
+# CHECK-ASM-AND-OBJ: csrrc sp, ustatus, ra
+# CHECK-ASM: encoding: [0x73,0xb1,0x00,0x00]
+csrrc sp, 0x000, ra
+# CHECK-ASM-AND-OBJ: csrrwi a5, ustatus, 0
+# CHECK-ASM: encoding: [0xf3,0x57,0x00,0x00]
+csrrwi a5, 0x000, 0
+# CHECK-ASM-AND-OBJ: csrrsi t2, 4095, 31
+# CHECK-ASM: encoding: [0xf3,0xe3,0xff,0xff]
+csrrsi t2, 0xfff, 31
+# CHECK-ASM-AND-OBJ: csrrci t1, sscratch, 5
+# CHECK-ASM: encoding: [0x73,0xf3,0x02,0x14]
+csrrci t1, 0x140, 5
Index: llvm/test/MC/RISCV/rv32zicsr-invalid.s
===================================================================
--- /dev/null
+++ llvm/test/MC/RISCV/rv32zicsr-invalid.s
@@ -0,0 +1,44 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+zicsr < %s 2>&1 | FileCheck %s
+
+# Out of range immediates
+## uimm5
+csrrwi a1, 0x1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+csrrsi t1, 999, 32 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+csrrci x0, 43, -90 # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+
+## uimm12
+csrrw a0, -1, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
+csrrs a0, 4096, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
+csrrs a0, -0xf, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
+csrrc a0, 0x1000, a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
+csrrwi a0, -50, 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
+csrrsi a0, 4097, a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
+csrrci a0, 0xffff, a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
+
+# Illegal operand modifier
+## uimm5
+csrrwi a1, 0x1, %hi(b) # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+csrrsi t1, 999, %pcrel_hi(3) # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+csrrci x0, 43, %pcrel_hi(c) # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+csrrsi t1, 999, %pcrel_lo(4) # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 31]
+csrrci x0, 43, %pcrel_lo(d) # CHECK: :[[@LINE]]:16: error: immediate must be an integer in the range [0, 31]
+
+## uimm12
+csrrw a0, %lo(1), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
+csrrs a0, %lo(a), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
+csrrs a0, %hi(2), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
+csrrc a0, %hi(b), a0 # CHECK: :[[@LINE]]:11: error: immediate must be an integer in the range [0, 4095]
+csrrwi a0, %pcrel_hi(3), 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
+csrrsi a0, %pcrel_hi(c), a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
+csrrwi a0, %pcrel_lo(4), 0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
+csrrsi a0, %pcrel_lo(d), a0 # CHECK: :[[@LINE]]:12: error: immediate must be an integer in the range [0, 4095]
+
+## named csr in place of uimm12
+csrrw a0, foos, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrs a0, mstatusx, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrs a0, xmstatus, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrc a0, m12status, a0 # CHECK: :[[@LINE]]:11: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrwi a0, mstatus12, 0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrsi a0, mhpm12counter, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrwi a0, mhpmcounter32, 0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
+csrrsi a0, A, a0 # CHECK: :[[@LINE]]:12: error: operand must be a valid system register name or an integer in the range [0, 4095]
Index: llvm/test/MC/RISCV/attribute-arch.s
===================================================================
--- llvm/test/MC/RISCV/attribute-arch.s
+++ llvm/test/MC/RISCV/attribute-arch.s
@@ -12,6 +12,9 @@
 .attribute arch, "rv32i2p0"
 # CHECK: attribute      5, "rv32i2p0"
 
+.attribute arch, "rv32i2p1"
+# CHECK: attribute      5, "rv32i2p1"
+
 .attribute arch, "rv32i2_m2"
 # CHECK: attribute      5, "rv32i2p0_m2p0"
 
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -52,6 +52,9 @@
   bool HasStdExtV = false;
   bool HasStdExtZvlsseg = false;
   bool HasStdExtZvamo = false;
+  bool IsI2p1 = false;
+  bool HasStdExtZicsr = false;
+  bool HasStdExtZifencei = false;
   bool HasStdExtZfhmin = false;
   bool HasStdExtZfh = false;
   bool HasRV64 = false;
@@ -119,6 +122,8 @@
   bool hasStdExtV() const { return HasStdExtV; }
   bool hasStdExtZvlsseg() const { return HasStdExtZvlsseg; }
   bool hasStdExtZvamo() const { return HasStdExtZvamo; }
+  bool hasStdExtZicsr() const { return HasStdExtZicsr; }
+  bool hasStdExtZifencei() const { return HasStdExtZifencei; }
   bool hasStdExtZfhmin() const { return HasStdExtZfhmin; }
   bool hasStdExtZfh() const { return HasStdExtZfh; }
   bool is64Bit() const { return HasRV64; }
@@ -146,6 +151,13 @@
     return hasVInstructions() ? MaxInterleaveFactor : 1;
   }
 
+  bool HasI2p0OrZicsr() {
+    return (IsI2p1 && HasStdExtZicsr) || (!IsI2p1 && !HasStdExtZicsr);
+  }
+  bool HasI2p0OrZifencei() {
+    return (IsI2p1 && HasStdExtZifencei) || (!IsI2p1 && !HasStdExtZifencei);
+  }
+
 protected:
   // GlobalISel related APIs.
   std::unique_ptr<CallLowering> CallLoweringInfo;
Index: llvm/lib/Target/RISCV/RISCVInstrInfo.td
===================================================================
--- llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -572,6 +572,7 @@
   let imm12 = {0b1000,0b0011,0b0011};
 }
 
+let Predicates = [HasI2p0OrZifencei] in
 def FENCE_I : RVInstI<0b001, OPC_MISC_MEM, (outs), (ins), "fence.i", "">, Sched<[]> {
   let rs1 = 0;
   let rd = 0;
@@ -602,6 +603,7 @@
 }
 } // hasSideEffects = 1, mayLoad = 0, mayStore = 0
 
+let Predicates = [HasI2p0OrZicsr] in {
 def CSRRW : CSR_ir<0b001, "csrrw">;
 def CSRRS : CSR_ir<0b010, "csrrs">;
 def CSRRC : CSR_ir<0b011, "csrrc">;
@@ -609,6 +611,7 @@
 def CSRRWI : CSR_ii<0b101, "csrrwi">;
 def CSRRSI : CSR_ii<0b110, "csrrsi">;
 def CSRRCI : CSR_ii<0b111, "csrrci">;
+} // Predicates = [HasI2p0OrZicsr]
 
 /// RV64I instructions
 
@@ -794,6 +797,7 @@
 def : InstAlias<"rdtimeh $rd",    (CSRRS GPR:$rd, TIMEH.Encoding, X0)>;
 } // Predicates = [IsRV32]
 
+let Predicates = [HasI2p0OrZicsr] in {
 def : InstAlias<"csrr $rd, $csr", (CSRRS GPR:$rd, csr_sysreg:$csr,      X0)>;
 def : InstAlias<"csrw $csr, $rs", (CSRRW      X0, csr_sysreg:$csr, GPR:$rs)>;
 def : InstAlias<"csrs $csr, $rs", (CSRRS      X0, csr_sysreg:$csr, GPR:$rs)>;
@@ -812,6 +816,7 @@
 def : InstAlias<"csrrs $rd, $csr, $imm", (CSRRSI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
 def : InstAlias<"csrrc $rd, $csr, $imm", (CSRRCI GPR:$rd, csr_sysreg:$csr, uimm5:$imm)>;
 }
+} // Predicates = [HasI2p0OrZicsr]
 
 def : InstAlias<"sfence.vma",     (SFENCE_VMA      X0, X0)>;
 def : InstAlias<"sfence.vma $rs", (SFENCE_VMA GPR:$rs, X0)>;
Index: llvm/lib/Target/RISCV/RISCV.td
===================================================================
--- llvm/lib/Target/RISCV/RISCV.td
+++ llvm/lib/Target/RISCV/RISCV.td
@@ -176,6 +176,26 @@
                                AssemblerPredicate<(all_of FeatureStdExtZvamo),
                                "'Zvamo' (Vector AMO Operations)">;
 
+def FeatureI2p1
+    : SubtargetFeature<"i2p1", "IsI2p1", "true", "Implements I 2.1">;
+
+def FeatureStdExtZicsr
+    : SubtargetFeature<"zicsr", "HasStdExtZicsr", "true",
+                       "'Zicsr' (Control and Status Register)">;
+def HasStdExtZicsr : Predicate<"Subtarget->hasStdExtZicsr()">,
+                               AssemblerPredicate<(all_of FeatureStdExtZicsr),
+                               "'Zicsr' (Control and Status Register)">;
+
+def FeatureStdExtZifencei
+    : SubtargetFeature<"zifencei", "HasStdExtZifencei", "true",
+                       "'Zifencei' (Instruction-Fetch Fence)">;
+def HasStdExtZifencei : Predicate<"Subtarget->hasStdExtZifencei()">,
+                                  AssemblerPredicate<(all_of FeatureStdExtZifencei),
+                                  "'Zifencei' (Instruction-Fetch Fence)">;
+
+def HasI2p0OrZicsr       : Predicate<"Subtarget->HasI2p0OrZicsr()">;
+def HasI2p0OrZifencei    : Predicate<"Subtarget->HasI2p0OrZifencei()">;
+
 def Feature64Bit
     : SubtargetFeature<"64bit", "HasRV64", "true", "Implements RV64">;
 def IsRV64 : Predicate<"Subtarget->is64Bit()">,
Index: llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
===================================================================
--- llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
+++ llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
@@ -49,7 +49,9 @@
   std::vector<std::string> FeatureVector;
   RISCVFeatures::toFeatureVector(FeatureVector, STI.getFeatureBits());
 
-  auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeatureVector);
+  bool IsI2p1 = STI.hasFeature(RISCV::FeatureI2p1);
+  auto ParseResult =
+      llvm::RISCVISAInfo::parseFeatures(XLen, false, FeatureVector);
   if (!ParseResult) {
     /* Assume any error about features should handled earlier.  */
     consumeError(ParseResult.takeError());
Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
===================================================================
--- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -2157,6 +2157,9 @@
       if (ISAInfo->hasExtension(Feature.Key))
         setFeatureBits(Feature.Value, Feature.Key);
 
+    if (ISAInfo->getIsI2p1())
+      setFeatureBits(RISCV::FeatureI2p1, "i2p1");
+
     if (ISAInfo->getXLen() == 32)
       clearFeatureBits(RISCV::Feature64Bit, "64bit");
     else if (ISAInfo->getXLen() == 64)
Index: llvm/lib/Support/RISCVISAInfo.cpp
===================================================================
--- llvm/lib/Support/RISCVISAInfo.cpp
+++ llvm/lib/Support/RISCVISAInfo.cpp
@@ -30,42 +30,45 @@
 
 struct RISCVSupportedExtension {
   const char *Name;
-  /// Supported version.
-  RISCVExtensionVersion Version;
+  /// Supported versions.
+  std::array<RISCVExtensionVersion, 2> Versions;
 };
 
 } // end anonymous namespace
 
 static constexpr StringLiteral AllStdExts = "mafdqlcbjtpvn";
 
-static const RISCVSupportedExtension SupportedExtensions[] = {
-    {"i", RISCVExtensionVersion{2, 0}},
-    {"e", RISCVExtensionVersion{1, 9}},
-    {"m", RISCVExtensionVersion{2, 0}},
-    {"a", RISCVExtensionVersion{2, 0}},
-    {"f", RISCVExtensionVersion{2, 0}},
-    {"d", RISCVExtensionVersion{2, 0}},
-    {"c", RISCVExtensionVersion{2, 0}},
+const RISCVSupportedExtension SupportedExtensions[] = {
+    {"i", {RISCVExtensionVersion{2, 0}, RISCVExtensionVersion{2, 1}}},
+    {"e", {RISCVExtensionVersion{1, 9}}},
+    {"m", {RISCVExtensionVersion{2, 0}}},
+    {"a", {RISCVExtensionVersion{2, 0}}},
+    {"f", {RISCVExtensionVersion{2, 0}}},
+    {"d", {RISCVExtensionVersion{2, 0}}},
+    {"c", {RISCVExtensionVersion{2, 0}}},
+
+    {"zicsr", {RISCVExtensionVersion{2, 0}}},
+    {"zifencei", {RISCVExtensionVersion{2, 0}}},
 };
 
-static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
-    {"v", RISCVExtensionVersion{0, 10}},
-    {"zba", RISCVExtensionVersion{1, 0}},
-    {"zbb", RISCVExtensionVersion{1, 0}},
-    {"zbc", RISCVExtensionVersion{1, 0}},
-    {"zbe", RISCVExtensionVersion{0, 93}},
-    {"zbf", RISCVExtensionVersion{0, 93}},
-    {"zbm", RISCVExtensionVersion{0, 93}},
-    {"zbp", RISCVExtensionVersion{0, 93}},
-    {"zbr", RISCVExtensionVersion{0, 93}},
-    {"zbs", RISCVExtensionVersion{1, 0}},
-    {"zbt", RISCVExtensionVersion{0, 93}},
-
-    {"zvamo", RISCVExtensionVersion{0, 10}},
-    {"zvlsseg", RISCVExtensionVersion{0, 10}},
-
-    {"zfhmin", RISCVExtensionVersion{0, 1}},
-    {"zfh", RISCVExtensionVersion{0, 1}},
+const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
+    {"v", {RISCVExtensionVersion{0, 10}}},
+    {"zba", {RISCVExtensionVersion{1, 0}}},
+    {"zbb", {RISCVExtensionVersion{1, 0}}},
+    {"zbc", {RISCVExtensionVersion{1, 0}}},
+    {"zbe", {RISCVExtensionVersion{0, 93}}},
+    {"zbf", {RISCVExtensionVersion{0, 93}}},
+    {"zbm", {RISCVExtensionVersion{0, 93}}},
+    {"zbp", {RISCVExtensionVersion{0, 93}}},
+    {"zbr", {RISCVExtensionVersion{0, 93}}},
+    {"zbs", {RISCVExtensionVersion{1, 0}}},
+    {"zbt", {RISCVExtensionVersion{0, 93}}},
+
+    {"zvamo", {RISCVExtensionVersion{0, 10}}},
+    {"zvlsseg", {RISCVExtensionVersion{0, 10}}},
+
+    {"zfhmin", {RISCVExtensionVersion{0, 1}}},
+    {"zfh", {RISCVExtensionVersion{0, 1}}},
 };
 
 static bool stripExperimentalPrefix(StringRef &Ext) {
@@ -112,7 +115,7 @@
     if (ExtensionInfoIterator == ExtInfo.end()) {
       continue;
     }
-    return ExtensionInfoIterator->Version;
+    return ExtensionInfoIterator->Versions.front();
   }
   return None;
 }
@@ -156,7 +159,7 @@
   if (ExtIterator == std::end(SupportedExperimentalExtensions))
     return None;
 
-  return ExtIterator->Version;
+  return ExtIterator->Versions.front();
 }
 
 bool RISCVISAInfo::isSupportedExtensionFeature(StringRef Ext) {
@@ -176,8 +179,11 @@
 bool RISCVISAInfo::isSupportedExtension(StringRef Ext, unsigned MajorVersion,
                                         unsigned MinorVersion) {
   auto FindByNameAndVersion = [=](const RISCVSupportedExtension &ExtInfo) {
-    return ExtInfo.Name == Ext && (MajorVersion == ExtInfo.Version.Major) &&
-           (MinorVersion == ExtInfo.Version.Minor);
+    for (const auto &Version : ExtInfo.Versions)
+      if (ExtInfo.Name == Ext && (MajorVersion == Version.Major) &&
+          (MinorVersion == Version.Minor))
+        return true;
+    return false;
   };
   return llvm::any_of(SupportedExtensions, FindByNameAndVersion) ||
          llvm::any_of(SupportedExperimentalExtensions, FindByNameAndVersion);
@@ -279,9 +285,16 @@
     std::function<StringRef(const Twine &)> StrAlloc) const {
   for (auto &Ext : Exts) {
     StringRef ExtName = Ext.first;
+    unsigned Major = Ext.second.MajorVersion;
+    unsigned Minor = Ext.second.MinorVersion;
 
-    if (ExtName == "i")
+    if (ExtName == "i") {
+      if (Major == 2 && Minor == 0) {
+        Features.push_back("+zicsr");
+        Features.push_back("+zifencei");
+      }
       continue;
+    }
 
     if (ExtName == "zvlsseg") {
       Features.push_back("+experimental-v");
@@ -407,7 +420,7 @@
 }
 
 llvm::Expected<std::unique_ptr<RISCVISAInfo>>
-RISCVISAInfo::parseFeatures(unsigned XLen,
+RISCVISAInfo::parseFeatures(unsigned XLen, bool IsI2p1,
                             const std::vector<std::string> &Features) {
   assert(XLen == 32 || XLen == 64);
   std::unique_ptr<RISCVISAInfo> ISAInfo(new RISCVISAInfo(XLen));
@@ -431,12 +444,16 @@
       continue;
 
     if (Add)
-      ISAInfo->addExtension(ExtName, ExtensionInfoIterator->Version.Major,
-                            ExtensionInfoIterator->Version.Minor);
+      ISAInfo->addExtension(ExtName,
+                            ExtensionInfoIterator->Versions.front().Major,
+                            ExtensionInfoIterator->Versions.front().Minor);
     else
       ISAInfo->Exts.erase(ExtName.str());
   }
 
+  if (IsI2p1)
+    ISAInfo->addExtension("i", 2, 1);
+
   ISAInfo->updateImplication();
   ISAInfo->updateFLen();
 
@@ -520,9 +537,12 @@
         ISAInfo->addExtension(Ext, Version->Major, Version->Minor);
       else
         llvm_unreachable("Default extension version not found?");
-  } else
+  } else {
     // Baseline is `i` or `e`
     ISAInfo->addExtension(std::string(1, Baseline), Major, Minor);
+    if (Baseline == 'i' && Major == 2 && Minor == 1)
+      ISAInfo->IsI2p1 = true;
+  }
 
   // Consume the base ISA version number and any '_' between rvxxx and the
   // first extension
Index: llvm/include/llvm/Support/RISCVISAInfo.h
===================================================================
--- llvm/include/llvm/Support/RISCVISAInfo.h
+++ llvm/include/llvm/Support/RISCVISAInfo.h
@@ -51,7 +51,8 @@
 
   /// Parse RISCV ISA info from feature vector.
   static llvm::Expected<std::unique_ptr<RISCVISAInfo>>
-  parseFeatures(unsigned XLen, const std::vector<std::string> &Features);
+  parseFeatures(unsigned XLen, bool IsI2p1,
+                const std::vector<std::string> &Features);
 
   /// Convert RISCV ISA info to a feature vector.
   void toFeatures(std::vector<StringRef> &Features,
@@ -61,6 +62,7 @@
 
   unsigned getXLen() const { return XLen; };
   unsigned getFLen() const { return FLen; };
+  bool getIsI2p1() const { return IsI2p1; };
 
   bool hasExtension(StringRef Ext) const;
   std::string toString() const;
@@ -75,6 +77,7 @@
 
   unsigned XLen;
   unsigned FLen;
+  bool IsI2p1;
 
   OrderedExtensionMap Exts;
 
Index: clang/test/Driver/riscv-cpus.c
===================================================================
--- clang/test/Driver/riscv-cpus.c
+++ clang/test/Driver/riscv-cpus.c
@@ -129,7 +129,8 @@
 
 // march overwrite mcpu's default march
 // RUN: %clang -target riscv32 -### -c %s 2>&1 -mcpu=sifive-e31 -march=rv32imc | FileCheck -check-prefix=MCPU-MARCH %s
-// MCPU-MARCH: "-nostdsysteminc" "-target-cpu" "sifive-e31" "-target-feature" "+m" "-target-feature" "+c"
+// MCPU-MARCH: "-nostdsysteminc" "-target-cpu" "sifive-e31"
+// MCPU-MARCH: "-target-feature" "+m" "-target-feature" "+c"
 // MCPU-MARCH: "-target-abi" "ilp32"
 
 // Check interaction between mcpu and mtune, mtune won't affect arch related
Index: clang/test/Driver/riscv-arch.c
===================================================================
--- clang/test/Driver/riscv-arch.c
+++ clang/test/Driver/riscv-arch.c
@@ -307,10 +307,10 @@
 // RV32-IMINOR-MISS: error: invalid arch name 'rv32i2p',
 // RV32-IMINOR-MISS: minor version number missing after 'p' for extension 'i'
 
-// RUN: %clang -target riscv32-unknown-elf -march=rv32i2p1 -### %s \
+// RUN: %clang -target riscv32-unknown-elf -march=rv32i2p2 -### %s \
 // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-IMINOR1 %s
-// RV32-IMINOR1: error: invalid arch name 'rv32i2p1', unsupported
-// RV32-IMINOR1: version number 2.1 for extension 'i'
+// RV32-IMINOR1: error: invalid arch name 'rv32i2p2', unsupported
+// RV32-IMINOR1: version number 2.2 for extension 'i'
 
 // RUN: %clang -target riscv32-unknown-elf -march=rv32ixt2p -### %s \
 // RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-XMINOR-MISS %s
Index: clang/lib/Basic/Targets/RISCV.cpp
===================================================================
--- clang/lib/Basic/Targets/RISCV.cpp
+++ clang/lib/Basic/Targets/RISCV.cpp
@@ -233,7 +233,7 @@
 bool RISCVTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
                                            DiagnosticsEngine &Diags) {
   unsigned XLen = getTriple().isArch64Bit() ? 64 : 32;
-  auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, Features);
+  auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, false, Features);
   if (!ParseResult) {
     std::string Buffer;
     llvm::raw_string_ostream OutputErrMsg(Buffer);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to