From fb74ff749a24b9d054deb92c1c6edb9df5032056 Mon Sep 17 00:00:00 2001 From: imkiva Date: Fri, 21 Jul 2023 16:24:05 +0800 Subject: [PATCH 1/5] [Clang][RISCV] support `v0p7` arch string --- llvm/lib/Support/RISCVISAInfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 70fab80108310..95287a6c1ad17 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -64,6 +64,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = { {"svpbmt", RISCVExtensionVersion{1, 0}}, {"v", RISCVExtensionVersion{1, 0}}, + {"v", RISCVExtensionVersion{0, 7}}, // vendor-defined ('X') extensions {"xcvbitmanip", RISCVExtensionVersion{1, 0}}, From 5532136954c5ba56838caa587555b9b2199f9ddf Mon Sep 17 00:00:00 2001 From: imkiva Date: Fri, 21 Jul 2023 16:26:11 +0800 Subject: [PATCH 2/5] [Clang][RISCV] add pragma for rvv 0.7.1 as 'vector0p7' --- clang/include/clang/Sema/Sema.h | 3 +++ clang/lib/Parse/ParsePragma.cpp | 7 +++++-- clang/lib/Sema/SemaLookup.cpp | 3 ++- clang/test/Sema/riscv-bad-intrinsic-pragma.c | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 082fa252feaba..7d9e7ac3c68dc 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -1645,6 +1645,9 @@ class Sema final { /// Indicate RISC-V SiFive vector builtin functions enabled or not. bool DeclareRISCVSiFiveVectorBuiltins = false; + /// Indicate RISC-V vector 0.7.1 builtin functions enabled or not. + bool DeclareRISCVV0p7Builtins = false; + private: std::unique_ptr RVIntrinsicManager; diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index b3178aef64d72..718ca351f8219 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -4042,10 +4042,11 @@ void PragmaRISCVHandler::HandlePragma(Preprocessor &PP, PP.Lex(Tok); II = Tok.getIdentifierInfo(); - if (!II || !(II->isStr("vector") || II->isStr("sifive_vector"))) { + if (!II || !(II->isStr("vector") || II->isStr("sifive_vector") || + II->isStr("vector0p7"))) { PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_argument) << PP.getSpelling(Tok) << "riscv" << /*Expected=*/true - << "'vector' or 'sifive_vector'"; + << "'vector', 'sifive_vector' or 'vector0p7'"; return; } @@ -4060,4 +4061,6 @@ void PragmaRISCVHandler::HandlePragma(Preprocessor &PP, Actions.DeclareRISCVVBuiltins = true; else if (II->isStr("sifive_vector")) Actions.DeclareRISCVSiFiveVectorBuiltins = true; + else if (II->isStr("vector0p7")) + Actions.DeclareRISCVV0p7Builtins = true; } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index d1ff688c2a21d..04869d9afc471 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -933,7 +933,8 @@ bool Sema::LookupBuiltin(LookupResult &R) { } } - if (DeclareRISCVVBuiltins || DeclareRISCVSiFiveVectorBuiltins) { + if (DeclareRISCVVBuiltins || DeclareRISCVSiFiveVectorBuiltins || + DeclareRISCVV0p7Builtins) { if (!RVIntrinsicManager) RVIntrinsicManager = CreateRISCVIntrinsicManager(*this); diff --git a/clang/test/Sema/riscv-bad-intrinsic-pragma.c b/clang/test/Sema/riscv-bad-intrinsic-pragma.c index fc8e18ff130e0..6b91fccefcd0f 100644 --- a/clang/test/Sema/riscv-bad-intrinsic-pragma.c +++ b/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' or 'sifive_vector' [-Wignored-pragmas] +// CHECK: warning: unexpected argument 'vvvv' to '#pragma riscv'; expected 'vector', 'sifive_vector' or 'vector0p7' [-Wignored-pragmas] #pragma clang riscv what + 3241 // CHECK: warning: unexpected argument 'what' to '#pragma riscv'; expected 'intrinsic' [-Wignored-pragmas] From 8c0c41475eadc05dee72c43bd82d47a3421660de Mon Sep 17 00:00:00 2001 From: imkiva Date: Mon, 24 Jul 2023 16:30:20 +0800 Subject: [PATCH 3/5] [Clang][RISCV] pass rvv version to cc1 The macro `__riscv_v` now correctly reflects the rvv version being used. --- .../test/Preprocessor/riscv-target-features.c | 9 ++++ llvm/lib/Support/RISCVISAInfo.cpp | 50 ++++++++++++++++--- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index 27c089494de17..cd6cf14feed7c 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -222,6 +222,15 @@ // CHECK-V-EXT: __riscv_v 1000000{{$}} // CHECK-V-EXT: __riscv_vector 1 +// RUN: %clang -target riscv32-unknown-linux-gnu \ +// RUN: -march=rv32iv0p7 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-V0P7-EXT %s +// RUN: %clang -target riscv64-unknown-linux-gnu \ +// RUN: -march=rv64iv0p7 -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-V0P7-EXT %s +// CHECK-V0P7-EXT: __riscv_v 7000{{$}} +// CHECK-V0P7-EXT: __riscv_vector 1 + // RUN: %clang -target riscv32-unknown-linux-gnu \ // RUN: -march=rv32izfhmin1p0 -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-ZFHMIN-EXT %s diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 95287a6c1ad17..50734e0ecd37e 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -429,7 +429,18 @@ void RISCVISAInfo::toFeatures( if (isExperimentalExtension(ExtName)) { Features.push_back(StrAlloc("+experimental-" + ExtName)); } else { - Features.push_back(StrAlloc("+" + ExtName)); + auto Major = Ext.second.MajorVersion; + auto Minor = Ext.second.MinorVersion; + if (ExtName == "v" && Major == 0 && Minor == 7) { + // Append the version number only when 0.7.1 is specified. + // Otherwise, do not change anything, for the following reasons: + // - Better compatibility with upstream LLVM. + // - Most of the RISC-V code assumes the default version of V is 1.0. + // NOTE: keep this in sync with RISCVISAInfo::parseFeatures + Features.push_back(StrAlloc("+" + ExtName + + utostr(Major) + "p" + utostr(Minor))); + } else + Features.push_back(StrAlloc("+" + ExtName)); } } if (AddAllExtensions) { @@ -571,7 +582,27 @@ RISCVISAInfo::parseFeatures(unsigned XLen, auto ExtensionInfos = Experimental ? ArrayRef(SupportedExperimentalExtensions) : ArrayRef(SupportedExtensions); - auto ExtensionInfoIterator = + auto ExtensionInfoIterator = ExtensionInfos.end(); + + if (ExtName.startswith("v")) { + auto Major = 1u; + auto Minor = 0u; + auto Versions = ExtName.drop_front(1); + if (Versions.size() == 3) { + Major = Versions[0] - '0'; + Minor = Versions[2] - '0'; + ExtName = "v"; // stripping the trailing version + } + + auto Range = + std::equal_range(ExtensionInfos.begin(), ExtensionInfos.end(), ExtName, LessExtName()); + for (auto I = Range.first, E = Range.second; I != E; ++I) + if (I->Version.Major == Major && I->Version.Minor == Minor) { + ExtensionInfoIterator = I; + break; + } + } else + ExtensionInfoIterator = llvm::lower_bound(ExtensionInfos, ExtName, LessExtName()); // Not all features is related to ISA extension, like `relax` or @@ -1215,10 +1246,17 @@ std::vector RISCVISAInfo::toFeatureVector() const { continue; if (!isSupportedExtension(ExtName)) continue; - std::string Feature = isExperimentalExtension(ExtName) - ? "+experimental-" + ExtName - : "+" + ExtName; - FeatureVector.push_back(Feature); + auto Major = Ext.second.MajorVersion; + auto Minor = Ext.second.MinorVersion; + if (ExtName == "v" && Major == 0 && Minor == 7) { + std::string Feature = "+" + ExtName + utostr(Major) + "p" + utostr(Minor); + FeatureVector.push_back(Feature); + } else { + std::string Feature = isExperimentalExtension(ExtName) + ? "+experimental-" + ExtName + : "+" + ExtName; + FeatureVector.push_back(Feature); + } } return FeatureVector; } From 38976e259c2f156642ec5b605745257d2014f1ac Mon Sep 17 00:00:00 2001 From: imkiva Date: Mon, 24 Jul 2023 16:35:42 +0800 Subject: [PATCH 4/5] [Clang][RISCV] test clang driver about rvv 0.7.1 target feature --- clang/test/Driver/riscv-arch.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/test/Driver/riscv-arch.c b/clang/test/Driver/riscv-arch.c index 4f618d52dce10..96c32ba0a095e 100644 --- a/clang/test/Driver/riscv-arch.c +++ b/clang/test/Driver/riscv-arch.c @@ -416,6 +416,10 @@ // RUN: FileCheck -check-prefix=RV32-V-GOODVERS %s // RV32-V-GOODVERS: "-target-feature" "+v" +// RUN: %clang --target=riscv32-unknown-elf -march=rv32iv0p7 -### %s -c 2>&1 | \ +// RUN: FileCheck -check-prefix=RV32-V0P7-GOODVERS %s +// RV32-V0P7-GOODVERS: "-target-feature" "+v0p7" + // RUN: %clang --target=riscv32-unknown-elf -march=rv32iv1p0_zvl32b0p1 -### %s -c 2>&1 | \ // RUN: FileCheck -check-prefix=RV32-ZVL-BADVERS %s // RV32-ZVL-BADVERS: error: invalid arch name 'rv32iv1p0_zvl32b0p1' From e45031cb1a65aa1c8a642d7c09033a2be7f16b6d Mon Sep 17 00:00:00 2001 From: imkiva Date: Tue, 25 Jul 2023 14:59:33 +0800 Subject: [PATCH 5/5] [Clang][RISCV] extract common code --- llvm/lib/Support/RISCVISAInfo.cpp | 34 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 50734e0ecd37e..716d994e2d16f 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -259,6 +259,18 @@ findDefaultVersion(StringRef ExtName) { return std::nullopt; } +static const RISCVSupportedExtension * +findExtensionIn(llvm::ArrayRef ExtensionInfos, + StringRef Ext, unsigned MajorVersion, unsigned MinorVersion) { + auto Range = std::equal_range(ExtensionInfos.begin(), ExtensionInfos.end(), + Ext, LessExtName()); + for (auto I = Range.first, E = Range.second; I != E; ++I) + if (I->Version.Major == MajorVersion && I->Version.Minor == MinorVersion) { + return I; + } + return ExtensionInfos.end(); +} + void RISCVISAInfo::addExtension(StringRef ExtName, unsigned MajorVersion, unsigned MinorVersion) { RISCVExtensionInfo Ext; @@ -325,11 +337,8 @@ bool RISCVISAInfo::isSupportedExtension(StringRef Ext, unsigned MajorVersion, unsigned MinorVersion) { for (auto ExtInfo : {ArrayRef(SupportedExtensions), ArrayRef(SupportedExperimentalExtensions)}) { - auto Range = - std::equal_range(ExtInfo.begin(), ExtInfo.end(), Ext, LessExtName()); - for (auto I = Range.first, E = Range.second; I != E; ++I) - if (I->Version.Major == MajorVersion && I->Version.Minor == MinorVersion) - return true; + return findExtensionIn(ExtInfo, Ext, MajorVersion, MinorVersion) != + ExtInfo.end(); } return false; @@ -437,8 +446,8 @@ void RISCVISAInfo::toFeatures( // - Better compatibility with upstream LLVM. // - Most of the RISC-V code assumes the default version of V is 1.0. // NOTE: keep this in sync with RISCVISAInfo::parseFeatures - Features.push_back(StrAlloc("+" + ExtName + - utostr(Major) + "p" + utostr(Minor))); + Features.push_back( + StrAlloc("+" + ExtName + utostr(Major) + "p" + utostr(Minor))); } else Features.push_back(StrAlloc("+" + ExtName)); } @@ -594,16 +603,11 @@ RISCVISAInfo::parseFeatures(unsigned XLen, ExtName = "v"; // stripping the trailing version } - auto Range = - std::equal_range(ExtensionInfos.begin(), ExtensionInfos.end(), ExtName, LessExtName()); - for (auto I = Range.first, E = Range.second; I != E; ++I) - if (I->Version.Major == Major && I->Version.Minor == Minor) { - ExtensionInfoIterator = I; - break; - } + ExtensionInfoIterator = + findExtensionIn(ExtensionInfos, ExtName, Major, Minor); } else ExtensionInfoIterator = - llvm::lower_bound(ExtensionInfos, ExtName, LessExtName()); + llvm::lower_bound(ExtensionInfos, ExtName, LessExtName()); // Not all features is related to ISA extension, like `relax` or // `save-restore`, skip those feature.