4vtomat created this revision.
Herald added subscribers: jobnoorman, luke, VincentWu, vkmr, frasercrmck, 
evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, 
jocewei, PkmX, arphaman, the_o, brucehoult, MartinMosbeck, rogfer01, 
edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, 
simoncook, johnrusso, rbar, asb, arichardson.
Herald added a project: All.
4vtomat requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, pcwang-thead, eopXD, 
MaskRay.
Herald added projects: clang, LLVM.

Since we don't always need the vendor extension to be in riscv_vector.td,
so it's better to make it be in separated header.

Depends on D148223 <https://reviews.llvm.org/D148223>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148308

Files:
  clang/include/clang/Basic/BuiltinsRISCVVector.def
  clang/include/clang/Basic/CMakeLists.txt
  clang/include/clang/Basic/riscv_sifive_vcix.td
  clang/include/clang/Basic/riscv_vector.td
  clang/include/clang/Basic/riscv_vector_common.td
  clang/include/clang/Sema/RISCVIntrinsicManager.h
  clang/include/clang/Sema/Sema.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Headers/CMakeLists.txt
  clang/lib/Headers/sifive_vector.h
  clang/lib/Parse/ParsePragma.cpp
  clang/lib/Sema/SemaLookup.cpp
  clang/lib/Sema/SemaRISCVVectorLookup.cpp
  
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x-rv64.c
  
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x.c
  
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv-rv64.c
  
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv.c
  
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv-rv64.c
  
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv.c
  
clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvw.c
  
clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/xsfvcp-index-out-of-range.c
  clang/test/Sema/riscv-bad-intrinsic-pragma.c
  clang/utils/TableGen/TableGen.cpp
  llvm/docs/CommandGuide/tblgen.rst

Index: llvm/docs/CommandGuide/tblgen.rst
===================================================================
--- llvm/docs/CommandGuide/tblgen.rst
+++ llvm/docs/CommandGuide/tblgen.rst
@@ -348,6 +348,14 @@
 
   Generate ``riscv_vector_builtin_cg.inc`` for Clang.
 
+.. option:: -gen-riscv-sifive-vcix-builtins
+
+  Generate ``riscv_sifive_vcix_builtins.inc`` for Clang.
+
+.. option:: -gen-riscv-sifive-vcix-builtin-codegen
+
+  Generate ``riscv_sifive_vcix_builtin_cg.inc`` for Clang.
+
 .. option:: -gen-attr-docs
 
   Generate attribute documentation.
Index: clang/utils/TableGen/TableGen.cpp
===================================================================
--- clang/utils/TableGen/TableGen.cpp
+++ clang/utils/TableGen/TableGen.cpp
@@ -91,6 +91,9 @@
   GenRISCVVectorBuiltins,
   GenRISCVVectorBuiltinCG,
   GenRISCVVectorBuiltinSema,
+  GenRISCVSiFiveVCIXBuiltins,
+  GenRISCVSiFiveVCIXBuiltinCG,
+  GenRISCVSiFiveVCIXBuiltinSema,
   GenAttrDocs,
   GenDiagDocs,
   GenOptDocs,
@@ -251,6 +254,12 @@
                    "Generate riscv_vector_builtin_cg.inc for clang"),
         clEnumValN(GenRISCVVectorBuiltinSema, "gen-riscv-vector-builtin-sema",
                    "Generate riscv_vector_builtin_sema.inc for clang"),
