[clang] [compiler-rt] [llvm] [RISCV] Support new groupid/bitmask for cpu_model (PR #101632)

via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 2 01:20:14 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Piyou Chen (BeMg)

<details>
<summary>Changes</summary>

1. Add the new extension GroupID/Bitmask with latest hwprobe key.
2. Update the `initRISCVFeature `
3. Update `EmitRISCVCpuSupports` due to not only group0 now. 


---
Full diff: https://github.com/llvm/llvm-project/pull/101632.diff


5 Files Affected:

- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+2-1) 
- (modified) clang/test/CodeGen/builtin-cpu-supports.c (+36-14) 
- (modified) compiler-rt/lib/builtins/cpu_model/riscv.c (+49-1) 
- (modified) llvm/include/llvm/TargetParser/RISCVISAInfo.h (+5-1) 
- (modified) llvm/lib/TargetParser/RISCVISAInfo.cpp (+43-26) 


``````````diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 0c2ee446aa303..c903064b12cba 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -14391,9 +14391,10 @@ Value *CodeGenFunction::EmitRISCVCpuSupports(const CallExpr *E) {
   };
 
   int BitPos = RISCVISAInfo::getRISCVFeaturesBitPosition(FeatureStr);
+  int GroupID = RISCVISAInfo::getRISCVFeaturesGroupID(FeatureStr);
   assert(BitPos != -1 && "validation should have rejected this feature");
   Value *MaskV = Builder.getInt64(1ULL << BitPos);
-  Value *Bitset = Builder.CreateAnd(LoadFeatureBit(0), MaskV);
+  Value *Bitset = Builder.CreateAnd(LoadFeatureBit(GroupID), MaskV);
   return Builder.CreateICmpEQ(Bitset, MaskV);
 }
 
