https://github.com/4vtomat updated https://github.com/llvm/llvm-project/pull/187197
>From abec7a4d68cd56445c7e5221288394bc4d587e77 Mon Sep 17 00:00:00 2001 From: Brandon Wu <[email protected]> Date: Mon, 16 Mar 2026 23:48:35 -0700 Subject: [PATCH 1/7] [clang][RISCV] Use macro to check if intrinsics are supported Normally intrinsic support is decoupled from assembler support which means we cant simply use arch string to check if intrinsics are supported. This patch defines macros "__riscv_v_intrinsic_{EXTENSION}} to check whether the intrinsics of EXTENSION is supported by this compiler. --- clang/lib/Basic/Targets/RISCV.cpp | 46 ++++++++++++++ .../riscv-vector-intrinsic-exts.c | 63 +++++++++++++++++++ clang/utils/TableGen/RISCVVEmitter.cpp | 19 +++++- llvm/docs/RISCVUsage.rst | 23 +++++++ 4 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 clang/test/Preprocessor/riscv-vector-intrinsic-exts.c diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 685925b0773dc..a46eb87d88b94 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -22,6 +22,16 @@ using namespace clang; using namespace clang::targets; +namespace { +static constexpr StringRef UniqueExtensions[] = { +#define DECL_REQUIRED_EXTENSIONS +#include "clang/Basic/riscv_andes_vector_builtins.inc" +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#include "clang/Basic/riscv_vector_builtins.inc" +#undef DECL_REQUIRED_EXTENSIONS +}; +} // namespace + ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const { // clang-format off static const char *const GCCRegNames[] = { @@ -225,6 +235,42 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, // Currently we support the v1.0 RISC-V V intrinsics. Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(1, 0))); + // These macros indicate which extensions have intrinsics supported by the + // toolchain, regardless of whether they are currently enabled. + for (llvm::StringRef Ext : UniqueExtensions) { + if (Ext == "64bit") + continue; + Builder.defineMacro("__riscv_v_intrinsic_" + Twine(Ext)); + } + + // Define macros for intrinsics that are not explicitly listed in + // RequiredFeatures in td files. + const char *ImplicitList[] = {"v", "zve32x", "zve32f", + "zve64x", "zve64f", "zve64d"}; + for (const auto *Ext : ImplicitList) + Builder.defineMacro(Twine("__riscv_v_intrinsic_") + Ext); + + // Define macros for shorthand extensions when all of intrinsics of its + // extensions are presented. + auto DefineSuperExt = [&](const char *Name, ArrayRef<const char *> Required) { + assert(Required.size() > 0); + std::string Condition = + std::string("#if defined(__riscv_v_intrinsic_") + Required[0] + ")"; + for (size_t i = 1; i < Required.size(); ++i) + Condition += + std::string(" && defined(__riscv_v_intrinsic_") + Required[i] + ")"; + Builder.append(Condition); + Builder.defineMacro(Twine("__riscv_v_intrinsic_") + Name); + Builder.append("#endif"); + }; + + DefineSuperExt("zvkn", {"zvkned", "zvknhb", "zvkb"}); + DefineSuperExt("zvknc", {"zvkn", "zvbc"}); + DefineSuperExt("zvkng", {"zvkn", "zvkg"}); + DefineSuperExt("zvks", {"zvksed", "zvksh", "zvkb"}); + DefineSuperExt("zvksc", {"zvks", "zvbc"}); + DefineSuperExt("zvksg", {"zvks", "zvkg"}); + auto VScale = getVScaleRange(Opts, ArmStreamingKind::NotStreaming); if (VScale && VScale->first && VScale->first == VScale->second) Builder.defineMacro("__riscv_v_fixed_vlen", diff --git a/clang/test/Preprocessor/riscv-vector-intrinsic-exts.c b/clang/test/Preprocessor/riscv-vector-intrinsic-exts.c new file mode 100644 index 0000000000000..77e9293aec502 --- /dev/null +++ b/clang/test/Preprocessor/riscv-vector-intrinsic-exts.c @@ -0,0 +1,63 @@ +// RUN: %clang --target=riscv32-unknown-linux-gnu \ +// RUN: -march=rv32iv -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ALL-INTRINSICS %s +// RUN: %clang --target=riscv64-unknown-linux-gnu \ +// RUN: -march=rv64iv -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-ALL-INTRINSICS %s + +// Base vector intrinsics +// CHECK-ALL-INTRINSICS: __riscv_v_intrinsic_v 1 + +// Andes vendor extensions +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xandesvbfhcvt 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xandesvdot 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xandesvpackfph 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xandesvsintload 1 + +// SiFive vendor extensions +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm32a16f 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm32a32f 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm32a8f 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm32a8i 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm64a64f 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmmbase 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvcp 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfbfexp16e 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfexp16e 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfexp32e 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfexpa 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfexpa64e 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfnrclipxfqf 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfwmaccqqq 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvqmaccdod 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvqmaccqoq 1 + +// Standard vector extensions +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvabd 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvbb 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvbc 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvdot4a8i 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve32f 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve32x 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve64d 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve64f 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve64x 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfbfa 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfbfmin 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfbfwma 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfh 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfhmin 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfofp8min 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkb 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkg 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkn 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvknc 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkned 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkng 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvknha 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvknhb 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvks 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvksc 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvksed 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvksg 1 +// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvksh 1 diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index 970132d85d5b6..4810e9838e6e9 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -118,7 +118,8 @@ class RVVEmitter { private: /// Create all intrinsics and add them to \p Out and SemaRecords. void createRVVIntrinsics(std::vector<std::unique_ptr<RVVIntrinsic>> &Out, - std::vector<SemaRecord> *SemaRecords = nullptr); + std::vector<SemaRecord> *SemaRecords = nullptr, + std::set<StringRef> *UniqueExtensions = nullptr); /// Create all intrinsic records and SemaSignatureTable from SemaRecords. void createRVVIntrinsicRecords(std::vector<RVVIntrinsicRecord> &Out, SemaSignatureTable &SST, @@ -504,7 +505,8 @@ void RVVEmitter::createHeader(raw_ostream &OS) { void RVVEmitter::createBuiltins(raw_ostream &OS) { std::vector<std::unique_ptr<RVVIntrinsic>> Defs; - createRVVIntrinsics(Defs); + std::set<StringRef> UniqueExtensions; + createRVVIntrinsics(Defs, nullptr, &UniqueExtensions); llvm::StringToOffsetTable Table; // Ensure offset zero is the empty string. @@ -568,6 +570,12 @@ void RVVEmitter::createBuiltins(raw_ostream &OS) { OS << "HeaderDesc::NO_HEADER, ALL_LANGUAGES},\n"; } OS << "#endif // GET_RISCVV_BUILTIN_INFOS\n\n"; + + // Collect all unique required extensions for vector intrinsics + OS << "#ifdef DECL_REQUIRED_EXTENSIONS\n"; + for (const auto &UE : UniqueExtensions) + OS << " \"" << UE << "\",\n"; + OS << "#endif // DECL_REQUIRED_EXTENSIONS\n\n"; } void RVVEmitter::createCodeGen(raw_ostream &OS) { @@ -626,7 +634,8 @@ void RVVEmitter::createCodeGen(raw_ostream &OS) { void RVVEmitter::createRVVIntrinsics( std::vector<std::unique_ptr<RVVIntrinsic>> &Out, - std::vector<SemaRecord> *SemaRecords) { + std::vector<SemaRecord> *SemaRecords, + std::set<StringRef> *UniqueExtensions) { for (const Record *R : Records.getAllDerivedDefinitions("RVVBuiltin")) { StringRef Name = R->getValueAsString("Name"); StringRef SuffixProto = R->getValueAsString("Suffix"); @@ -676,6 +685,10 @@ void RVVEmitter::createRVVIntrinsics( SmallVector<PrototypeDescriptor> OverloadedSuffixDesc = parsePrototypes(OverloadedSuffixProto); + if (UniqueExtensions) + UniqueExtensions->insert(RequiredFeatures.begin(), + RequiredFeatures.end()); + // Compute Builtin types auto Prototype = RVVIntrinsic::computeBuiltinTypes( BasicPrototype, /*IsMasked=*/false, diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index d1befbd645900..165c1f081b39d 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -578,6 +578,29 @@ line. This currently applies to the following extensions: No extensions have experimental intrinsics. +Vector Intrinsic Detection Macros +================================== + +Clang defines preprocessor macros ``__riscv_v_intrinsic_<extension>`` to indicate +toolchain support for RISC-V vector intrinsics. These macros are defined for all +vector extensions that have intrinsics, allowing code to detect whether the compiler +supports intrinsics for a specific extension. + +Note: These macros are defined unconditionally because it's intended to show capabilities +of this compiler instead of showing whether extension is enabled. + +Example usage: + +.. code-block:: c + + #if defined(__riscv_v_intrinsic_zvbb) + // Compiler supports Zvbb intrinsics - can use them + #include <riscv_vector.h> + void use_zvbb_intrinsics() { + // Use Zvbb intrinsics here + } + #endif + Long (>32-bit) Instruction Support ================================== >From 617f95717ce406027b0df4d0a7405bcd162606ab Mon Sep 17 00:00:00 2001 From: Brandon Wu <[email protected]> Date: Tue, 31 Mar 2026 02:34:55 -0700 Subject: [PATCH 2/7] fixup! support scalar --- clang/lib/Basic/Targets/RISCV.cpp | 188 +++++++++++------- .../test/Preprocessor/riscv-intrinsic-exts.c | 92 +++++++++ .../riscv-vector-intrinsic-exts.c | 63 ------ 3 files changed, 204 insertions(+), 139 deletions(-) create mode 100644 clang/test/Preprocessor/riscv-intrinsic-exts.c delete mode 100644 clang/test/Preprocessor/riscv-vector-intrinsic-exts.c diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index a46eb87d88b94..f59859862191d 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -153,6 +153,92 @@ static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) { return MajorVersion * 1000000 + MinorVersion * 1000; } +static constexpr int NumRVVBuiltins = + RISCVVector::FirstSiFiveBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumRVVSiFiveBuiltins = + RISCVVector::FirstAndesBuiltin - RISCVVector::FirstSiFiveBuiltin; +static constexpr int NumRVVAndesBuiltins = + RISCVVector::FirstTSBuiltin - RISCVVector::FirstAndesBuiltin; +static constexpr int NumRISCVBuiltins = + RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; +static constexpr int NumBuiltins = + RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == (NumRVVBuiltins + NumRVVSiFiveBuiltins + + NumRVVAndesBuiltins + NumRISCVBuiltins)); + +namespace RVV { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE +static_assert(BuiltinStrings.size() < 100'000); + +static constexpr std::array<Builtin::Info, NumRVVBuiltins> BuiltinInfos = { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS +}; +} // namespace RVV + +namespace RVVSiFive { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE + +static constexpr std::array<Builtin::Info, NumRVVSiFiveBuiltins> BuiltinInfos = + { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS +}; +} // namespace RVVSiFive + +namespace RVVAndes { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_andes_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE + +static constexpr std::array<Builtin::Info, NumRVVAndesBuiltins> BuiltinInfos = + { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_andes_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS +}; +} // namespace RVVAndes + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_INFOS +}; +static_assert(std::size(BuiltinInfos) == NumRISCVBuiltins); + +// Extract unique scalar extensions from RISC-V scalar builtins +static llvm::SmallSet<std::string, 16> getUniqueScalarExtensions() { + llvm::SmallSet<std::string, 16> UniqueScalarExtensions; + for (const auto &Info : BuiltinInfos) { + StringRef Features = BuiltinStrings[Info.Offsets.Features]; + if (Features.empty()) + continue; + + SmallVector<StringRef, 4> Parts; + Features.split(Parts, ','); + for (StringRef Part : Parts) { + SmallVector<StringRef, 2> OrParts; + Part.split(OrParts, '|'); + for (StringRef Feature : OrParts) { + Feature = Feature.trim(); + if (Feature != "32bit" && Feature != "64bit" && !Feature.empty()) + UniqueScalarExtensions.insert(Feature.str()); + } + } + } + return UniqueScalarExtensions; +} + void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__riscv"); @@ -250,26 +336,39 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, for (const auto *Ext : ImplicitList) Builder.defineMacro(Twine("__riscv_v_intrinsic_") + Ext); - // Define macros for shorthand extensions when all of intrinsics of its - // extensions are presented. - auto DefineSuperExt = [&](const char *Name, ArrayRef<const char *> Required) { - assert(Required.size() > 0); + // Define macros for scalar RISC-V extensions that have builtins. + // These indicate toolchain support for scalar intrinsics. + llvm::SmallSet<std::string, 16> UniqueScalarExtensions = + getUniqueScalarExtensions(); + for (const auto &Ext : UniqueScalarExtensions) + Builder.defineMacro(Twine("__riscv_intrinsic_") + Ext); + + // Helper to define composite extension macros when all required extensions + // are present. Works for both scalar and vector intrinsics. + auto DefineSuperExt = [&](StringRef Prefix, const char *Name, + ArrayRef<const char *> Required) { + assert(!Required.empty()); std::string Condition = - std::string("#if defined(__riscv_v_intrinsic_") + Required[0] + ")"; + std::string("#if defined(") + Prefix.str() + Required[0] + ")"; for (size_t i = 1; i < Required.size(); ++i) Condition += - std::string(" && defined(__riscv_v_intrinsic_") + Required[i] + ")"; + std::string(" && defined(") + Prefix.str() + Required[i] + ")"; Builder.append(Condition); - Builder.defineMacro(Twine("__riscv_v_intrinsic_") + Name); + Builder.defineMacro(Twine(Prefix) + Name); Builder.append("#endif"); }; - DefineSuperExt("zvkn", {"zvkned", "zvknhb", "zvkb"}); - DefineSuperExt("zvknc", {"zvkn", "zvbc"}); - DefineSuperExt("zvkng", {"zvkn", "zvkg"}); - DefineSuperExt("zvks", {"zvksed", "zvksh", "zvkb"}); - DefineSuperExt("zvksc", {"zvks", "zvbc"}); - DefineSuperExt("zvksg", {"zvks", "zvkg"}); + // Vector crypto composite extensions + DefineSuperExt("__riscv_v_intrinsic_", "zvkn", {"zvkned", "zvknhb", "zvkb"}); + DefineSuperExt("__riscv_v_intrinsic_", "zvknc", {"zvkn", "zvbc"}); + DefineSuperExt("__riscv_v_intrinsic_", "zvkng", {"zvkn", "zvkg"}); + DefineSuperExt("__riscv_v_intrinsic_", "zvks", {"zvksed", "zvksh", "zvkb"}); + DefineSuperExt("__riscv_v_intrinsic_", "zvksc", {"zvks", "zvbc"}); + DefineSuperExt("__riscv_v_intrinsic_", "zvksg", {"zvks", "zvkg"}); + + // Scalar crypto composite extensions + DefineSuperExt("__riscv_intrinsic_", "zkn", {"zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"}); + DefineSuperExt("__riscv_intrinsic_", "zks", {"zbkb", "zbkc", "zbkx", "zksed", "zksh"}); auto VScale = getVScaleRange(Opts, ArmStreamingKind::NotStreaming); if (VScale && VScale->first && VScale->first == VScale->second) @@ -311,69 +410,6 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, } } -static constexpr int NumRVVBuiltins = - RISCVVector::FirstSiFiveBuiltin - Builtin::FirstTSBuiltin; -static constexpr int NumRVVSiFiveBuiltins = - RISCVVector::FirstAndesBuiltin - RISCVVector::FirstSiFiveBuiltin; -static constexpr int NumRVVAndesBuiltins = - RISCVVector::FirstTSBuiltin - RISCVVector::FirstAndesBuiltin; -static constexpr int NumRISCVBuiltins = - RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; -static constexpr int NumBuiltins = - RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin; -static_assert(NumBuiltins == (NumRVVBuiltins + NumRVVSiFiveBuiltins + - NumRVVAndesBuiltins + NumRISCVBuiltins)); - -namespace RVV { -#define GET_RISCVV_BUILTIN_STR_TABLE -#include "clang/Basic/riscv_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_STR_TABLE -static_assert(BuiltinStrings.size() < 100'000); - -static constexpr std::array<Builtin::Info, NumRVVBuiltins> BuiltinInfos = { -#define GET_RISCVV_BUILTIN_INFOS -#include "clang/Basic/riscv_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_INFOS -}; -} // namespace RVV - -namespace RVVSiFive { -#define GET_RISCVV_BUILTIN_STR_TABLE -#include "clang/Basic/riscv_sifive_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_STR_TABLE - -static constexpr std::array<Builtin::Info, NumRVVSiFiveBuiltins> BuiltinInfos = - { -#define GET_RISCVV_BUILTIN_INFOS -#include "clang/Basic/riscv_sifive_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_INFOS -}; -} // namespace RVVSiFive - -namespace RVVAndes { -#define GET_RISCVV_BUILTIN_STR_TABLE -#include "clang/Basic/riscv_andes_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_STR_TABLE - -static constexpr std::array<Builtin::Info, NumRVVAndesBuiltins> BuiltinInfos = - { -#define GET_RISCVV_BUILTIN_INFOS -#include "clang/Basic/riscv_andes_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_INFOS -}; -} // namespace RVVAndes - -#define GET_BUILTIN_STR_TABLE -#include "clang/Basic/BuiltinsRISCV.inc" -#undef GET_BUILTIN_STR_TABLE - -static constexpr Builtin::Info BuiltinInfos[] = { -#define GET_BUILTIN_INFOS -#include "clang/Basic/BuiltinsRISCV.inc" -#undef GET_BUILTIN_INFOS -}; -static_assert(std::size(BuiltinInfos) == NumRISCVBuiltins); - llvm::SmallVector<Builtin::InfosShard> RISCVTargetInfo::getTargetBuiltins() const { return { diff --git a/clang/test/Preprocessor/riscv-intrinsic-exts.c b/clang/test/Preprocessor/riscv-intrinsic-exts.c new file mode 100644 index 0000000000000..bba8d005a2bef --- /dev/null +++ b/clang/test/Preprocessor/riscv-intrinsic-exts.c @@ -0,0 +1,92 @@ +// Tests for RISC-V intrinsic detection macros. +// These macros indicate which extensions have intrinsics supported by the +// toolchain, regardless of whether they are currently enabled via -march. + +// RUN: %clang_cc1 -triple riscv32 -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-SCALAR-EXTS %s +// RUN: %clang_cc1 -triple riscv64 -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-SCALAR-EXTS %s + +// RUN: %clang --target=riscv32-unknown-linux-gnu \ +// RUN: -march=rv32iv -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-VECTOR-EXTS %s +// RUN: %clang --target=riscv64-unknown-linux-gnu \ +// RUN: -march=rv64iv -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=CHECK-VECTOR-EXTS %s + +// Scalar intrinsic extension macros (__riscv_intrinsic_*) +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbb 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbc 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbkb 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbkc 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbkx 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zknd 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zkne 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zknh 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zksed 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zksh 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_xtheadbb 1 + +// Scalar composite extensions (defined when all components are supported) +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zkn 1 +// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zks 1 + +// Vector intrinsic extension macros (__riscv_v_intrinsic_*) + +// Base vector intrinsics +// CHECK-VECTOR-EXTS: __riscv_v_intrinsic_v 1 + +// Andes vendor extensions +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xandesvbfhcvt 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xandesvdot 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xandesvpackfph 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xandesvsintload 1 + +// SiFive vendor extensions +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm32a16f 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm32a32f 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm32a8f 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm32a8i 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm64a64f 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmmbase 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvcp 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfbfexp16e 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfexp16e 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfexp32e 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfexpa 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfexpa64e 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfnrclipxfqf 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfwmaccqqq 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvqmaccdod 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvqmaccqoq 1 + +// Standard vector extensions +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvabd 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvbb 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvbc 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvdot4a8i 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve32f 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve32x 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve64d 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve64f 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve64x 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfbfa 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfbfmin 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfbfwma 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfh 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfhmin 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfofp8min 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkb 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkg 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkn 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvknc 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkned 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkng 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvknha 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvknhb 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvks 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvksc 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvksed 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvksg 1 +// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvksh 1 + diff --git a/clang/test/Preprocessor/riscv-vector-intrinsic-exts.c b/clang/test/Preprocessor/riscv-vector-intrinsic-exts.c deleted file mode 100644 index 77e9293aec502..0000000000000 --- a/clang/test/Preprocessor/riscv-vector-intrinsic-exts.c +++ /dev/null @@ -1,63 +0,0 @@ -// RUN: %clang --target=riscv32-unknown-linux-gnu \ -// RUN: -march=rv32iv -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-ALL-INTRINSICS %s -// RUN: %clang --target=riscv64-unknown-linux-gnu \ -// RUN: -march=rv64iv -E -dM %s \ -// RUN: -o - | FileCheck --check-prefix=CHECK-ALL-INTRINSICS %s - -// Base vector intrinsics -// CHECK-ALL-INTRINSICS: __riscv_v_intrinsic_v 1 - -// Andes vendor extensions -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xandesvbfhcvt 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xandesvdot 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xandesvpackfph 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xandesvsintload 1 - -// SiFive vendor extensions -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm32a16f 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm32a32f 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm32a8f 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm32a8i 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmm64a64f 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfmmbase 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvcp 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfbfexp16e 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfexp16e 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfexp32e 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfexpa 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfexpa64e 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfnrclipxfqf 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvfwmaccqqq 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvqmaccdod 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_xsfvqmaccqoq 1 - -// Standard vector extensions -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvabd 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvbb 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvbc 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvdot4a8i 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve32f 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve32x 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve64d 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve64f 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zve64x 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfbfa 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfbfmin 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfbfwma 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfh 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfhmin 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvfofp8min 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkb 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkg 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkn 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvknc 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkned 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvkng 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvknha 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvknhb 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvks 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvksc 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvksed 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvksg 1 -// CHECK-ALL-INTRINSICS-NEXT: __riscv_v_intrinsic_zvksh 1 >From 490551f3ff4a1c1944eca0ce63f0649ec9f06e86 Mon Sep 17 00:00:00 2001 From: Brandon Wu <[email protected]> Date: Tue, 31 Mar 2026 09:36:04 -0700 Subject: [PATCH 3/7] fixup! RISCVSupport.rst --- clang/docs/RISCVSupport.rst | 44 +++++++++++++++++++++++++++++++++++++ clang/docs/index.rst | 1 + llvm/docs/RISCVUsage.rst | 23 ------------------- 3 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 clang/docs/RISCVSupport.rst diff --git a/clang/docs/RISCVSupport.rst b/clang/docs/RISCVSupport.rst new file mode 100644 index 0000000000000..ba11094edcd34 --- /dev/null +++ b/clang/docs/RISCVSupport.rst @@ -0,0 +1,44 @@ +============== +RISC-V Support +============== + +.. contents:: + :local: + +Intrinsic Detection Macros +=========================== + +Clang provides macros to detect which RISC-V intrinsics are supported by the +toolchain. +Note: This is independent from assembler support. + +Scalar Intrinsic Detection +--------------------------- + +Macros of the form ``__riscv_intrinsic_<extension>`` indicate that the +toolchain supports scalar built-in functions for a given extension: + +.. code-block:: c + + #if defined(__riscv_intrinsic_zbb) + // Toolchain supports Zbb intrinsics like __builtin_riscv_orc_b_* + // These can be used with target attributes + #endif + +Composite extensions are also defined when all their sub-extensions are available, e.g. + ``__riscv_intrinsic_zkn`` - zbkb + zbkc + zbkx + zkne + zknd + zknh + +Vector Intrinsic Detection +--------------------------- + +Macros of the form ``__riscv_v_intrinsic_<extension>`` indicate that the +toolchain supports vector intrinsics for a given extension: + +.. code-block:: c + + #if defined(__riscv_v_intrinsic_zvbb) + // Toolchain supports vector bit manipulation intrinsics + #endif + +Composite vector crypto extensions are defined when all components are available, e.g. + ``__riscv_v_intrinsic_zvkn`` - zvkned + zvknhb + zvkb diff --git a/clang/docs/index.rst b/clang/docs/index.rst index 89ca6d73d9d8d..351c0ba947ecc 100644 --- a/clang/docs/index.rst +++ b/clang/docs/index.rst @@ -68,6 +68,7 @@ Using Clang as a Compiler APINotes DebuggingCoroutines AMDGPUSupport + RISCVSupport CXXTypeAwareAllocators CommandGuide/index FAQ diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst index 165c1f081b39d..d1befbd645900 100644 --- a/llvm/docs/RISCVUsage.rst +++ b/llvm/docs/RISCVUsage.rst @@ -578,29 +578,6 @@ line. This currently applies to the following extensions: No extensions have experimental intrinsics. -Vector Intrinsic Detection Macros -================================== - -Clang defines preprocessor macros ``__riscv_v_intrinsic_<extension>`` to indicate -toolchain support for RISC-V vector intrinsics. These macros are defined for all -vector extensions that have intrinsics, allowing code to detect whether the compiler -supports intrinsics for a specific extension. - -Note: These macros are defined unconditionally because it's intended to show capabilities -of this compiler instead of showing whether extension is enabled. - -Example usage: - -.. code-block:: c - - #if defined(__riscv_v_intrinsic_zvbb) - // Compiler supports Zvbb intrinsics - can use them - #include <riscv_vector.h> - void use_zvbb_intrinsics() { - // Use Zvbb intrinsics here - } - #endif - Long (>32-bit) Instruction Support ================================== >From c481f8b22842b2db848012142dc4c6ca43642591 Mon Sep 17 00:00:00 2001 From: Brandon Wu <[email protected]> Date: Sun, 5 Apr 2026 21:23:19 -0700 Subject: [PATCH 4/7] fixup! unify scalar and vector --- clang/lib/Basic/Targets/RISCV.cpp | 16 +- .../test/Preprocessor/riscv-intrinsic-exts.c | 155 ++++++++---------- 2 files changed, 78 insertions(+), 93 deletions(-) diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index f59859862191d..aef7501172bd7 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -326,7 +326,7 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, for (llvm::StringRef Ext : UniqueExtensions) { if (Ext == "64bit") continue; - Builder.defineMacro("__riscv_v_intrinsic_" + Twine(Ext)); + Builder.defineMacro("__riscv_intrinsic_" + Twine(Ext)); } // Define macros for intrinsics that are not explicitly listed in @@ -334,7 +334,7 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, const char *ImplicitList[] = {"v", "zve32x", "zve32f", "zve64x", "zve64f", "zve64d"}; for (const auto *Ext : ImplicitList) - Builder.defineMacro(Twine("__riscv_v_intrinsic_") + Ext); + Builder.defineMacro(Twine("__riscv_intrinsic_") + Ext); // Define macros for scalar RISC-V extensions that have builtins. // These indicate toolchain support for scalar intrinsics. @@ -359,12 +359,12 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, }; // Vector crypto composite extensions - DefineSuperExt("__riscv_v_intrinsic_", "zvkn", {"zvkned", "zvknhb", "zvkb"}); - DefineSuperExt("__riscv_v_intrinsic_", "zvknc", {"zvkn", "zvbc"}); - DefineSuperExt("__riscv_v_intrinsic_", "zvkng", {"zvkn", "zvkg"}); - DefineSuperExt("__riscv_v_intrinsic_", "zvks", {"zvksed", "zvksh", "zvkb"}); - DefineSuperExt("__riscv_v_intrinsic_", "zvksc", {"zvks", "zvbc"}); - DefineSuperExt("__riscv_v_intrinsic_", "zvksg", {"zvks", "zvkg"}); + DefineSuperExt("__riscv_intrinsic_", "zvkn", {"zvkned", "zvknhb", "zvkb"}); + DefineSuperExt("__riscv_intrinsic_", "zvknc", {"zvkn", "zvbc"}); + DefineSuperExt("__riscv_intrinsic_", "zvkng", {"zvkn", "zvkg"}); + DefineSuperExt("__riscv_intrinsic_", "zvks", {"zvksed", "zvksh", "zvkb"}); + DefineSuperExt("__riscv_intrinsic_", "zvksc", {"zvks", "zvbc"}); + DefineSuperExt("__riscv_intrinsic_", "zvksg", {"zvks", "zvkg"}); // Scalar crypto composite extensions DefineSuperExt("__riscv_intrinsic_", "zkn", {"zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"}); diff --git a/clang/test/Preprocessor/riscv-intrinsic-exts.c b/clang/test/Preprocessor/riscv-intrinsic-exts.c index bba8d005a2bef..f74017caae00b 100644 --- a/clang/test/Preprocessor/riscv-intrinsic-exts.c +++ b/clang/test/Preprocessor/riscv-intrinsic-exts.c @@ -3,90 +3,75 @@ // toolchain, regardless of whether they are currently enabled via -march. // RUN: %clang_cc1 -triple riscv32 -E -dM %s -o - \ -// RUN: | FileCheck --check-prefix=CHECK-SCALAR-EXTS %s +// RUN: | FileCheck --check-prefix=CHECK-INTRINSIC-EXTS %s // RUN: %clang_cc1 -triple riscv64 -E -dM %s -o - \ -// RUN: | FileCheck --check-prefix=CHECK-SCALAR-EXTS %s - -// RUN: %clang --target=riscv32-unknown-linux-gnu \ -// RUN: -march=rv32iv -E -dM %s -o - \ -// RUN: | FileCheck --check-prefix=CHECK-VECTOR-EXTS %s -// RUN: %clang --target=riscv64-unknown-linux-gnu \ -// RUN: -march=rv64iv -E -dM %s -o - \ -// RUN: | FileCheck --check-prefix=CHECK-VECTOR-EXTS %s - -// Scalar intrinsic extension macros (__riscv_intrinsic_*) -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbb 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbc 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbkb 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbkc 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zbkx 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zknd 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zkne 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zknh 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zksed 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zksh 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_xtheadbb 1 - -// Scalar composite extensions (defined when all components are supported) -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zkn 1 -// CHECK-SCALAR-EXTS-DAG: #define __riscv_intrinsic_zks 1 - -// Vector intrinsic extension macros (__riscv_v_intrinsic_*) - -// Base vector intrinsics -// CHECK-VECTOR-EXTS: __riscv_v_intrinsic_v 1 - -// Andes vendor extensions -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xandesvbfhcvt 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xandesvdot 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xandesvpackfph 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xandesvsintload 1 - -// SiFive vendor extensions -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm32a16f 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm32a32f 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm32a8f 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm32a8i 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmm64a64f 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfmmbase 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvcp 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfbfexp16e 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfexp16e 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfexp32e 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfexpa 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfexpa64e 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfnrclipxfqf 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvfwmaccqqq 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvqmaccdod 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_xsfvqmaccqoq 1 - -// Standard vector extensions -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvabd 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvbb 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvbc 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvdot4a8i 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve32f 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve32x 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve64d 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve64f 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zve64x 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfbfa 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfbfmin 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfbfwma 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfh 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfhmin 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvfofp8min 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkb 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkg 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkn 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvknc 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkned 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvkng 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvknha 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvknhb 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvks 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvksc 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvksed 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvksg 1 -// CHECK-VECTOR-EXTS-NEXT: __riscv_v_intrinsic_zvksh 1 +// RUN: | FileCheck --check-prefix=CHECK-INTRINSIC-EXTS %s +// CHECK-INTRINSIC-EXTS: #define __riscv_intrinsic_v 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xandesbfhcvt 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xandesperf 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xandesvbfhcvt 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xandesvdot 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xandesvpackfph 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xandesvsintload 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xcvalu 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xmipsexectl 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfmm32a16f 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfmm32a32f 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfmm32a8f 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfmm32a8i 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfmm64a64f 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfmmbase 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvcp 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvfbfexp16e 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvfexp16e 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvfexp32e 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvfexpa 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvfexpa64e 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvfnrclipxfqf 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvfwmaccqqq 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvqmaccdod 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvqmaccqoq 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xtheadbb 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbb 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbc 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbkb 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbkc 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbkx 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zihintntl 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zihintpause 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zkn 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zknd 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zkne 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zknh 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zks 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zksed 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zksh 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvabd 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvbb 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvbc 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvdot4a8i 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zve32f 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zve32x 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zve64d 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zve64f 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zve64x 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvfbfa 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvfbfmin 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvfbfwma 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvfh 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvfhmin 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvfofp8min 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvkb 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvkg 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvkn 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvknc 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvkned 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvkng 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvknha 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvknhb 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvks 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvksc 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvksed 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvksg 1 +// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zvksh 1 >From 8dff1575d2ea9d3f8c342df816d5d4eb22f61a19 Mon Sep 17 00:00:00 2001 From: Brandon Wu <[email protected]> Date: Sun, 5 Apr 2026 21:26:36 -0700 Subject: [PATCH 5/7] fixup! clang-format --- clang/lib/Basic/Targets/RISCV.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index aef7501172bd7..79aa217c4be33 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -197,8 +197,7 @@ namespace RVVAndes { #include "clang/Basic/riscv_andes_vector_builtins.inc" #undef GET_RISCVV_BUILTIN_STR_TABLE -static constexpr std::array<Builtin::Info, NumRVVAndesBuiltins> BuiltinInfos = - { +static constexpr std::array<Builtin::Info, NumRVVAndesBuiltins> BuiltinInfos = { #define GET_RISCVV_BUILTIN_INFOS #include "clang/Basic/riscv_andes_vector_builtins.inc" #undef GET_RISCVV_BUILTIN_INFOS @@ -367,8 +366,10 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, DefineSuperExt("__riscv_intrinsic_", "zvksg", {"zvks", "zvkg"}); // Scalar crypto composite extensions - DefineSuperExt("__riscv_intrinsic_", "zkn", {"zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"}); - DefineSuperExt("__riscv_intrinsic_", "zks", {"zbkb", "zbkc", "zbkx", "zksed", "zksh"}); + DefineSuperExt("__riscv_intrinsic_", "zkn", + {"zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"}); + DefineSuperExt("__riscv_intrinsic_", "zks", + {"zbkb", "zbkc", "zbkx", "zksed", "zksh"}); auto VScale = getVScaleRange(Opts, ArmStreamingKind::NotStreaming); if (VScale && VScale->first && VScale->first == VScale->second) >From 96625ea8218860bc2543bbd48988248a27d77663 Mon Sep 17 00:00:00 2001 From: Brandon Wu <[email protected]> Date: Tue, 7 Apr 2026 08:53:51 -0700 Subject: [PATCH 6/7] fixup! define macro in headers --- clang/docs/RISCVSupport.rst | 19 +- clang/lib/Basic/Targets/RISCV.cpp | 209 ++++++------------ clang/lib/Headers/andes_vector.h | 5 + clang/lib/Headers/riscv_bitmanip.h | 7 + clang/lib/Headers/riscv_corev_alu.h | 2 + clang/lib/Headers/riscv_crypto.h | 8 + clang/lib/Headers/riscv_mips.h | 2 + clang/lib/Headers/riscv_nds.h | 3 + clang/lib/Headers/riscv_ntlh.h | 2 + clang/lib/Headers/sifive_vector.h | 17 ++ .../test/Preprocessor/riscv-intrinsic-exts.c | 15 +- clang/utils/TableGen/RISCVVEmitter.cpp | 30 ++- 12 files changed, 137 insertions(+), 182 deletions(-) diff --git a/clang/docs/RISCVSupport.rst b/clang/docs/RISCVSupport.rst index ba11094edcd34..12f0344fb6d14 100644 --- a/clang/docs/RISCVSupport.rst +++ b/clang/docs/RISCVSupport.rst @@ -12,11 +12,11 @@ Clang provides macros to detect which RISC-V intrinsics are supported by the toolchain. Note: This is independent from assembler support. -Scalar Intrinsic Detection +Scalar/Vector Intrinsic Detection --------------------------- Macros of the form ``__riscv_intrinsic_<extension>`` indicate that the -toolchain supports scalar built-in functions for a given extension: +toolchain supports scalar/vector built-in functions for a given extension: .. code-block:: c @@ -27,18 +27,3 @@ toolchain supports scalar built-in functions for a given extension: Composite extensions are also defined when all their sub-extensions are available, e.g. ``__riscv_intrinsic_zkn`` - zbkb + zbkc + zbkx + zkne + zknd + zknh - -Vector Intrinsic Detection ---------------------------- - -Macros of the form ``__riscv_v_intrinsic_<extension>`` indicate that the -toolchain supports vector intrinsics for a given extension: - -.. code-block:: c - - #if defined(__riscv_v_intrinsic_zvbb) - // Toolchain supports vector bit manipulation intrinsics - #endif - -Composite vector crypto extensions are defined when all components are available, e.g. - ``__riscv_v_intrinsic_zvkn`` - zvkned + zvknhb + zvkb diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp index 79aa217c4be33..685925b0773dc 100644 --- a/clang/lib/Basic/Targets/RISCV.cpp +++ b/clang/lib/Basic/Targets/RISCV.cpp @@ -22,16 +22,6 @@ using namespace clang; using namespace clang::targets; -namespace { -static constexpr StringRef UniqueExtensions[] = { -#define DECL_REQUIRED_EXTENSIONS -#include "clang/Basic/riscv_andes_vector_builtins.inc" -#include "clang/Basic/riscv_sifive_vector_builtins.inc" -#include "clang/Basic/riscv_vector_builtins.inc" -#undef DECL_REQUIRED_EXTENSIONS -}; -} // namespace - ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const { // clang-format off static const char *const GCCRegNames[] = { @@ -153,91 +143,6 @@ static unsigned getVersionValue(unsigned MajorVersion, unsigned MinorVersion) { return MajorVersion * 1000000 + MinorVersion * 1000; } -static constexpr int NumRVVBuiltins = - RISCVVector::FirstSiFiveBuiltin - Builtin::FirstTSBuiltin; -static constexpr int NumRVVSiFiveBuiltins = - RISCVVector::FirstAndesBuiltin - RISCVVector::FirstSiFiveBuiltin; -static constexpr int NumRVVAndesBuiltins = - RISCVVector::FirstTSBuiltin - RISCVVector::FirstAndesBuiltin; -static constexpr int NumRISCVBuiltins = - RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; -static constexpr int NumBuiltins = - RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin; -static_assert(NumBuiltins == (NumRVVBuiltins + NumRVVSiFiveBuiltins + - NumRVVAndesBuiltins + NumRISCVBuiltins)); - -namespace RVV { -#define GET_RISCVV_BUILTIN_STR_TABLE -#include "clang/Basic/riscv_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_STR_TABLE -static_assert(BuiltinStrings.size() < 100'000); - -static constexpr std::array<Builtin::Info, NumRVVBuiltins> BuiltinInfos = { -#define GET_RISCVV_BUILTIN_INFOS -#include "clang/Basic/riscv_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_INFOS -}; -} // namespace RVV - -namespace RVVSiFive { -#define GET_RISCVV_BUILTIN_STR_TABLE -#include "clang/Basic/riscv_sifive_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_STR_TABLE - -static constexpr std::array<Builtin::Info, NumRVVSiFiveBuiltins> BuiltinInfos = - { -#define GET_RISCVV_BUILTIN_INFOS -#include "clang/Basic/riscv_sifive_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_INFOS -}; -} // namespace RVVSiFive - -namespace RVVAndes { -#define GET_RISCVV_BUILTIN_STR_TABLE -#include "clang/Basic/riscv_andes_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_STR_TABLE - -static constexpr std::array<Builtin::Info, NumRVVAndesBuiltins> BuiltinInfos = { -#define GET_RISCVV_BUILTIN_INFOS -#include "clang/Basic/riscv_andes_vector_builtins.inc" -#undef GET_RISCVV_BUILTIN_INFOS -}; -} // namespace RVVAndes - -#define GET_BUILTIN_STR_TABLE -#include "clang/Basic/BuiltinsRISCV.inc" -#undef GET_BUILTIN_STR_TABLE - -static constexpr Builtin::Info BuiltinInfos[] = { -#define GET_BUILTIN_INFOS -#include "clang/Basic/BuiltinsRISCV.inc" -#undef GET_BUILTIN_INFOS -}; -static_assert(std::size(BuiltinInfos) == NumRISCVBuiltins); - -// Extract unique scalar extensions from RISC-V scalar builtins -static llvm::SmallSet<std::string, 16> getUniqueScalarExtensions() { - llvm::SmallSet<std::string, 16> UniqueScalarExtensions; - for (const auto &Info : BuiltinInfos) { - StringRef Features = BuiltinStrings[Info.Offsets.Features]; - if (Features.empty()) - continue; - - SmallVector<StringRef, 4> Parts; - Features.split(Parts, ','); - for (StringRef Part : Parts) { - SmallVector<StringRef, 2> OrParts; - Part.split(OrParts, '|'); - for (StringRef Feature : OrParts) { - Feature = Feature.trim(); - if (Feature != "32bit" && Feature != "64bit" && !Feature.empty()) - UniqueScalarExtensions.insert(Feature.str()); - } - } - } - return UniqueScalarExtensions; -} - void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { Builder.defineMacro("__riscv"); @@ -320,57 +225,6 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, // Currently we support the v1.0 RISC-V V intrinsics. Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(1, 0))); - // These macros indicate which extensions have intrinsics supported by the - // toolchain, regardless of whether they are currently enabled. - for (llvm::StringRef Ext : UniqueExtensions) { - if (Ext == "64bit") - continue; - Builder.defineMacro("__riscv_intrinsic_" + Twine(Ext)); - } - - // Define macros for intrinsics that are not explicitly listed in - // RequiredFeatures in td files. - const char *ImplicitList[] = {"v", "zve32x", "zve32f", - "zve64x", "zve64f", "zve64d"}; - for (const auto *Ext : ImplicitList) - Builder.defineMacro(Twine("__riscv_intrinsic_") + Ext); - - // Define macros for scalar RISC-V extensions that have builtins. - // These indicate toolchain support for scalar intrinsics. - llvm::SmallSet<std::string, 16> UniqueScalarExtensions = - getUniqueScalarExtensions(); - for (const auto &Ext : UniqueScalarExtensions) - Builder.defineMacro(Twine("__riscv_intrinsic_") + Ext); - - // Helper to define composite extension macros when all required extensions - // are present. Works for both scalar and vector intrinsics. - auto DefineSuperExt = [&](StringRef Prefix, const char *Name, - ArrayRef<const char *> Required) { - assert(!Required.empty()); - std::string Condition = - std::string("#if defined(") + Prefix.str() + Required[0] + ")"; - for (size_t i = 1; i < Required.size(); ++i) - Condition += - std::string(" && defined(") + Prefix.str() + Required[i] + ")"; - Builder.append(Condition); - Builder.defineMacro(Twine(Prefix) + Name); - Builder.append("#endif"); - }; - - // Vector crypto composite extensions - DefineSuperExt("__riscv_intrinsic_", "zvkn", {"zvkned", "zvknhb", "zvkb"}); - DefineSuperExt("__riscv_intrinsic_", "zvknc", {"zvkn", "zvbc"}); - DefineSuperExt("__riscv_intrinsic_", "zvkng", {"zvkn", "zvkg"}); - DefineSuperExt("__riscv_intrinsic_", "zvks", {"zvksed", "zvksh", "zvkb"}); - DefineSuperExt("__riscv_intrinsic_", "zvksc", {"zvks", "zvbc"}); - DefineSuperExt("__riscv_intrinsic_", "zvksg", {"zvks", "zvkg"}); - - // Scalar crypto composite extensions - DefineSuperExt("__riscv_intrinsic_", "zkn", - {"zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"}); - DefineSuperExt("__riscv_intrinsic_", "zks", - {"zbkb", "zbkc", "zbkx", "zksed", "zksh"}); - auto VScale = getVScaleRange(Opts, ArmStreamingKind::NotStreaming); if (VScale && VScale->first && VScale->first == VScale->second) Builder.defineMacro("__riscv_v_fixed_vlen", @@ -411,6 +265,69 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts, } } +static constexpr int NumRVVBuiltins = + RISCVVector::FirstSiFiveBuiltin - Builtin::FirstTSBuiltin; +static constexpr int NumRVVSiFiveBuiltins = + RISCVVector::FirstAndesBuiltin - RISCVVector::FirstSiFiveBuiltin; +static constexpr int NumRVVAndesBuiltins = + RISCVVector::FirstTSBuiltin - RISCVVector::FirstAndesBuiltin; +static constexpr int NumRISCVBuiltins = + RISCV::LastTSBuiltin - RISCVVector::FirstTSBuiltin; +static constexpr int NumBuiltins = + RISCV::LastTSBuiltin - Builtin::FirstTSBuiltin; +static_assert(NumBuiltins == (NumRVVBuiltins + NumRVVSiFiveBuiltins + + NumRVVAndesBuiltins + NumRISCVBuiltins)); + +namespace RVV { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE +static_assert(BuiltinStrings.size() < 100'000); + +static constexpr std::array<Builtin::Info, NumRVVBuiltins> BuiltinInfos = { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS +}; +} // namespace RVV + +namespace RVVSiFive { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE + +static constexpr std::array<Builtin::Info, NumRVVSiFiveBuiltins> BuiltinInfos = + { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_sifive_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS +}; +} // namespace RVVSiFive + +namespace RVVAndes { +#define GET_RISCVV_BUILTIN_STR_TABLE +#include "clang/Basic/riscv_andes_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_STR_TABLE + +static constexpr std::array<Builtin::Info, NumRVVAndesBuiltins> BuiltinInfos = + { +#define GET_RISCVV_BUILTIN_INFOS +#include "clang/Basic/riscv_andes_vector_builtins.inc" +#undef GET_RISCVV_BUILTIN_INFOS +}; +} // namespace RVVAndes + +#define GET_BUILTIN_STR_TABLE +#include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_STR_TABLE + +static constexpr Builtin::Info BuiltinInfos[] = { +#define GET_BUILTIN_INFOS +#include "clang/Basic/BuiltinsRISCV.inc" +#undef GET_BUILTIN_INFOS +}; +static_assert(std::size(BuiltinInfos) == NumRISCVBuiltins); + llvm::SmallVector<Builtin::InfosShard> RISCVTargetInfo::getTargetBuiltins() const { return { diff --git a/clang/lib/Headers/andes_vector.h b/clang/lib/Headers/andes_vector.h index dc717e6d805b9..968a922b6a21c 100644 --- a/clang/lib/Headers/andes_vector.h +++ b/clang/lib/Headers/andes_vector.h @@ -13,4 +13,9 @@ #pragma clang riscv intrinsic andes_vector +#define __riscv_intrinsic_xandesvbfhcvt 1 +#define __riscv_intrinsic_xandesvdot 1 +#define __riscv_intrinsic_xandesvpackfph 1 +#define __riscv_intrinsic_xandesvsintload 1 + #endif //_ANDES_VECTOR_H_ diff --git a/clang/lib/Headers/riscv_bitmanip.h b/clang/lib/Headers/riscv_bitmanip.h index 2bc7ee022a96b..9f35ba896643b 100644 --- a/clang/lib/Headers/riscv_bitmanip.h +++ b/clang/lib/Headers/riscv_bitmanip.h @@ -16,6 +16,13 @@ extern "C" { #endif +#define __riscv_intrinsic_zbb 1 +#define __riscv_intrinsic_zbc 1 +#define __riscv_intrinsic_zbkb 1 +#define __riscv_intrinsic_zbkc 1 +#define __riscv_intrinsic_zbkx 1 +#define __riscv_intrinsic_xtheadbb 1 + #if defined(__riscv_zbb) static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) __riscv_orc_b_32(uint32_t __x) { diff --git a/clang/lib/Headers/riscv_corev_alu.h b/clang/lib/Headers/riscv_corev_alu.h index 84f4d087e4863..d6fba94790aab 100644 --- a/clang/lib/Headers/riscv_corev_alu.h +++ b/clang/lib/Headers/riscv_corev_alu.h @@ -16,6 +16,8 @@ extern "C" { #endif +#define __riscv_intrinsic_xcvalu 1 + #if defined(__riscv_xcvalu) #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) diff --git a/clang/lib/Headers/riscv_crypto.h b/clang/lib/Headers/riscv_crypto.h index 7cd2a708f5575..ea9f29c0dd31b 100644 --- a/clang/lib/Headers/riscv_crypto.h +++ b/clang/lib/Headers/riscv_crypto.h @@ -16,6 +16,14 @@ extern "C" { #endif +#define __riscv_intrinsic_zkn 1 +#define __riscv_intrinsic_zknd 1 +#define __riscv_intrinsic_zkne 1 +#define __riscv_intrinsic_zknh 1 +#define __riscv_intrinsic_zks 1 +#define __riscv_intrinsic_zksed 1 +#define __riscv_intrinsic_zksh 1 + #if defined(__riscv_zknd) #if __riscv_xlen == 32 #define __riscv_aes32dsi(x, y, bs) __builtin_riscv_aes32dsi(x, y, bs) diff --git a/clang/lib/Headers/riscv_mips.h b/clang/lib/Headers/riscv_mips.h index 124a989280ed4..afd390b174bf4 100644 --- a/clang/lib/Headers/riscv_mips.h +++ b/clang/lib/Headers/riscv_mips.h @@ -14,6 +14,8 @@ #error "This header is only meant to be used on riscv architecture" #endif +#define __riscv_intrinsic_xmipsexectl 1 + #define __DEFAULT_FN_ATTRS \ __attribute__((__always_inline__, __nodebug__, __target__("xmipsexectl"))) diff --git a/clang/lib/Headers/riscv_nds.h b/clang/lib/Headers/riscv_nds.h index 29734c43834c7..c321e0b263380 100644 --- a/clang/lib/Headers/riscv_nds.h +++ b/clang/lib/Headers/riscv_nds.h @@ -16,6 +16,9 @@ extern "C" { #endif +#define __riscv_intrinsic_xandesbfhcvt 1 +#define __riscv_intrinsic_xandesperf 1 + #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) #if defined(__riscv_xandesperf) diff --git a/clang/lib/Headers/riscv_ntlh.h b/clang/lib/Headers/riscv_ntlh.h index c92e580a0a631..10540d95eb164 100644 --- a/clang/lib/Headers/riscv_ntlh.h +++ b/clang/lib/Headers/riscv_ntlh.h @@ -10,6 +10,8 @@ #ifndef __RISCV_NTLH_H #define __RISCV_NTLH_H +#define __riscv_intrinsic_zihintntl 1 + #ifndef __riscv_zihintntl #error "NTLH intrinsics require the NTLH extension." #endif diff --git a/clang/lib/Headers/sifive_vector.h b/clang/lib/Headers/sifive_vector.h index d315eb9609821..6df1dae535041 100644 --- a/clang/lib/Headers/sifive_vector.h +++ b/clang/lib/Headers/sifive_vector.h @@ -13,6 +13,23 @@ #pragma clang riscv intrinsic sifive_vector +#define __riscv_intrinsic_xsfmm32a16f 1 +#define __riscv_intrinsic_xsfmm32a32f 1 +#define __riscv_intrinsic_xsfmm32a8f 1 +#define __riscv_intrinsic_xsfmm32a8i 1 +#define __riscv_intrinsic_xsfmm64a64f 1 +#define __riscv_intrinsic_xsfmmbase 1 +#define __riscv_intrinsic_xsfvcp 1 +#define __riscv_intrinsic_xsfvfbfexp16e 1 +#define __riscv_intrinsic_xsfvfexp16e 1 +#define __riscv_intrinsic_xsfvfexp32e 1 +#define __riscv_intrinsic_xsfvfexpa 1 +#define __riscv_intrinsic_xsfvfexpa64e 1 +#define __riscv_intrinsic_xsfvfnrclipxfqf 1 +#define __riscv_intrinsic_xsfvfwmaccqqq 1 +#define __riscv_intrinsic_xsfvqmaccdod 1 +#define __riscv_intrinsic_xsfvqmaccqoq 1 + #define __riscv_sf_vc_x_se_u8mf4(p27_26, p24_20, p11_7, rs1, vl) \ __riscv_sf_vc_x_se(p27_26, p24_20, p11_7, (uint8_t)rs1, 8, 6, vl) #define __riscv_sf_vc_x_se_u8mf2(p27_26, p24_20, p11_7, rs1, vl) \ diff --git a/clang/test/Preprocessor/riscv-intrinsic-exts.c b/clang/test/Preprocessor/riscv-intrinsic-exts.c index f74017caae00b..ae8e887594b30 100644 --- a/clang/test/Preprocessor/riscv-intrinsic-exts.c +++ b/clang/test/Preprocessor/riscv-intrinsic-exts.c @@ -2,11 +2,21 @@ // These macros indicate which extensions have intrinsics supported by the // toolchain, regardless of whether they are currently enabled via -march. -// RUN: %clang_cc1 -triple riscv32 -E -dM %s -o - \ +// RUN: %clang_cc1 -triple riscv32 -target-feature +zihintntl -E -dM %s -o - \ // RUN: | FileCheck --check-prefix=CHECK-INTRINSIC-EXTS %s -// RUN: %clang_cc1 -triple riscv64 -E -dM %s -o - \ +// RUN: %clang_cc1 -triple riscv64 -target-feature +zihintntl -E -dM %s -o - \ // RUN: | FileCheck --check-prefix=CHECK-INTRINSIC-EXTS %s +#include <riscv_bitmanip.h> +#include <riscv_corev_alu.h> +#include <riscv_crypto.h> +#include <riscv_mips.h> +#include <riscv_nds.h> +#include <riscv_ntlh.h> +#include <riscv_vector.h> +#include <andes_vector.h> +#include <sifive_vector.h> + // CHECK-INTRINSIC-EXTS: #define __riscv_intrinsic_v 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xandesbfhcvt 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xandesperf 1 @@ -39,7 +49,6 @@ // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbkc 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbkx 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zihintntl 1 -// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zihintpause 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zkn 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zknd 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zkne 1 diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index 4810e9838e6e9..8fe519495dc38 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -118,8 +118,7 @@ class RVVEmitter { private: /// Create all intrinsics and add them to \p Out and SemaRecords. void createRVVIntrinsics(std::vector<std::unique_ptr<RVVIntrinsic>> &Out, - std::vector<SemaRecord> *SemaRecords = nullptr, - std::set<StringRef> *UniqueExtensions = nullptr); + std::vector<SemaRecord> *SemaRecords = nullptr); /// Create all intrinsic records and SemaSignatureTable from SemaRecords. void createRVVIntrinsicRecords(std::vector<RVVIntrinsicRecord> &Out, SemaSignatureTable &SST, @@ -432,6 +431,17 @@ void RVVEmitter::createHeader(raw_ostream &OS) { OS << "#pragma clang riscv intrinsic vector\n\n"; + auto DefineIntrinsicMacro = [&](ArrayRef<const char *> Exts) { + for (const char *Ext : Exts) + OS << "#define __riscv_intrinsic_" << Ext << " 1\n"; + }; + DefineIntrinsicMacro( + {"v", "zvabd", "zvbb", "zvbc", "zvdot4a8i", "zve32f", + "zve32x", "zve64d", "zve64f", "zve64x", "zvfbfa", "zvfbfmin", + "zvfbfwma", "zvfh", "zvfhmin", "zvfofp8min", "zvkb", "zvkg", + "zvkn", "zvknc", "zvkned", "zvkng", "zvknha", "zvknhb", + "zvks", "zvksc", "zvksed", "zvksg", "zvksh"}); + printHeaderCode(OS); auto printType = [&](auto T) { @@ -505,8 +515,7 @@ void RVVEmitter::createHeader(raw_ostream &OS) { void RVVEmitter::createBuiltins(raw_ostream &OS) { std::vector<std::unique_ptr<RVVIntrinsic>> Defs; - std::set<StringRef> UniqueExtensions; - createRVVIntrinsics(Defs, nullptr, &UniqueExtensions); + createRVVIntrinsics(Defs); llvm::StringToOffsetTable Table; // Ensure offset zero is the empty string. @@ -570,12 +579,6 @@ void RVVEmitter::createBuiltins(raw_ostream &OS) { OS << "HeaderDesc::NO_HEADER, ALL_LANGUAGES},\n"; } OS << "#endif // GET_RISCVV_BUILTIN_INFOS\n\n"; - - // Collect all unique required extensions for vector intrinsics - OS << "#ifdef DECL_REQUIRED_EXTENSIONS\n"; - for (const auto &UE : UniqueExtensions) - OS << " \"" << UE << "\",\n"; - OS << "#endif // DECL_REQUIRED_EXTENSIONS\n\n"; } void RVVEmitter::createCodeGen(raw_ostream &OS) { @@ -634,8 +637,7 @@ void RVVEmitter::createCodeGen(raw_ostream &OS) { void RVVEmitter::createRVVIntrinsics( std::vector<std::unique_ptr<RVVIntrinsic>> &Out, - std::vector<SemaRecord> *SemaRecords, - std::set<StringRef> *UniqueExtensions) { + std::vector<SemaRecord> *SemaRecords) { for (const Record *R : Records.getAllDerivedDefinitions("RVVBuiltin")) { StringRef Name = R->getValueAsString("Name"); StringRef SuffixProto = R->getValueAsString("Suffix"); @@ -685,10 +687,6 @@ void RVVEmitter::createRVVIntrinsics( SmallVector<PrototypeDescriptor> OverloadedSuffixDesc = parsePrototypes(OverloadedSuffixProto); - if (UniqueExtensions) - UniqueExtensions->insert(RequiredFeatures.begin(), - RequiredFeatures.end()); - // Compute Builtin types auto Prototype = RVVIntrinsic::computeBuiltinTypes( BasicPrototype, /*IsMasked=*/false, >From b601e0ab6064af20837c9cb716e4897be86c5800 Mon Sep 17 00:00:00 2001 From: Brandon Wu <[email protected]> Date: Tue, 7 Apr 2026 09:21:09 -0700 Subject: [PATCH 7/7] fixup! address comments --- clang/docs/RISCVSupport.rst | 6 +++--- clang/lib/Headers/riscv_bitmanip.h | 1 - .../test/Preprocessor/riscv-intrinsic-exts.c | 1 - clang/utils/TableGen/RISCVVEmitter.cpp | 20 +++++++++---------- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/clang/docs/RISCVSupport.rst b/clang/docs/RISCVSupport.rst index 12f0344fb6d14..9394e82fad5ad 100644 --- a/clang/docs/RISCVSupport.rst +++ b/clang/docs/RISCVSupport.rst @@ -12,11 +12,11 @@ Clang provides macros to detect which RISC-V intrinsics are supported by the toolchain. Note: This is independent from assembler support. -Scalar/Vector Intrinsic Detection +Intrinsic Detection --------------------------- -Macros of the form ``__riscv_intrinsic_<extension>`` indicate that the -toolchain supports scalar/vector built-in functions for a given extension: +Macros of the form ``__riscv_intrinsic_<extension>`` indicate that the toolchain +supports intrinsics for a given extension: .. code-block:: c diff --git a/clang/lib/Headers/riscv_bitmanip.h b/clang/lib/Headers/riscv_bitmanip.h index 9f35ba896643b..e03e5cea6617f 100644 --- a/clang/lib/Headers/riscv_bitmanip.h +++ b/clang/lib/Headers/riscv_bitmanip.h @@ -21,7 +21,6 @@ extern "C" { #define __riscv_intrinsic_zbkb 1 #define __riscv_intrinsic_zbkc 1 #define __riscv_intrinsic_zbkx 1 -#define __riscv_intrinsic_xtheadbb 1 #if defined(__riscv_zbb) static __inline__ uint32_t __attribute__((__always_inline__, __nodebug__)) diff --git a/clang/test/Preprocessor/riscv-intrinsic-exts.c b/clang/test/Preprocessor/riscv-intrinsic-exts.c index ae8e887594b30..133b2c3600a1e 100644 --- a/clang/test/Preprocessor/riscv-intrinsic-exts.c +++ b/clang/test/Preprocessor/riscv-intrinsic-exts.c @@ -42,7 +42,6 @@ // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvfwmaccqqq 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvqmaccdod 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xsfvqmaccqoq 1 -// CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_xtheadbb 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbb 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbc 1 // CHECK-INTRINSIC-EXTS-NEXT: #define __riscv_intrinsic_zbkb 1 diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index 8fe519495dc38..9ef5b0725495a 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -431,16 +431,16 @@ void RVVEmitter::createHeader(raw_ostream &OS) { OS << "#pragma clang riscv intrinsic vector\n\n"; - auto DefineIntrinsicMacro = [&](ArrayRef<const char *> Exts) { - for (const char *Ext : Exts) - OS << "#define __riscv_intrinsic_" << Ext << " 1\n"; - }; - DefineIntrinsicMacro( - {"v", "zvabd", "zvbb", "zvbc", "zvdot4a8i", "zve32f", - "zve32x", "zve64d", "zve64f", "zve64x", "zvfbfa", "zvfbfmin", - "zvfbfwma", "zvfh", "zvfhmin", "zvfofp8min", "zvkb", "zvkg", - "zvkn", "zvknc", "zvkned", "zvkng", "zvknha", "zvknhb", - "zvks", "zvksc", "zvksed", "zvksg", "zvksh"}); + // This array includes all extensions that have intrinsics implemented. We + // need to update the list when any new intrinsic are defined. + const char *Exts[] = { + "v", "zvabd", "zvbb", "zvbc", "zvdot4a8i", "zve32f", + "zve32x", "zve64d", "zve64f", "zve64x", "zvfbfa", "zvfbfmin", + "zvfbfwma", "zvfh", "zvfhmin", "zvfofp8min", "zvkb", "zvkg", + "zvkn", "zvknc", "zvkned", "zvkng", "zvknha", "zvknhb", + "zvks", "zvksc", "zvksed", "zvksg", "zvksh"}; + for (const char *Ext : Exts) + OS << "#define __riscv_intrinsic_" << Ext << " 1\n"; printHeaderCode(OS); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