+        clEnumValN(GenRISCVSiFiveVCIXBuiltins, "gen-riscv-sifive-vcix-builtins",
+                   "Generate riscv_sifive_vcix_builtins.inc for clang"),
+        clEnumValN(GenRISCVSiFiveVCIXBuiltinCG, "gen-riscv-sifive-vcix-builtin-codegen",
+                   "Generate riscv_sifive_vcix_builtin_cg.inc for clang"),
+        clEnumValN(GenRISCVSiFiveVCIXBuiltinSema, "gen-riscv-sifive-vcix-builtin-sema",
+                   "Generate riscv_sifive_vcix_builtin_sema.inc for clang"),
         clEnumValN(GenAttrDocs, "gen-attr-docs",
                    "Generate attribute documentation"),
         clEnumValN(GenDiagDocs, "gen-diag-docs",
@@ -472,6 +481,15 @@
   case GenRISCVVectorBuiltinSema:
     EmitRVVBuiltinSema(Records, OS);
     break;
+  case GenRISCVSiFiveVCIXBuiltins:
+    EmitRVVBuiltins(Records, OS);
+    break;
+  case GenRISCVSiFiveVCIXBuiltinCG:
+    EmitRVVBuiltinCG(Records, OS);
+    break;
+  case GenRISCVSiFiveVCIXBuiltinSema:
+    EmitRVVBuiltinSema(Records, OS);
+    break;
   case GenAttrDocs:
     EmitClangAttrDocs(Records, OS);
     break;
Index: clang/test/Sema/riscv-bad-intrinsic-pragma.c
===================================================================
--- clang/test/Sema/riscv-bad-intrinsic-pragma.c
+++ clang/test/Sema/riscv-bad-intrinsic-pragma.c
@@ -2,7 +2,7 @@
 // RUN:            2>&1 | FileCheck %s
 
 #pragma clang riscv intrinsic vvvv
-// CHECK:      warning: unexpected argument 'vvvv' to '#pragma riscv'; expected 'vector' [-Wignored-pragmas]
+// CHECK:      warning: unexpected argument 'vvvv' to '#pragma riscv'; expected 'vector' or 'sifive_vcix' [-Wignored-pragmas]
 
 #pragma clang riscv what + 3241
 // CHECK:      warning: unexpected argument 'what' to '#pragma riscv'; expected 'intrinsic' [-Wignored-pragmas]
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/xsfvcp-index-out-of-range.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/xsfvcp-index-out-of-range.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-handcrafted/xsfvcp-index-out-of-range.c
@@ -5,7 +5,7 @@
 // RUN:   -target-feature +xsfvcp \
 // RUN:   -fsyntax-only -verify %s
 
-#include <riscv_vector.h>
+#include <sifive_vector.h>
 
 #define p27_26 (0b11)
 #define p26    (0b1)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvw.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvw.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvw.c
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -triple riscv32 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV32 %s
 // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
 
-#include <riscv_vector.h>
+#include <sifive_vector.h>
 
 #define p27_26 (0b11)
 #define p26    (0b1)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv.c
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -triple riscv32 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV32 %s
 // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
 
-#include <riscv_vector.h>
+#include <sifive_vector.h>
 
 #define p27_26 (0b11)
 #define p26    (0b1)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv-rv64.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv-rv64.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xvv-rv64.c
@@ -2,7 +2,7 @@
 // REQUIRES: riscv-registered-target
 // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
 
-#include <riscv_vector.h>
+#include <sifive_vector.h>
 
 #define p27_26 (0b11)
 
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv.c
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -triple riscv32 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV32 %s
 // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zfh -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
 
-#include <riscv_vector.h>
+#include <sifive_vector.h>
 
 #define p27_26 (0b11)
 #define p26    (0b1)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv-rv64.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv-rv64.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-xv-rv64.c
@@ -2,7 +2,7 @@
 // REQUIRES: riscv-registered-target
 // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
 
-#include <riscv_vector.h>
+#include <sifive_vector.h>
 
 #define p27_26 (0b11)
 #define p11_7  (0b11111)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x.c
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -triple riscv32 -target-feature +v -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV32 %s
 // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
 
-#include <riscv_vector.h>
+#include <sifive_vector.h>
 
 #define p27_26 (0b11)
 #define p24_20 (0b11111)
Index: clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x-rv64.c
===================================================================
--- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x-rv64.c
+++ clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/xsfvcp-x-rv64.c
@@ -1,7 +1,7 @@
 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
 // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvcp -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | FileCheck --check-prefix=CHECK-RV64 %s
 
-#include <riscv_vector.h>
+#include <sifive_vector.h>
 
 #define p27_26 (0b11)
 #define p24_20 (0b11111)
Index: clang/lib/Sema/SemaRISCVVectorLookup.cpp
===================================================================
--- clang/lib/Sema/SemaRISCVVectorLookup.cpp
+++ clang/lib/Sema/SemaRISCVVectorLookup.cpp
@@ -28,6 +28,8 @@
 using namespace clang;
 using namespace clang::RISCV;
 
+using IntrinsicKind = sema::RISCVIntrinsicManager::IntrinsicKind;
+
 namespace {
 
 // Function definition of a RVV intrinsic.
@@ -58,16 +60,35 @@
 #undef DECL_SIGNATURE_TABLE
 };
 
+static const PrototypeDescriptor RVSiFiveVCIXSignatureTable[] = {
+#define DECL_SIGNATURE_TABLE
+#include "clang/Basic/riscv_sifive_vcix_builtin_sema.inc"
+#undef DECL_SIGNATURE_TABLE
+};
+
 static const RVVIntrinsicRecord RVVIntrinsicRecords[] = {
 #define DECL_INTRINSIC_RECORDS
 #include "clang/Basic/riscv_vector_builtin_sema.inc"
 #undef DECL_INTRINSIC_RECORDS
 };
 
+static const RVVIntrinsicRecord RVSiFiveVCIXIntrinsicRecords[] = {
+#define DECL_INTRINSIC_RECORDS
+#include "clang/Basic/riscv_sifive_vcix_builtin_sema.inc"
+#undef DECL_INTRINSIC_RECORDS
+};
+
 // Get subsequence of signature table.
-static ArrayRef<PrototypeDescriptor> ProtoSeq2ArrayRef(uint16_t Index,
-                                                       uint8_t Length) {
-  return ArrayRef(&RVVSignatureTable[Index], Length);
+static ArrayRef<PrototypeDescriptor>
+ProtoSeq2ArrayRef(IntrinsicKind K, uint16_t Index, uint8_t Length) {
+  switch (K) {
+  default:
+    llvm_unreachable("Unsupported intrinsic kind.");
+  case IntrinsicKind::RVV:
+    return ArrayRef(&RVVSignatureTable[Index], Length);
+  case IntrinsicKind::SIFIVE_VCIX:
+    return ArrayRef(&RVSiFiveVCIXSignatureTable[Index], Length);
+  }
 }
 
 static QualType RVVType2Qual(ASTContext &Context, const RVVType *Type) {
@@ -172,123 +193,132 @@
   bool HasRV64 = TI.hasFeature("64bit");
   bool HasFullMultiply = TI.hasFeature("v");
 
-  // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
-  // in RISCVVEmitter.cpp.
-  for (auto &Record : RVVIntrinsicRecords) {
-    // Create Intrinsics for each type and LMUL.
-    BasicType BaseType = BasicType::Unknown;
-    ArrayRef<PrototypeDescriptor> BasicProtoSeq =
-        ProtoSeq2ArrayRef(Record.PrototypeIndex, Record.PrototypeLength);
-    ArrayRef<PrototypeDescriptor> SuffixProto =
-        ProtoSeq2ArrayRef(Record.SuffixIndex, Record.SuffixLength);
-    ArrayRef<PrototypeDescriptor> OverloadedSuffixProto = ProtoSeq2ArrayRef(
-        Record.OverloadedSuffixIndex, Record.OverloadedSuffixSize);
-
-    PolicyScheme UnMaskedPolicyScheme =
-        static_cast<PolicyScheme>(Record.UnMaskedPolicyScheme);
-    PolicyScheme MaskedPolicyScheme =
-        static_cast<PolicyScheme>(Record.MaskedPolicyScheme);
-
-    const Policy DefaultPolicy;
-
-    llvm::SmallVector<PrototypeDescriptor> ProtoSeq =
-        RVVIntrinsic::computeBuiltinTypes(BasicProtoSeq, /*IsMasked=*/false,
-                                          /*HasMaskedOffOperand=*/false,
-                                          Record.HasVL, Record.NF,
-                                          UnMaskedPolicyScheme, DefaultPolicy);
-
-    llvm::SmallVector<PrototypeDescriptor> ProtoMaskSeq =
-        RVVIntrinsic::computeBuiltinTypes(
-            BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
-            Record.HasVL, Record.NF, MaskedPolicyScheme, DefaultPolicy);
-
-    bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
-    bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
-    SmallVector<Policy> SupportedUnMaskedPolicies =
-        RVVIntrinsic::getSupportedUnMaskedPolicies();
-    SmallVector<Policy> SupportedMaskedPolicies =
-        RVVIntrinsic::getSupportedMaskedPolicies(Record.HasTailPolicy,
-                                                 Record.HasMaskPolicy);
-
-    for (unsigned int TypeRangeMaskShift = 0;
-         TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
-         ++TypeRangeMaskShift) {
-      unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
-      BaseType = static_cast<BasicType>(BaseTypeI);
-
-      if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI)
-        continue;
-
-      // Check requirement.
-      if (((Record.RequiredExtensions & RVV_REQ_RV64) == RVV_REQ_RV64) &&
-          !HasRV64)
-        continue;
-
-      if ((BaseType == BasicType::Int64) &&
-          ((Record.RequiredExtensions & RVV_REQ_FullMultiply) ==
-           RVV_REQ_FullMultiply) &&
-          !HasFullMultiply)
-        continue;
-
-      // Expanded with different LMUL.
-      for (int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
-        if (!(Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
+  auto ConstructRVVIntrinsics = [&](ArrayRef<RVVIntrinsicRecord> Recs,
+                                    IntrinsicKind K) {
+    // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics
+    // in RISCVVEmitter.cpp.
+    for (auto &Record : Recs) {
+      // Create Intrinsics for each type and LMUL.
+      BasicType BaseType = BasicType::Unknown;
+      ArrayRef<PrototypeDescriptor> BasicProtoSeq =
+          ProtoSeq2ArrayRef(K, Record.PrototypeIndex, Record.PrototypeLength);
+      ArrayRef<PrototypeDescriptor> SuffixProto =
+          ProtoSeq2ArrayRef(K, Record.SuffixIndex, Record.SuffixLength);
+      ArrayRef<PrototypeDescriptor> OverloadedSuffixProto = ProtoSeq2ArrayRef(
+          K, Record.OverloadedSuffixIndex, Record.OverloadedSuffixSize);
+
+      PolicyScheme UnMaskedPolicyScheme =
+          static_cast<PolicyScheme>(Record.UnMaskedPolicyScheme);
+      PolicyScheme MaskedPolicyScheme =
+          static_cast<PolicyScheme>(Record.MaskedPolicyScheme);
+
+      const Policy DefaultPolicy;
+
+      llvm::SmallVector<PrototypeDescriptor> ProtoSeq =
+          RVVIntrinsic::computeBuiltinTypes(BasicProtoSeq, /*IsMasked=*/false,
+                                            /*HasMaskedOffOperand=*/false,
+                                            Record.HasVL, Record.NF,
+                                            UnMaskedPolicyScheme, DefaultPolicy);
+
+      llvm::SmallVector<PrototypeDescriptor> ProtoMaskSeq =
+          RVVIntrinsic::computeBuiltinTypes(
+              BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
+              Record.HasVL, Record.NF, MaskedPolicyScheme, DefaultPolicy);
+
+      bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
+      bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
+      SmallVector<Policy> SupportedUnMaskedPolicies =
+          RVVIntrinsic::getSupportedUnMaskedPolicies();
+      SmallVector<Policy> SupportedMaskedPolicies =
+          RVVIntrinsic::getSupportedMaskedPolicies(Record.HasTailPolicy,
+                                                   Record.HasMaskPolicy);
+
+      for (unsigned int TypeRangeMaskShift = 0;
+           TypeRangeMaskShift <= static_cast<unsigned int>(BasicType::MaxOffset);
+           ++TypeRangeMaskShift) {
+        unsigned int BaseTypeI = 1 << TypeRangeMaskShift;
+        BaseType = static_cast<BasicType>(BaseTypeI);
+
+        if ((BaseTypeI & Record.TypeRangeMask) != BaseTypeI)
           continue;
 
-        std::optional<RVVTypes> Types =
-            TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
-
-        // Ignored to create new intrinsic if there are any illegal types.
-        if (!Types.has_value())
+        // Check requirement.
+        if (((Record.RequiredExtensions & RVV_REQ_RV64) == RVV_REQ_RV64) &&
+            !HasRV64)
           continue;
 
-        std::string SuffixStr = RVVIntrinsic::getSuffixStr(
-            TypeCache, BaseType, Log2LMUL, SuffixProto);
-        std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
-            TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
-
-        // Create non-masked intrinsic.
-        InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
-                         UnMaskedHasPolicy, DefaultPolicy);
+        if ((BaseType == BasicType::Int64) &&
+            ((Record.RequiredExtensions & RVV_REQ_FullMultiply) ==
+             RVV_REQ_FullMultiply) &&
+            !HasFullMultiply)
+          continue;
 
-        // Create non-masked policy intrinsic.
-        if (Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
-          for (auto P : SupportedUnMaskedPolicies) {
+        // Expanded with different LMUL.
+        for (int Log2LMUL = -3; Log2LMUL <= 3; Log2LMUL++) {
+          if (!(Record.Log2LMULMask & (1 << (Log2LMUL + 3))))
+            continue;
+
+          std::optional<RVVTypes> Types =
+              TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoSeq);
+
+          // Ignored to create new intrinsic if there are any illegal types.
+          if (!Types.has_value())
+            continue;
+
+          std::string SuffixStr = RVVIntrinsic::getSuffixStr(
+              TypeCache, BaseType, Log2LMUL, SuffixProto);
+          std::string OverloadedSuffixStr = RVVIntrinsic::getSuffixStr(
+              TypeCache, BaseType, Log2LMUL, OverloadedSuffixProto);
+
+          // Create non-masked intrinsic.
+          InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, false, *Types,
+                           UnMaskedHasPolicy, DefaultPolicy);
+
+          // Create non-masked policy intrinsic.
+          if (Record.UnMaskedPolicyScheme != PolicyScheme::SchemeNone) {
+            for (auto P : SupportedUnMaskedPolicies) {
+              llvm::SmallVector<PrototypeDescriptor> PolicyPrototype =
+                  RVVIntrinsic::computeBuiltinTypes(
+                      BasicProtoSeq, /*IsMasked=*/false,
+                      /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
+                      UnMaskedPolicyScheme, P);
+              std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
+                  BaseType, Log2LMUL, Record.NF, PolicyPrototype);
+              InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
+                               /*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
+                               P);
+            }
+          }
+          if (!Record.HasMasked)
+            continue;
+          // Create masked intrinsic.
+          std::optional<RVVTypes> MaskTypes =
+              TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
+          InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
+                           *MaskTypes, MaskedHasPolicy, DefaultPolicy);
+          if (Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
+            continue;
+          // Create masked policy intrinsic.
+          for (auto P : SupportedMaskedPolicies) {
             llvm::SmallVector<PrototypeDescriptor> PolicyPrototype =
                 RVVIntrinsic::computeBuiltinTypes(
-                    BasicProtoSeq, /*IsMasked=*/false,
-                    /*HasMaskedOffOperand=*/false, Record.HasVL, Record.NF,
-                    UnMaskedPolicyScheme, P);
+                    BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
+                    Record.HasVL, Record.NF, MaskedPolicyScheme, P);
             std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
                 BaseType, Log2LMUL, Record.NF, PolicyPrototype);
             InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
-                             /*IsMask=*/false, *PolicyTypes, UnMaskedHasPolicy,
-                             P);
+                             /*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P);
           }
-        }
-        if (!Record.HasMasked)
-          continue;
-        // Create masked intrinsic.
-        std::optional<RVVTypes> MaskTypes =
-            TypeCache.computeTypes(BaseType, Log2LMUL, Record.NF, ProtoMaskSeq);
-        InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr, true,
-                         *MaskTypes, MaskedHasPolicy, DefaultPolicy);
-        if (Record.MaskedPolicyScheme == PolicyScheme::SchemeNone)
-          continue;
-        // Create masked policy intrinsic.
-        for (auto P : SupportedMaskedPolicies) {
-          llvm::SmallVector<PrototypeDescriptor> PolicyPrototype =
-              RVVIntrinsic::computeBuiltinTypes(
-                  BasicProtoSeq, /*IsMasked=*/true, Record.HasMaskedOffOperand,
-                  Record.HasVL, Record.NF, MaskedPolicyScheme, P);
-          std::optional<RVVTypes> PolicyTypes = TypeCache.computeTypes(
-              BaseType, Log2LMUL, Record.NF, PolicyPrototype);
-          InitRVVIntrinsic(Record, SuffixStr, OverloadedSuffixStr,
-                           /*IsMask=*/true, *PolicyTypes, MaskedHasPolicy, P);
-        }
-      } // End for different LMUL
-    } // End for different TypeRange
-  }
+        } // End for different LMUL
+      } // End for different TypeRange
+    }
+  };
+  if (S.DeclareRISCVVBuiltins)
+    ConstructRVVIntrinsics(RVVIntrinsicRecords,
+                           IntrinsicKind::RVV);
+  if (S.DeclareRISCVVCIXBuiltins)
+    ConstructRVVIntrinsics(RVSiFiveVCIXIntrinsicRecords,
+                           IntrinsicKind::SIFIVE_VCIX);
 }
 
 // Compute name and signatures for intrinsic with practical types.