diff --git a/clang/test/CodeGen/builtin-cpu-supports.c b/clang/test/CodeGen/builtin-cpu-supports.c
index 92c407653e660..461e49d0fc7fa 100644
--- a/clang/test/CodeGen/builtin-cpu-supports.c
+++ b/clang/test/CodeGen/builtin-cpu-supports.c
@@ -270,20 +270,30 @@ int test_ppc(int a) {
 // CHECK-RV32-NEXT:    [[TMP6:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
 // CHECK-RV32-NEXT:    [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
 // CHECK-RV32-NEXT:    [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
-// CHECK-RV32-NEXT:    br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
+// CHECK-RV32-NEXT:    br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
 // CHECK-RV32:       if.then3:
 // CHECK-RV32-NEXT:    store i32 11, ptr [[RETVAL]], align 4
 // CHECK-RV32-NEXT:    br label [[RETURN]]
+// CHECK-RV32:       if.else4:
+// CHECK-RV32-NEXT:    [[TMP9:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 1), align 8
+// CHECK-RV32-NEXT:    [[TMP10:%.*]] = and i64 [[TMP9]], 8
+// CHECK-RV32-NEXT:    [[TMP11:%.*]] = icmp eq i64 [[TMP10]], 8
+// CHECK-RV32-NEXT:    br i1 [[TMP11]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
+// CHECK-RV32:       if.then5:
+// CHECK-RV32-NEXT:    store i32 11, ptr [[RETVAL]], align 4
+// CHECK-RV32-NEXT:    br label [[RETURN]]
 // CHECK-RV32:       if.end:
-// CHECK-RV32-NEXT:    br label [[IF_END4:%.*]]
-// CHECK-RV32:       if.end4:
-// CHECK-RV32-NEXT:    br label [[IF_END5:%.*]]
-// CHECK-RV32:       if.end5:
+// CHECK-RV32-NEXT:    br label [[IF_END6:%.*]]
+// CHECK-RV32:       if.end6:
+// CHECK-RV32-NEXT:    br label [[IF_END7:%.*]]
+// CHECK-RV32:       if.end7:
+// CHECK-RV32-NEXT:    br label [[IF_END8:%.*]]
+// CHECK-RV32:       if.end8:
 // CHECK-RV32-NEXT:    store i32 0, ptr [[RETVAL]], align 4
 // CHECK-RV32-NEXT:    br label [[RETURN]]
 // CHECK-RV32:       return:
-// CHECK-RV32-NEXT:    [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4
-// CHECK-RV32-NEXT:    ret i32 [[TMP9]]
+// CHECK-RV32-NEXT:    [[TMP12:%.*]] = load i32, ptr [[RETVAL]], align 4
+// CHECK-RV32-NEXT:    ret i32 [[TMP12]]
 //
 // CHECK-RV64-LABEL: define dso_local signext i32 @test_riscv(
 // CHECK-RV64-SAME: i32 noundef signext [[A:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -311,20 +321,30 @@ int test_ppc(int a) {
 // CHECK-RV64-NEXT:    [[TMP6:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 0), align 8
 // CHECK-RV64-NEXT:    [[TMP7:%.*]] = and i64 [[TMP6]], 2097152
 // CHECK-RV64-NEXT:    [[TMP8:%.*]] = icmp eq i64 [[TMP7]], 2097152
-// CHECK-RV64-NEXT:    br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_END:%.*]]
+// CHECK-RV64-NEXT:    br i1 [[TMP8]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
 // CHECK-RV64:       if.then3:
 // CHECK-RV64-NEXT:    store i32 11, ptr [[RETVAL]], align 4
 // CHECK-RV64-NEXT:    br label [[RETURN]]
+// CHECK-RV64:       if.else4:
+// CHECK-RV64-NEXT:    [[TMP9:%.*]] = load i64, ptr getelementptr inbounds ({ i32, [1 x i64] }, ptr @__riscv_feature_bits, i32 0, i32 1, i32 1), align 8
+// CHECK-RV64-NEXT:    [[TMP10:%.*]] = and i64 [[TMP9]], 8
+// CHECK-RV64-NEXT:    [[TMP11:%.*]] = icmp eq i64 [[TMP10]], 8
+// CHECK-RV64-NEXT:    br i1 [[TMP11]], label [[IF_THEN5:%.*]], label [[IF_END:%.*]]
+// CHECK-RV64:       if.then5:
+// CHECK-RV64-NEXT:    store i32 11, ptr [[RETVAL]], align 4
+// CHECK-RV64-NEXT:    br label [[RETURN]]
 // CHECK-RV64:       if.end:
-// CHECK-RV64-NEXT:    br label [[IF_END4:%.*]]
-// CHECK-RV64:       if.end4:
-// CHECK-RV64-NEXT:    br label [[IF_END5:%.*]]
-// CHECK-RV64:       if.end5:
+// CHECK-RV64-NEXT:    br label [[IF_END6:%.*]]
+// CHECK-RV64:       if.end6:
+// CHECK-RV64-NEXT:    br label [[IF_END7:%.*]]
+// CHECK-RV64:       if.end7:
+// CHECK-RV64-NEXT:    br label [[IF_END8:%.*]]
+// CHECK-RV64:       if.end8:
 // CHECK-RV64-NEXT:    store i32 0, ptr [[RETVAL]], align 4
 // CHECK-RV64-NEXT:    br label [[RETURN]]
 // CHECK-RV64:       return:
-// CHECK-RV64-NEXT:    [[TMP9:%.*]] = load i32, ptr [[RETVAL]], align 4
-// CHECK-RV64-NEXT:    ret i32 [[TMP9]]
+// CHECK-RV64-NEXT:    [[TMP12:%.*]] = load i32, ptr [[RETVAL]], align 4
+// CHECK-RV64-NEXT:    ret i32 [[TMP12]]
 //
 int test_riscv(int a) {
   __builtin_cpu_init();
@@ -334,6 +354,8 @@ int test_riscv(int a) {
     return 7;
   else if (__builtin_cpu_supports("v"))
     return 11;
+  else if (__builtin_cpu_supports("zcb"))
+    return 11;
   return 0;
 }
 #endif
diff --git a/compiler-rt/lib/builtins/cpu_model/riscv.c b/compiler-rt/lib/builtins/cpu_model/riscv.c
index 92931fae64fbf..0c443025b74c6 100644
--- a/compiler-rt/lib/builtins/cpu_model/riscv.c
+++ b/compiler-rt/lib/builtins/cpu_model/riscv.c
@@ -8,7 +8,7 @@
 
 #include "cpu_model.h"
 
-#define RISCV_FEATURE_BITS_LENGTH 1
+#define RISCV_FEATURE_BITS_LENGTH 2
 struct {
   unsigned length;
   unsigned long long features[RISCV_FEATURE_BITS_LENGTH];
@@ -105,6 +105,30 @@ struct {
 #define ZVKSH_BITMASK (1ULL << 58)
 #define ZVKT_GROUPID 0
 #define ZVKT_BITMASK (1ULL << 59)
+#define ZVE32X_GROUPID 0
+#define ZVE32X_BITMASK (1ULL << 60)
+#define ZVE32F_GROUPID 0
+#define ZVE32F_BITMASK (1ULL << 61)
+#define ZVE64X_GROUPID 0
+#define ZVE64X_BITMASK (1ULL << 62)
+#define ZVE64F_GROUPID 0
+#define ZVE64F_BITMASK (1ULL << 63)
+#define ZVE64D_GROUPID 1
+#define ZVE64D_BITMASK (1ULL << 0)
+#define ZIMOP_GROUPID 1
+#define ZIMOP_BITMASK (1ULL << 1)
+#define ZCA_GROUPID 1
+#define ZCA_BITMASK (1ULL << 2)
+#define ZCB_GROUPID 1
+#define ZCB_BITMASK (1ULL << 3)
+#define ZCD_GROUPID 1
+#define ZCD_BITMASK (1ULL << 4)
+#define ZCF_GROUPID 1
+#define ZCF_BITMASK (1ULL << 5)
+#define ZCMOP_GROUPID 1
+#define ZCMOP_BITMASK (1ULL << 6)
+#define ZAWRS_GROUPID 1
+#define ZAWRS_BITMASK (1ULL << 7)
 
 #if defined(__linux__)
 
@@ -169,6 +193,18 @@ static long syscall_impl_5_args(long number, long arg1, long arg2, long arg3,
 #define RISCV_HWPROBE_EXT_ZACAS (1ULL << 34)
 #define RISCV_HWPROBE_EXT_ZICOND (1ULL << 35)
 #define RISCV_HWPROBE_EXT_ZIHINTPAUSE (1ULL << 36)
+#define RISCV_HWPROBE_EXT_ZVE32X (1ULL << 37)
+#define RISCV_HWPROBE_EXT_ZVE32F (1ULL << 38)
+#define RISCV_HWPROBE_EXT_ZVE64X (1ULL << 39)
+#define RISCV_HWPROBE_EXT_ZVE64F (1ULL << 40)
+#define RISCV_HWPROBE_EXT_ZVE64D (1ULL << 41)
+#define RISCV_HWPROBE_EXT_ZIMOP (1ULL << 42)
+#define RISCV_HWPROBE_EXT_ZCA (1ULL << 43)
+#define RISCV_HWPROBE_EXT_ZCB (1ULL << 44)
+#define RISCV_HWPROBE_EXT_ZCD (1ULL << 45)
+#define RISCV_HWPROBE_EXT_ZCF (1ULL << 46)
+#define RISCV_HWPROBE_EXT_ZCMOP (1ULL << 47)
+#define RISCV_HWPROBE_EXT_ZAWRS (1ULL << 48)
 #define RISCV_HWPROBE_KEY_CPUPERF_0 5
 #define RISCV_HWPROBE_MISALIGNED_UNKNOWN (0 << 0)
 #define RISCV_HWPROBE_MISALIGNED_EMULATED (1ULL << 0)
@@ -271,6 +307,18 @@ static void initRISCVFeature(struct riscv_hwprobe Hwprobes[]) {
   SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZTSO);
   SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZACAS);
   SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZICOND);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32X);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE32F);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64X);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64F);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZVE64D);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZIMOP);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCA);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCB);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCD);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCF);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZCMOP);