Index: clang/lib/Sema/SemaLookup.cpp
===================================================================
--- clang/lib/Sema/SemaLookup.cpp
+++ clang/lib/Sema/SemaLookup.cpp
@@ -932,7 +932,7 @@
         }
       }
 
-      if (DeclareRISCVVBuiltins) {
+      if (DeclareRISCVVBuiltins || DeclareRISCVVCIXBuiltins) {
         if (!RVIntrinsicManager)
           RVIntrinsicManager = CreateRISCVIntrinsicManager(*this);
 
Index: clang/lib/Parse/ParsePragma.cpp
===================================================================
--- clang/lib/Parse/ParsePragma.cpp
+++ clang/lib/Parse/ParsePragma.cpp
@@ -4023,6 +4023,7 @@
 }
 
 // Handle '#pragma clang riscv intrinsic vector'.
+//        '#pragma clang riscv intrinsic sifive_vcix'.
 void PragmaRISCVHandler::HandlePragma(Preprocessor &PP,
                                       PragmaIntroducer Introducer,
                                       Token &FirstToken) {
@@ -4038,9 +4039,11 @@
 
   PP.Lex(Tok);
   II = Tok.getIdentifierInfo();
-  if (!II || !II->isStr("vector")) {
+  StringRef IntrinsicClass = II->getName();
+  if (!II || !(II->isStr("vector") || II->isStr("sifive_vcix"))) {
     PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument)
-        << PP.getSpelling(Tok) << "riscv" << /*Expected=*/true << "'vector'";
+        << PP.getSpelling(Tok) << "riscv" << /*Expected=*/true
+        << "'vector' or 'sifive_vcix'";
     return;
   }
 
@@ -4051,5 +4054,8 @@
     return;
   }
 
-  Actions.DeclareRISCVVBuiltins = true;
+  if (IntrinsicClass == "vector")
+    Actions.DeclareRISCVVBuiltins = true;
+  else if (IntrinsicClass == "sifive_vcix")
+    Actions.DeclareRISCVVCIXBuiltins = true;
 }