+  SET_RISCV_HWPROBE_EXT_SINGLE_RISCV_FEATURE(ZAWRS);
 
   for (i = 0; i < RISCV_FEATURE_BITS_LENGTH; i++)
     __riscv_feature_bits.features[i] = features[i];
diff --git a/llvm/include/llvm/TargetParser/RISCVISAInfo.h b/llvm/include/llvm/TargetParser/RISCVISAInfo.h
index d71ff174bf0d2..2f81307dcfabf 100644
--- a/llvm/include/llvm/TargetParser/RISCVISAInfo.h
+++ b/llvm/include/llvm/TargetParser/RISCVISAInfo.h
@@ -80,10 +80,14 @@ class RISCVISAInfo {
                                      std::set<StringRef> &EnabledFeatureNames,
                                      StringMap<StringRef> &DescMap);
 
-  /// Return the bit position (in group 0) of __riscv_feature_bits.  Returns
+  /// Return the bit position of __riscv_feature_bits.  Returns
   /// -1 if not supported.
   static int getRISCVFeaturesBitPosition(StringRef Ext);
 
+  /// Return the group id of __riscv_feature_bits.  Returns
+  /// -1 if not supported.
+  static int getRISCVFeaturesGroupID(StringRef Ext);
+
 private:
   RISCVISAInfo(unsigned XLen) : XLen(XLen) {}
 