Index: clang/lib/Headers/sifive_vector.h
===================================================================
--- /dev/null
+++ clang/lib/Headers/sifive_vector.h
@@ -0,0 +1,16 @@
+//===----- sifive_vector.h - SiFive Vector definitions --------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _SIFIVE_VECTOR_H_
+#define _SIFIVE_VECTOR_H_
+
+#include "riscv_vector.h"
+
+#pragma clang riscv intrinsic sifive_vcix
+
+#endif //_SIFIVE_VECTOR_H_
Index: clang/lib/Headers/CMakeLists.txt
===================================================================
--- clang/lib/Headers/CMakeLists.txt
+++ clang/lib/Headers/CMakeLists.txt
@@ -98,6 +98,10 @@
   htmxlintrin.h
   )
 
+set(sifive_files
+  sifive_vector.h
+  )
+
 set(systemz_files
   s390intrin.h
   vecintrin.h
@@ -244,6 +248,7 @@
   ${opencl_files}
   ${ppc_files}
   ${ppc_htm_files}
+  ${sifive_files}
   ${systemz_files}
   ${ve_files}
   ${x86_files}
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -19966,6 +19966,8 @@
 
   // Vector builtins are handled from here.
 #include "clang/Basic/riscv_vector_builtin_cg.inc"
+  // SiFive VCIX builtins are handled from here.
+#include "clang/Basic/riscv_sifive_vcix_builtin_cg.inc"
   }
 
   assert(ID != Intrinsic::not_intrinsic);
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -1621,6 +1621,9 @@
   /// Indicate RISC-V vector builtin functions enabled or not.
   bool DeclareRISCVVBuiltins = false;
 
+  /// Indicate RISC-V Sifive vcix builtin functions enabled or not.
+  bool DeclareRISCVVCIXBuiltins = false;
+
 private:
   std::unique_ptr<sema::RISCVIntrinsicManager> RVIntrinsicManager;
 
Index: clang/include/clang/Sema/RISCVIntrinsicManager.h
===================================================================
--- clang/include/clang/Sema/RISCVIntrinsicManager.h
+++ clang/include/clang/Sema/RISCVIntrinsicManager.h
@@ -22,6 +22,8 @@
 namespace sema {
 class RISCVIntrinsicManager {
 public:
+  enum class IntrinsicKind : uint8_t { RVV, SIFIVE_VCIX };
+
   virtual ~RISCVIntrinsicManager() = default;
 
   // Create RISC-V intrinsic and insert into symbol table and return true if
Index: clang/include/clang/Basic/riscv_vector_common.td
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/riscv_vector_common.td
@@ -0,0 +1,239 @@
+//==------ riscv_vector_common.td - RISC-V V-ext builtin class ------------===//
+//
+//  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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines RVV builtin base class for RISC-V V-extension.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+// Each record of the class RVVBuiltin defines a collection of builtins (i.e.
+// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1",
+// "vadd_vv_i32m2", etc).
+//
+// The elements of this collection are defined by an instantiation process the
+// range of which is specified by the cross product of the LMUL attribute and
+// every element in the attribute TypeRange. By default builtins have LMUL = [1,
+// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we
+// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL.
+//
+// LMUL represents the fact that the types of values used by that builtin are
+// values generated by instructions that are executed under that LMUL. However,
+// this does not mean the builtin is necessarily lowered into an instruction
+// that executes under the specified LMUL. An example where this happens are
+// loads and stores of masks. A mask like `vbool8_t` can be generated, for
+// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two
+// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will
+// be performed under LMUL=1 because mask registers are not grouped.
+//
+// TypeRange is a non-empty sequence of basic types:
+//
+//   c: int8_t (i8)
+//   s: int16_t (i16)
+//   i: int32_t (i32)
+//   l: int64_t (i64)
+//   x: float16_t (half)
+//   f: float32_t (float)
+//   d: float64_t (double)
+//
+// This way, given an LMUL, a record with a TypeRange "sil" will cause the
+// definition of 3 builtins. Each type "t" in the TypeRange (in this example
+// they are int16_t, int32_t, int64_t) is used as a parameter that drives the
+// definition of that particular builtin (for the given LMUL).
+//
+// During the instantiation, types can be transformed or modified using type
+// transformers. Given a type "t" the following primitive type transformers can
+// be applied to it to yield another type.
+//
+//   e: type of "t" as is (identity)
+//   v: computes a vector type whose element type is "t" for the current LMUL
+//   w: computes a vector type identical to what 'v' computes except for the
+//      element type which is twice as wide as the element type of 'v'
+//   q: computes a vector type identical to what 'v' computes except for the
+//      element type which is four times as wide as the element type of 'v'
+//   o: computes a vector type identical to what 'v' computes except for the
+//      element type which is eight times as wide as the element type of 'v'
+//   m: computes a vector type identical to what 'v' computes except for the
+//      element type which is bool
+//   0: void type, ignores "t"
+//   z: size_t, ignores "t"
+//   t: ptrdiff_t, ignores "t"
+//   u: unsigned long, ignores "t"
+//   l: long, ignores "t"
+//
+// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
+// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
+// Accordingly "w" would yield __rvv_int64m2_t.
+//
+// A type transformer can be prefixed by other non-primitive type transformers.
+//
+//   P: constructs a pointer to the current type
+//   C: adds const to the type
+//   K: requires the integer type to be a constant expression
+//   U: given an integer type or vector type, computes its unsigned variant
+//   I: given a vector type, compute the vector type with integer type
+//      elements of the same width
+//   F: given a vector type, compute the vector type with floating-point type
+//      elements of the same width
+//   S: given a vector type, computes its equivalent one for LMUL=1. This is a
+//      no-op if the vector was already LMUL=1
+//   (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a
+//      vector type (SEW and LMUL) and EEW (8/16/32/64), computes its
+//      equivalent integer vector type with EEW and corresponding ELMUL (elmul =
+//      (eew/sew) * lmul). For example, vector type is __rvv_float16m4
+//      (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector
+//      type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new
+//      builtins if its equivalent type has illegal lmul.
+//   (FixedSEW:Value): Given a vector type (SEW and LMUL), and computes another
+//      vector type which only changed SEW as given value. Ignore to define a new
+//      builtin if its equivalent type has illegal lmul or the SEW does not changed.
+//   (SFixedLog2LMUL:Value): Smaller Fixed Log2LMUL. Given a vector type (SEW
+//      and LMUL), and computes another vector type which only changed LMUL as
+//      given value. The new LMUL should be smaller than the old one. Ignore to
+//      define a new builtin if its equivalent type has illegal lmul.
+//   (LFixedLog2LMUL:Value): Larger Fixed Log2LMUL. Given a vector type (SEW
+//      and LMUL), and computes another vector type which only changed LMUL as
+//      given value. The new LMUL should be larger than the old one. Ignore to
+//      define a new builtin if its equivalent type has illegal lmul.
+//
+// Following with the example above, if t is "i", then "Ue" will yield unsigned
+// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would
+// yield __rvv_float64m2_t, etc.
+//
+// Each builtin is then defined by applying each type in TypeRange against the
+// sequence of type transformers described in Suffix and Prototype.
+//
+// The name of the builtin is defined by the Name attribute (which defaults to
+// the name of the class) appended (separated with an underscore) the Suffix
+// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
+// the builtin generated will be __builtin_rvv_foo_i32m1 and
+// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
+// type transformer (say "vv") each of the types is separated with an
+// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
+//
+// The C/C++ prototype of the builtin is defined by the Prototype attribute.
+// Prototype is a non-empty sequence of type transformers, the first of which
+// is the return type of the builtin and the rest are the parameters of the
+// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si"
+// a first builtin will have type
+// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin
+// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again
+// under LMUL=1).
+//
+// There are a number of attributes that are used to constraint the number and
+// shape of the builtins generated. Refer to the comments below for them.
+
+class PolicyScheme<int val>{
+  int Value = val;
+}
+def NonePolicy : PolicyScheme<0>;
+def HasPassthruOperand : PolicyScheme<1>;
+def HasPolicyOperand : PolicyScheme<2>;
+
+class RVVBuiltin<string suffix, string prototype, string type_range,
+                 string overloaded_suffix = ""> {
+  // Base name that will be prepended in __builtin_rvv_ and appended the
+  // computed Suffix.
+  string Name = NAME;
+
+  // If not empty, each instantiated builtin will have this appended after an
+  // underscore (_). It is instantiated like Prototype.
+  string Suffix = suffix;
+
+  // If empty, default OverloadedName is sub string of `Name` which end of first
+  // '_'. For example, the default overloaded name  is `vadd` for Name `vadd_vv`.
+  // It's used for describe some special naming cases.
+  string OverloadedName = "";
+
+  // If not empty, each OverloadedName will have this appended after an
+  // underscore (_). It is instantiated like Prototype.
+  string OverloadedSuffix = overloaded_suffix;
+
+  // The different variants of the builtin, parameterised with a type.
+  string TypeRange = type_range;
+
+  // We use each type described in TypeRange and LMUL with prototype to
+  // instantiate a specific element of the set of builtins being defined.
+  // Prototype attribute defines the C/C++ prototype of the builtin. It is a
+  // non-empty sequence of type transformers, the first of which is the return
+  // type of the builtin and the rest are the parameters of the builtin, in
+  // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a
+  // first builtin will have type
+  // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin
+  // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t).
+  string Prototype = prototype;
+
+  // This builtin has a masked form.
+  bit HasMasked = true;
+
+  // If HasMasked, this flag states that this builtin has a maskedoff operand. It
+  // is always the first operand in builtin and IR intrinsic.
+  bit HasMaskedOffOperand = true;
+
+  // This builtin has a granted vector length parameter.
+  bit HasVL = true;
+
+  // The policy scheme for masked intrinsic IR.
+  // It could be NonePolicy or HasPolicyOperand.
+  // HasPolicyOperand: Has a policy operand. 0 is tail and mask undisturbed, 1 is
+  // tail agnostic, 2 is mask undisturbed, and 3 is tail and mask agnostic. The
+  // policy operand is located at the last position.
+  PolicyScheme MaskedPolicyScheme = HasPolicyOperand;
+
+  // The policy scheme for unmasked intrinsic IR.
+  // It could be NonePolicy, HasPassthruOperand or HasPolicyOperand.
+  // HasPassthruOperand: Has a passthru operand to decide tail policy. If it is
+  // poison, tail policy is tail agnostic, otherwise policy is tail undisturbed.
+  // HasPolicyOperand: Has a policy operand. 1 is tail agnostic and 0 is tail
+  // undisturbed.
+  PolicyScheme UnMaskedPolicyScheme = NonePolicy;
+
+  // This builtin support tail agnostic and undisturbed policy.
+  bit HasTailPolicy = true;
+  // This builtin support mask agnostic and undisturbed policy.
+  bit HasMaskPolicy = true;
+
+  // This builtin prototype with TA or TAMA policy could not support overloading
+  // API. Other policy intrinsic functions would support overloading API with
+  // suffix `_tu`, `tumu`, `tuma`, `tamu` and `tama`.
+  bit SupportOverloading = true;
+
+  // This builtin is valid for the given Log2LMULs.
+  list<int> Log2LMUL = [0, 1, 2, 3, -1, -2, -3];
+
+  // Manual code in clang codegen riscv_vector_builtin_cg.inc
+  code ManualCodegen = [{}];
+
+  // When emit the automatic clang codegen, it describes what types we have to use
+  // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise,
+  // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd
+  // parameter of the unmasked version. k can't be the mask operand's position.
+  list<int> IntrinsicTypes = [];
+
+  // If these names are not empty, this is the ID of the LLVM intrinsic
+  // we want to lower to.
+  string IRName = NAME;
+
+  // If HasMasked, this is the ID of the LLVM intrinsic we want to lower to.
+  string MaskedIRName = NAME #"_mask";
+
+  // Use clang_builtin_alias to save the number of builtins.
+  bit HasBuiltinAlias = true;
+
+  // Features required to enable for this builtin.
+  list<string> RequiredFeatures = [];
+
+  // Number of fields for Load/Store Segment instructions.
+  int NF = 1;
+}
+
+// This is the code emitted in the header.
+class RVVHeader {
+  code HeaderCode;
+}
Index: clang/include/clang/Basic/riscv_vector.td
===================================================================
--- clang/include/clang/Basic/riscv_vector.td
+++ clang/include/clang/Basic/riscv_vector.td
@@ -12,233 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-//===----------------------------------------------------------------------===//
-// Instruction definitions
-//===----------------------------------------------------------------------===//
-// Each record of the class RVVBuiltin defines a collection of builtins (i.e.
-// "def vadd : RVVBuiltin" will be used to define things like "vadd_vv_i32m1",
-// "vadd_vv_i32m2", etc).
-//
-// The elements of this collection are defined by an instantiation process the
-// range of which is specified by the cross product of the LMUL attribute and
-// every element in the attribute TypeRange. By default builtins have LMUL = [1,
-// 2, 4, 8, 1/2, 1/4, 1/8] so the process is repeated 7 times. In tablegen we
-// use the Log2LMUL [0, 1, 2, 3, -1, -2, -3] to represent the LMUL.
-//
-// LMUL represents the fact that the types of values used by that builtin are
-// values generated by instructions that are executed under that LMUL. However,
-// this does not mean the builtin is necessarily lowered into an instruction
-// that executes under the specified LMUL. An example where this happens are
-// loads and stores of masks. A mask like `vbool8_t` can be generated, for
-// instance, by comparing two `__rvv_int8m1_t` (this is LMUL=1) or comparing two
-// `__rvv_int16m2_t` (this is LMUL=2). The actual load or store, however, will
-// be performed under LMUL=1 because mask registers are not grouped.
-//
-// TypeRange is a non-empty sequence of basic types:
-//
-//   c: int8_t (i8)
-//   s: int16_t (i16)
-//   i: int32_t (i32)
-//   l: int64_t (i64)
-//   x: float16_t (half)
-//   f: float32_t (float)
-//   d: float64_t (double)
-//
-// This way, given an LMUL, a record with a TypeRange "sil" will cause the
-// definition of 3 builtins. Each type "t" in the TypeRange (in this example
-// they are int16_t, int32_t, int64_t) is used as a parameter that drives the
-// definition of that particular builtin (for the given LMUL).
-//
-// During the instantiation, types can be transformed or modified using type
-// transformers. Given a type "t" the following primitive type transformers can
-// be applied to it to yield another type.
-//
-//   e: type of "t" as is (identity)
-//   v: computes a vector type whose element type is "t" for the current LMUL
-//   w: computes a vector type identical to what 'v' computes except for the
-//      element type which is twice as wide as the element type of 'v'
-//   q: computes a vector type identical to what 'v' computes except for the
-//      element type which is four times as wide as the element type of 'v'
-//   o: computes a vector type identical to what 'v' computes except for the
-//      element type which is eight times as wide as the element type of 'v'
-//   m: computes a vector type identical to what 'v' computes except for the
-//      element type which is bool
-//   0: void type, ignores "t"
-//   z: size_t, ignores "t"
-//   t: ptrdiff_t, ignores "t"
-//   u: unsigned long, ignores "t"
-//   l: long, ignores "t"
-//
-// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
-// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
-// Accordingly "w" would yield __rvv_int64m2_t.
-//
-// A type transformer can be prefixed by other non-primitive type transformers.
-//
-//   P: constructs a pointer to the current type
-//   C: adds const to the type
-//   K: requires the integer type to be a constant expression
-//   U: given an integer type or vector type, computes its unsigned variant
-//   I: given a vector type, compute the vector type with integer type
-//      elements of the same width
-//   F: given a vector type, compute the vector type with floating-point type
-//      elements of the same width
-//   S: given a vector type, computes its equivalent one for LMUL=1. This is a
-//      no-op if the vector was already LMUL=1
-//   (Log2EEW:Value): Log2EEW value could be 3/4/5/6 (8/16/32/64), given a
-//      vector type (SEW and LMUL) and EEW (8/16/32/64), computes its
-//      equivalent integer vector type with EEW and corresponding ELMUL (elmul =
-//      (eew/sew) * lmul). For example, vector type is __rvv_float16m4
-//      (SEW=16, LMUL=4) and Log2EEW is 3 (EEW=8), and then equivalent vector
-//      type is __rvv_uint8m2_t (elmul=(8/16)*4 = 2). Ignore to define a new
-//      builtins if its equivalent type has illegal lmul.
-//   (FixedSEW:Value): Given a vector type (SEW and LMUL), and computes another
-//      vector type which only changed SEW as given value. Ignore to define a new
-//      builtin if its equivalent type has illegal lmul or the SEW does not changed.
-//   (SFixedLog2LMUL:Value): Smaller Fixed Log2LMUL. Given a vector type (SEW
-//      and LMUL), and computes another vector type which only changed LMUL as
-//      given value. The new LMUL should be smaller than the old one. Ignore to
-//      define a new builtin if its equivalent type has illegal lmul.
-//   (LFixedLog2LMUL:Value): Larger Fixed Log2LMUL. Given a vector type (SEW
-//      and LMUL), and computes another vector type which only changed LMUL as
-//      given value. The new LMUL should be larger than the old one. Ignore to
-//      define a new builtin if its equivalent type has illegal lmul.
-//
-// Following with the example above, if t is "i", then "Ue" will yield unsigned
-// int and "Fv" will yield __rvv_float32m1_t (again assuming LMUL=1), Fw would
-// yield __rvv_float64m2_t, etc.
-//
-// Each builtin is then defined by applying each type in TypeRange against the
-// sequence of type transformers described in Suffix and Prototype.
-//
-// The name of the builtin is defined by the Name attribute (which defaults to
-// the name of the class) appended (separated with an underscore) the Suffix
-// attribute. For instance with Name="foo", Suffix = "v" and TypeRange = "il",
-// the builtin generated will be __builtin_rvv_foo_i32m1 and
-// __builtin_rvv_foo_i64m1 (under LMUL=1). If Suffix contains more than one
-// type transformer (say "vv") each of the types is separated with an
-// underscore as in "__builtin_rvv_foo_i32m1_i32m1".
-//
-// The C/C++ prototype of the builtin is defined by the Prototype attribute.
-// Prototype is a non-empty sequence of type transformers, the first of which
-// is the return type of the builtin and the rest are the parameters of the
-// builtin, in order. For instance if Prototype is "wvv" and TypeRange is "si"
-// a first builtin will have type
-// __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t) and the second builtin
-// will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t) (again
-// under LMUL=1).
-//
-// There are a number of attributes that are used to constraint the number and
-// shape of the builtins generated. Refer to the comments below for them.
-
-class PolicyScheme<int val>{
-  int Value = val;
-}
-def NonePolicy : PolicyScheme<0>;
-def HasPassthruOperand : PolicyScheme<1>;
-def HasPolicyOperand : PolicyScheme<2>;
-
-class RVVBuiltin<string suffix, string prototype, string type_range,
-                 string overloaded_suffix = ""> {
-  // Base name that will be prepended in __builtin_rvv_ and appended the
-  // computed Suffix.
-  string Name = NAME;
-
-  // If not empty, each instantiated builtin will have this appended after an
-  // underscore (_). It is instantiated like Prototype.
-  string Suffix = suffix;
-
-  // If empty, default OverloadedName is sub string of `Name` which end of first
-  // '_'. For example, the default overloaded name  is `vadd` for Name `vadd_vv`.
-  // It's used for describe some special naming cases.
-  string OverloadedName = "";
-
-  // If not empty, each OverloadedName will have this appended after an
-  // underscore (_). It is instantiated like Prototype.
-  string OverloadedSuffix = overloaded_suffix;
-
-  // The different variants of the builtin, parameterised with a type.
-  string TypeRange = type_range;
-
-  // We use each type described in TypeRange and LMUL with prototype to
-  // instantiate a specific element of the set of builtins being defined.
-  // Prototype attribute defines the C/C++ prototype of the builtin. It is a
-  // non-empty sequence of type transformers, the first of which is the return
-  // type of the builtin and the rest are the parameters of the builtin, in
-  // order. For instance if Prototype is "wvv", TypeRange is "si" and LMUL=1, a
-  // first builtin will have type
-  // __rvv_int32m2_t (__rvv_int16m1_t, __rvv_int16m1_t), and the second builtin
-  // will have type __rvv_int64m2_t (__rvv_int32m1_t, __rvv_int32m1_t).
-  string Prototype = prototype;
-
-  // This builtin has a masked form.
-  bit HasMasked = true;
-
-  // If HasMasked, this flag states that this builtin has a maskedoff operand. It
-  // is always the first operand in builtin and IR intrinsic.
-  bit HasMaskedOffOperand = true;
-
-  // This builtin has a granted vector length parameter.
-  bit HasVL = true;
-
-  // The policy scheme for masked intrinsic IR.
-  // It could be NonePolicy or HasPolicyOperand.
-  // HasPolicyOperand: Has a policy operand. 0 is tail and mask undisturbed, 1 is
-  // tail agnostic, 2 is mask undisturbed, and 3 is tail and mask agnostic. The
-  // policy operand is located at the last position.
-  PolicyScheme MaskedPolicyScheme = HasPolicyOperand;
-
-  // The policy scheme for unmasked intrinsic IR.
-  // It could be NonePolicy, HasPassthruOperand or HasPolicyOperand.
-  // HasPassthruOperand: Has a passthru operand to decide tail policy. If it is
-  // poison, tail policy is tail agnostic, otherwise policy is tail undisturbed.
-  // HasPolicyOperand: Has a policy operand. 1 is tail agnostic and 0 is tail
-  // undisturbed.
-  PolicyScheme UnMaskedPolicyScheme = NonePolicy;
-
-  // This builtin support tail agnostic and undisturbed policy.
-  bit HasTailPolicy = true;
-  // This builtin support mask agnostic and undisturbed policy.
-  bit HasMaskPolicy = true;
-
-  // This builtin prototype with TA or TAMA policy could not support overloading
-  // API. Other policy intrinsic functions would support overloading API with
-  // suffix `_tu`, `tumu`, `tuma`, `tamu` and `tama`.
-  bit SupportOverloading = true;
-
-  // This builtin is valid for the given Log2LMULs.
-  list<int> Log2LMUL = [0, 1, 2, 3, -1, -2, -3];
-
-  // Manual code in clang codegen riscv_vector_builtin_cg.inc
-  code ManualCodegen = [{}];
-
-  // When emit the automatic clang codegen, it describes what types we have to use
-  // to obtain the specific LLVM intrinsic. -1 means the return type, otherwise,
-  // k >= 0 meaning the k-th operand (counting from zero) of the codegen'd
-  // parameter of the unmasked version. k can't be the mask operand's position.
-  list<int> IntrinsicTypes = [];
-
-  // If these names are not empty, this is the ID of the LLVM intrinsic
-  // we want to lower to.
-  string IRName = NAME;
-
-  // If HasMasked, this is the ID of the LLVM intrinsic we want to lower to.
-  string MaskedIRName = NAME #"_mask";
-
-  // Use clang_builtin_alias to save the number of builtins.
-  bit HasBuiltinAlias = true;
-
-  // Features required to enable for this builtin.
-  list<string> RequiredFeatures = [];
-
-  // Number of fields for Load/Store Segment instructions.
-  int NF = 1;
-}
-
-// This is the code emitted in the header.
-class RVVHeader {
-  code HeaderCode;
-}
+include "riscv_vector_common.td"
 
 //===----------------------------------------------------------------------===//
 // Basic classes with automatic codegen.
@@ -2374,91 +2148,3 @@
     }
   }
 }