diff --git a/llvm/lib/TargetParser/RISCVISAInfo.cpp b/llvm/lib/TargetParser/RISCVISAInfo.cpp
index 9f650b87f2b39..033bf096625aa 100644
--- a/llvm/lib/TargetParser/RISCVISAInfo.cpp
+++ b/llvm/lib/TargetParser/RISCVISAInfo.cpp
@@ -1023,40 +1023,57 @@ std::string RISCVISAInfo::getTargetFeatureForExtension(StringRef Ext) {
 
 struct RISCVExtBit {
   const StringLiteral ext;
+  uint8_t groupid;
   uint8_t bitpos;
 };
 
-/// Maps extensions with assigned bit positions within group 0 of
-/// __riscv_features_bits to their respective bit position.  At the
-/// moment all extensions are within group 0.
-constexpr static RISCVExtBit RISCVGroup0BitPositions[] = {
-    {"a", 0},          {"c", 2},
-    {"d", 3},          {"f", 5},
-    {"i", 8},          {"m", 12},
-    {"v", 21},         {"zacas", 26},
-    {"zba", 27},       {"zbb", 28},
-    {"zbc", 29},       {"zbkb", 30},
-    {"zbkc", 31},      {"zbkx", 32},
-    {"zbs", 33},       {"zfa", 34},
-    {"zfh", 35},       {"zfhmin", 36},
-    {"zicboz", 37},    {"zicond", 38},
-    {"zihintntl", 39}, {"zihintpause", 40},
-    {"zknd", 41},      {"zkne", 42},
-    {"zknh", 43},      {"zksed", 44},
-    {"zksh", 45},      {"zkt", 46},
-    {"ztso", 47},      {"zvbb", 48},
-    {"zvbc", 49},      {"zvfh", 50},
-    {"zvfhmin", 51},   {"zvkb", 52},
-    {"zvkg", 53},      {"zvkned", 54},
-    {"zvknha", 55},    {"zvknhb", 56},
-    {"zvksed", 57},    {"zvksh", 58},
-    {"zvkt", 59}};
+constexpr static RISCVExtBit RISCVBitPositions[] = {
+    {"a", 0, 0},          {"c", 0, 2},
+    {"d", 0, 3},          {"f", 0, 5},
+    {"i", 0, 8},          {"m", 0, 12},
+    {"v", 0, 21},         {"zacas", 0, 26},
+    {"zba", 0, 27},       {"zbb", 0, 28},
+    {"zbc", 0, 29},       {"zbkb", 0, 30},
+    {"zbkc", 0, 31},      {"zbkx", 0, 32},
+    {"zbs", 0, 33},       {"zfa", 0, 34},
+    {"zfh", 0, 35},       {"zfhmin", 0, 36},
+    {"zicboz", 0, 37},    {"zicond", 0, 38},
+    {"zihintntl", 0, 39}, {"zihintpause", 0, 40},
+    {"zknd", 0, 41},      {"zkne", 0, 42},
+    {"zknh", 0, 43},      {"zksed", 0, 44},
+    {"zksh", 0, 45},      {"zkt", 0, 46},
+    {"ztso", 0, 47},      {"zvbb", 0, 48},
+    {"zvbc", 0, 49},      {"zvfh", 0, 50},
+    {"zvfhmin", 0, 51},   {"zvkb", 0, 52},
+    {"zvkg", 0, 53},      {"zvkned", 0, 54},
+    {"zvknha", 0, 55},    {"zvknhb", 0, 56},
+    {"zvksed", 0, 57},    {"zvksh", 0, 58},
+    {"zvkt", 0, 59},      {"zve32x", 0, 60},
+    {"zve32f", 0, 61},    {"zve64x", 0, 62},
+    {"zve64x", 0, 63},    {"zve64d", 1, 0},
+    {"zimop", 1, 1},      {"zca", 1, 2},
+    {"zcb", 1, 3},        {"zcd", 1, 4},
+    {"zcf", 1, 5},        {"zcmop", 1, 6},
+    {"zawrs", 1, 7}};
+
 int RISCVISAInfo::getRISCVFeaturesBitPosition(StringRef Ext) {
   // Note that this code currently accepts mixed case extension names, but
   // does not handle extension versions at all.  That's probably fine because
   // there's only one extension version in the __riscv_feature_bits vector.
-  for (auto E : RISCVGroup0BitPositions)
+  for (auto E : RISCVBitPositions)
     if (E.ext.equals_insensitive(Ext))
       return E.bitpos;
   return -1;
 }
+
+// TODO: merge getRISCVFeaturesBitPosition and getRISCVFeaturesGroupID into
+// single function.
+int RISCVISAInfo::getRISCVFeaturesGroupID(StringRef Ext) {
+  // Note that this code currently accepts mixed case extension names, but
+  // does not handle extension versions at all.  That's probably fine because
+  // there's only one extension version in the __riscv_feature_bits vector.
+  for (auto E : RISCVBitPositions)
+    if (E.ext.equals_insensitive(Ext))
+      return E.groupid;
+  return -1;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/101632


More information about the llvm-commits mailing list