-
-class VCIXSuffix<string range> {
-  list<string> suffix = !cond(!eq(range, "c"): ["8mf8", "8mf4", "8mf2", "8m1", "8m2", "8m4", "8m8"],
-                              !eq(range, "s"): ["16mf4", "16mf2", "16m1", "16m2", "16m4", "16m8"],
-                              !eq(range, "i"): ["32mf2", "32m1", "32m2", "32m4", "32m8"],
-                              !eq(range, "l"): ["64m1", "64m2", "64m4", "64m8"]);
-}
-
-class VCIXBuiltinSet<string name, string IR_name, string suffix,
-                     string prototype, string type_range,
-                     list<int> intrinsic_types>
-    : RVVBuiltin<suffix, prototype, type_range> {
-  let Name = name;
-  let OverloadedName = name;
-  let IRName = IR_name;
-  let HasMasked = false;
-  let IntrinsicTypes = intrinsic_types;
-}
-
-multiclass VCIXBuiltinSet<string name, string IR_name, string suffix,
-                          string prototype, string type_range,
-                          list<int> intrinsic_types> {
-  if !find(prototype, "0") then {
-  def : VCIXBuiltinSet<name, IR_name, suffix, prototype, type_range, intrinsic_types>;
-  }
-  def : VCIXBuiltinSet<name # "_se", IR_name # "_se", suffix, prototype, type_range, intrinsic_types>;
-}
-
-multiclass RVVVCIXBuiltinSet<list<string> range, string prototype,
-                             list<int> intrinsic_types, bit EncodeVtype,
-                             bit UseGPR> {
-  defvar suffix = !if(EncodeVtype, "", "Uv");
-  foreach r = range in {
-    let RequiredFeatures = !if(!and(UseGPR, !eq(r, "l")),
-                               ["Xsfvcp", "RV64"], ["Xsfvcp"]) in {
-      // If EncodeVtype is true, then these intrinsic don't have any vector
-      // types in the output and inputs, but we still need to add vetvli for
-      // them.  So we encode different VTYPE into the intrinsic names, and
-      // then will know which vsetvli is correct.
-      if EncodeVtype then {
-        foreach s = VCIXSuffix<r>.suffix in {
-          defvar name = NAME # "_u" # s;
-          defvar IR_name = NAME # "_e" # s;
-          // Since we already encode the Vtype into the name, so just set
-          // Log2LMUL to zero.  Otherwise the RISCVVEmitter will expand
-          // lots of redundant intrinsic but have same names.
-	  let Log2LMUL = [0] in
-            def : VCIXBuiltinSet<name, IR_name, suffix, prototype, r, intrinsic_types>;
-        }
-      } else {
-        defm : VCIXBuiltinSet<NAME, NAME, suffix, prototype, r, intrinsic_types>;
-      }
-    }
-  }
-}
-
-let SupportOverloading = false in {
-  defm sf_vc_x_se  : RVVVCIXBuiltinSet<["c", "s", "i", "l"], "0KzKzKzUe", [0, 3], /*EncodeVtype*/1, /*UseGPR*/1>;
-  defm sf_vc_i_se  : RVVVCIXBuiltinSet<["c", "s", "i", "l"], "0KzKzKzKz", [2, 3], /*EncodeVtype*/1, /*UseGPR*/0>;
-  defm sf_vc_xv    : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUe",  [0, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/1>;
-  defm sf_vc_iv    : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvKz",  [0, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_vv    : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUv",  [0, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_fv    : RVVVCIXBuiltinSet<["si",  "l"], "0KzKzUvFe",  [0, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_xvv   : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUe",  [0, 1, 3],  /*EncodeVtype*/0, /*UseGPR*/1>;
-  defm sf_vc_ivv   : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvKz",  [0, 1, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_vvv   : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUv",  [0, 1, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_fvv   : RVVVCIXBuiltinSet<["si",  "l"], "0KzUvUvFe",  [0, 1, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_x   : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzUe",   [-1, 1, 2], /*EncodeVtype*/0, /*UseGPR*/1>;
-  defm sf_vc_v_i   : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzKz",   [-1, 1, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_xv  : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUe",   [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/1>;
-  defm sf_vc_v_iv  : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvKz",   [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_vv  : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUv",   [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_fv  : RVVVCIXBuiltinSet<["si",  "l"], "UvKzUvFe",   [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_xvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUe", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
-  defm sf_vc_v_ivv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvKz", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_vvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUv", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_fvv : RVVVCIXBuiltinSet<["si",  "l"], "UvKzUvUvFe", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
-  let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
-  defm sf_vc_xvw   : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUe",  [0, 1, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/1>;
-  defm sf_vc_ivw   : RVVVCIXBuiltinSet<["csi"], "0KzUwUvKz",  [0, 1, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_vvw   : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUv",  [0, 1, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_fvw   : RVVVCIXBuiltinSet<["si"],  "0KzUwUvFe",  [0, 1, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_xvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUe", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
-  defm sf_vc_v_ivw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvKz", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_vvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUv", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
-  defm sf_vc_v_fvw : RVVVCIXBuiltinSet<["si"],  "UwKzUwUvFe", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
-  }
-}
Index: clang/include/clang/Basic/riscv_sifive_vcix.td
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/riscv_sifive_vcix.td
@@ -0,0 +1,107 @@
+//==--- riscv_sifive_vcix.td - RISC-V SiFive VCIX function list -----------===//
+//
+//  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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the builtins for RISC-V SiFive VCIX. See:
+//
+//     https://sifive.cdn.prismic.io/sifive/c3829e36-8552-41f0-a841-79945784241b_vcix-spec-software.pdf
+//
+//===----------------------------------------------------------------------===//
+
+include "riscv_vector_common.td"
+
+//===----------------------------------------------------------------------===//
+// Instruction definitions
+//===----------------------------------------------------------------------===//
+
+class VCIXSuffix<string range> {
+  list<string> suffix = !cond(!eq(range, "c"): ["8mf8", "8mf4", "8mf2", "8m1", "8m2", "8m4", "8m8"],
+                              !eq(range, "s"): ["16mf4", "16mf2", "16m1", "16m2", "16m4", "16m8"],
+                              !eq(range, "i"): ["32mf2", "32m1", "32m2", "32m4", "32m8"],
+                              !eq(range, "l"): ["64m1", "64m2", "64m4", "64m8"]);
+}
+
+class VCIXBuiltinSet<string name, string IR_name, string suffix,
+                     string prototype, string type_range,
+                     list<int> intrinsic_types>
+    : RVVBuiltin<suffix, prototype, type_range> {
+  let Name = name;
+  let OverloadedName = name;
+  let IRName = IR_name;
+  let HasMasked = false;
+  let IntrinsicTypes = intrinsic_types;
+}
+
+multiclass VCIXBuiltinSet<string name, string IR_name, string suffix,
+                          string prototype, string type_range,
+                          list<int> intrinsic_types> {
+  if !find(prototype, "0") then {
+  def : VCIXBuiltinSet<name, IR_name, suffix, prototype, type_range, intrinsic_types>;
+  }
+  def : VCIXBuiltinSet<name # "_se", IR_name # "_se", suffix, prototype, type_range, intrinsic_types>;
+}
+
+multiclass RVVVCIXBuiltinSet<list<string> range, string prototype,
+                             list<int> intrinsic_types, bit EncodeVtype,
+                             bit UseGPR> {
+  defvar suffix = !if(EncodeVtype, "", "Uv");
+  foreach r = range in {
+    let RequiredFeatures = !if(!and(UseGPR, !eq(r, "l")),
+                               ["Xsfvcp", "RV64"], ["Xsfvcp"]) in {
+      // If EncodeVtype is true, then these intrinsic don't have any vector
+      // types in the output and inputs, but we still need to add vetvli for
+      // them.  So we encode different VTYPE into the intrinsic names, and
+      // then will know which vsetvli is correct.
+      if EncodeVtype then {
+        foreach s = VCIXSuffix<r>.suffix in {
+          defvar name = NAME # "_u" # s;
+          defvar IR_name = NAME # "_e" # s;
+          // Since we already encode the Vtype into the name, so just set
+          // Log2LMUL to zero.  Otherwise the RISCVVEmitter will expand
+          // lots of redundant intrinsic but have same names.
+	  let Log2LMUL = [0] in
+            def : VCIXBuiltinSet<name, IR_name, suffix, prototype, r, intrinsic_types>;
+        }
+      } else {
+        defm : VCIXBuiltinSet<NAME, NAME, suffix, prototype, r, intrinsic_types>;
+      }
+    }
+  }
+}
+
+let SupportOverloading = false in {
+  defm sf_vc_x_se  : RVVVCIXBuiltinSet<["c", "s", "i", "l"], "0KzKzKzUe", [0, 3], /*EncodeVtype*/1, /*UseGPR*/1>;
+  defm sf_vc_i_se  : RVVVCIXBuiltinSet<["c", "s", "i", "l"], "0KzKzKzKz", [2, 3], /*EncodeVtype*/1, /*UseGPR*/0>;
+  defm sf_vc_xv    : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUe",  [0, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/1>;
+  defm sf_vc_iv    : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvKz",  [0, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_vv    : RVVVCIXBuiltinSet<["csi", "l"], "0KzKzUvUv",  [0, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_fv    : RVVVCIXBuiltinSet<["si",  "l"], "0KzKzUvFe",  [0, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_xvv   : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUe",  [0, 1, 3],  /*EncodeVtype*/0, /*UseGPR*/1>;
+  defm sf_vc_ivv   : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvKz",  [0, 1, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_vvv   : RVVVCIXBuiltinSet<["csi", "l"], "0KzUvUvUv",  [0, 1, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_fvv   : RVVVCIXBuiltinSet<["si",  "l"], "0KzUvUvFe",  [0, 1, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_x   : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzUe",   [-1, 1, 2], /*EncodeVtype*/0, /*UseGPR*/1>;
+  defm sf_vc_v_i   : RVVVCIXBuiltinSet<["csi", "l"], "UvKzKzKz",   [-1, 1, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_xv  : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUe",   [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/1>;
+  defm sf_vc_v_iv  : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvKz",   [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_vv  : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUv",   [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_fv  : RVVVCIXBuiltinSet<["si",  "l"], "UvKzUvFe",   [-1, 0, 2], /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_xvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUe", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
+  defm sf_vc_v_ivv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvKz", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_vvv : RVVVCIXBuiltinSet<["csi", "l"], "UvKzUvUvUv", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_fvv : RVVVCIXBuiltinSet<["si",  "l"], "UvKzUvUvFe", [-1, 0, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+  let Log2LMUL = [-3, -2, -1, 0, 1, 2] in {
+  defm sf_vc_xvw   : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUe",  [0, 1, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/1>;
+  defm sf_vc_ivw   : RVVVCIXBuiltinSet<["csi"], "0KzUwUvKz",  [0, 1, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_vvw   : RVVVCIXBuiltinSet<["csi"], "0KzUwUvUv",  [0, 1, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_fvw   : RVVVCIXBuiltinSet<["si"],  "0KzUwUvFe",  [0, 1, 2, 3],  /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_xvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUe", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/1>;
+  defm sf_vc_v_ivw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvKz", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_vvw : RVVVCIXBuiltinSet<["csi"], "UwKzUwUvUv", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+  defm sf_vc_v_fvw : RVVVCIXBuiltinSet<["si"],  "UwKzUwUvFe", [-1, 0, 2, 3], /*EncodeVtype*/0, /*UseGPR*/0>;
+  }
+}
Index: clang/include/clang/Basic/CMakeLists.txt
===================================================================
--- clang/include/clang/Basic/CMakeLists.txt
+++ clang/include/clang/Basic/CMakeLists.txt
@@ -93,3 +93,12 @@
 clang_tablegen(riscv_vector_builtin_sema.inc -gen-riscv-vector-builtin-sema
   SOURCE riscv_vector.td
   TARGET ClangRISCVVectorBuiltinSema)
+clang_tablegen(riscv_sifive_vcix_builtins.inc -gen-riscv-sifive-vcix-builtins
+  SOURCE riscv_sifive_vcix.td
+  TARGET ClangRISCVSiFiveVCIXBuiltins)
+clang_tablegen(riscv_sifive_vcix_builtin_cg.inc -gen-riscv-sifive-vcix-builtin-codegen
+  SOURCE riscv_sifive_vcix.td
+  TARGET ClangRISCVSiFiveVCIXBuiltinCG)
+clang_tablegen(riscv_sifive_vcix_builtin_sema.inc -gen-riscv-sifive-vcix-builtin-sema
+  SOURCE riscv_sifive_vcix.td
+  TARGET ClangRISCVSiFiveVCIXBuiltinSema)
Index: clang/include/clang/Basic/BuiltinsRISCVVector.def
===================================================================
--- clang/include/clang/Basic/BuiltinsRISCVVector.def
+++ clang/include/clang/Basic/BuiltinsRISCVVector.def
@@ -16,6 +16,7 @@
 #endif
 
 #include "clang/Basic/riscv_vector_builtins.inc"
+#include "clang/Basic/riscv_sifive_vcix_builtins.inc"
 
 #undef BUILTIN
 #undef TARGET_BUILTIN
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to