-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[RISCV] Implement multi-lib reuse rule for RISC-V bare-metal toolchain #73765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Brandon Wu (4vtomat) ChangesExtend the multi-lib re-use selection mechanism for RISC-V.
Full diff: https://github.com/llvm/llvm-project/pull/73765.diff 6 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 16cf5707227264d..ffc53377d97bd02 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -30,6 +30,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/RISCVISAInfo.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/TargetParser.h"
#include <system_error>
@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
Result.Multilibs = CSKYMultilibs;
}
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+/// - ABI must be the same.
+/// - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+/// - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+ const Multilib::flags_list &Flags,
+ llvm::SmallVector<Multilib> &SelectedMultilibs) {
+ // Try to find the perfect matching multi-lib first.
+ if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+ return true;
+
+ llvm::StringMap<bool> FlagSet;
+ Multilib::flags_list NewFlags;
+ std::vector<MultilibBuilder> NewMultilibs;
+
+ auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+ Arch, /*EnableExperimentalExtension=*/true,
+ /*ExperimentalExtensionVersionCheck=*/false);
+ if (!ParseResult) {
+ // Ignore any error here, we assume it will handled in another place.
+ consumeError(ParseResult.takeError());
+ return false;
+ }
+ auto &ISAInfo = *ParseResult;
+
+ auto CurrentExts = ISAInfo->getExtensions();
+
+ addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+ addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+ // Collect all flags except march=*
+ for (StringRef Flag : Flags) {
+ if (Flag.startswith("!march=") || Flag.startswith("-march="))
+ continue;
+
+ NewFlags.push_back(Flag.str());
+ }
+
+ llvm::StringSet<> AllArchExts;
+ // Reconstruct multi-lib list, and break march option into seperated
+ // extension. e.g. march=rv32im -> +i +m
+ for (auto M : RISCVMultilibSet) {
+ bool Skip = false;
+
+ MultilibBuilder NewMultilib =
+ MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());
+ for (StringRef Flag : M.flags()) {
+ // Add back the all option except -march.
+ if (!Flag.startswith("-march=")) {
+ NewMultilib.flag(Flag);
+ continue;
+ }
+
+ // Break down -march into individual extension.
+ auto MLConfigParseResult = llvm::RISCVISAInfo::parseArchString(
+ Flag.drop_front(7), /*EnableExperimentalExtension=*/true,
+ /*ExperimentalExtensionVersionCheck=*/false);
+ if (!MLConfigParseResult) {
+ // Ignore any error here, we assume it will handled in another place.
+ llvm::consumeError(MLConfigParseResult.takeError());
+
+ // We might got parsing error if rv32e in the list, we could just skip
+ // that and process the rest of multi-lib configs.
+ Skip = true;
+ continue;
+ }
+ auto &MLConfigISAInfo = *MLConfigParseResult;
+
+ auto MLConfigArchExts = MLConfigISAInfo->getExtensions();
+ for (auto MLConfigArchExt : MLConfigArchExts) {
+ auto ExtName = MLConfigArchExt.first;
+ NewMultilib.flag(Twine("-", ExtName).str());
+
+ if (!AllArchExts.contains(ExtName)) {
+ AllArchExts.insert(ExtName);
+ addMultilibFlag(ISAInfo->hasExtension(ExtName),
+ Twine("-", ExtName).str(), NewFlags);
+ }
+ }
+
+ // Check the XLEN explicitly.
+ if (MLConfigISAInfo->getXLen() == 32) {
+ NewMultilib.flag("-m32");
+ NewMultilib.flag("!m64");
+ } else {
+ NewMultilib.flag("!m32");
+ NewMultilib.flag("-m64");
+ }
+
+ // Atomic extension must be explicitly checked, soft and hard atomic
+ // operation never co-work correctly.
+ if (!MLConfigISAInfo->hasExtension("a"))
+ NewMultilib.flag("!a");
+ }
+
+ if (Skip)
+ continue;
+
+ NewMultilibs.emplace_back(NewMultilib);
+ }
+
+ // Build an internal used only multi-lib list, used for checking any
+ // compatible multi-lib.
+ MultilibSet NewRISCVMultilibs =
+ MultilibSetBuilder().Either(NewMultilibs).makeMultilibSet();
+
+ if (NewRISCVMultilibs.select(NewFlags, SelectedMultilibs))
+ for (const Multilib &NewSelectedM : SelectedMultilibs)
+ for (auto M : RISCVMultilibSet)
+ // Look up the corresponding multi-lib entry in original multi-lib set.
+ if (M.gccSuffix() == NewSelectedM.gccSuffix())
+ return true;
+
+ return false;
+}
+
static void findRISCVBareMetalMultilibs(const Driver &D,
const llvm::Triple &TargetTriple,
StringRef Path, const ArgList &Args,
@@ -1727,9 +1851,10 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
// currently only support the set of multilibs like riscv-gnu-toolchain does.
// TODO: support MULTILIB_REUSE
constexpr RiscvMultilib RISCVMultilibSet[] = {
- {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"},
- {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"},
- {"rv64imafdc", "lp64d"}};
+ {"rv32i", "ilp32"}, {"rv32ic", "ilp32"}, {"rv32if", "ilp32f"},
+ {"rv32im", "ilp32"}, {"rv32iac", "ilp32"}, {"rv32ifc", "ilp32"},
+ {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"},
+ {"rv64imac", "lp64"}, {"rv64imafdc", "lp64d"}};
std::vector<MultilibBuilder> Ms;
for (auto Element : RISCVMultilibSet) {
@@ -1766,7 +1891,8 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
}
}
- if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs))
+ if (RISCVMultilibSelect(RISCVMultilibs, MArch, Flags,
+ Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
}
diff --git a/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ic/ilp32/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ic/ilp32/crtbegin.o
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32if/ilp32f/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32if/ilp32f/crtbegin.o
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32/crtbegin.o
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32f/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32f/crtbegin.o
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c b/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c
new file mode 100644
index 000000000000000..7a1bca76fee8ec4
--- /dev/null
+++ b/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c
@@ -0,0 +1,86 @@
+// Test case for scanning input of GCC output as multilib config
+// Skip this test on Windows, we can't create a dummy GCC to output
+// multilib config, ExecuteAndWait only execute *.exe file.
+// UNSUPPORTED: system-windows
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imc -mabi=ilp32 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMC-ILP32 %s
+// GCC-MULTI-LIB-REUSE-RV32IMC-ILP32: rv32im/ilp32
+// GCC-MULTI-LIB-REUSE-RV32IMC-ILP32-NOT: {{^.+$}}
+
+// Check rv32imac won't reuse rv32im or rv32ic
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imac -mabi=ilp32 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32 %s
+// GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32: rv32imac/ilp32
+// GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32--NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32ifc -mabi=ilp32f \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IFC-ILP32F %s
+// GCC-MULTI-LIB-REUSE-RV32IFC-ILP32F: rv32if/ilp32f
+// GCC-MULTI-LIB-REUSE-RV32IFC-ILP32F-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imafdc -mabi=ilp32f \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F %s
+// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F: rv32imafc/ilp32f
+// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imafdc -mabi=ilp32d \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D %s
+// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D: .
+// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv64imafc -mabi=lp64 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64 %s
+// GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64: rv64imac/lp64
+// GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imafc_zfh -mabi=ilp32 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32 %s
+// GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32: rv32imac/ilp32
+// GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32i_zvkb -mabi=ilp32 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32 %s
+// GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32: rv32i/ilp32
+// GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv64imfc -mabi=lp64 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV64IMFC-LP64 %s
+// GCC-MULTI-LIB-REUSE-RV64IMFC-LP64: .
+// GCC-MULTI-LIB-REUSE-RV64IMFC-LP64-NOT: {{^.+$}}
|
@llvm/pr-subscribers-backend-risc-v Author: Brandon Wu (4vtomat) ChangesExtend the multi-lib re-use selection mechanism for RISC-V.
Full diff: https://github.com/llvm/llvm-project/pull/73765.diff 6 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 16cf5707227264d..ffc53377d97bd02 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -30,6 +30,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/RISCVISAInfo.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/TargetParser.h"
#include <system_error>
@@ -1715,6 +1716,129 @@ static void findCSKYMultilibs(const Driver &D, const llvm::Triple &TargetTriple,
Result.Multilibs = CSKYMultilibs;
}
+/// Extend the multi-lib re-use selection mechanism for RISC-V.
+/// This funciton will try to re-use multi-lib if they are compatible.
+/// Definition of compatible:
+/// - ABI must be the same.
+/// - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im
+/// is a subset of march=rv32imc.
+/// - march that contains atomic extension can't reuse multi-lib that
+/// doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
+/// march=rv32ima are not compatible, because software and hardware
+/// atomic operation can't work together correctly.
+static bool
+RISCVMultilibSelect(const MultilibSet &RISCVMultilibSet, StringRef Arch,
+ const Multilib::flags_list &Flags,
+ llvm::SmallVector<Multilib> &SelectedMultilibs) {
+ // Try to find the perfect matching multi-lib first.
+ if (RISCVMultilibSet.select(Flags, SelectedMultilibs))
+ return true;
+
+ llvm::StringMap<bool> FlagSet;
+ Multilib::flags_list NewFlags;
+ std::vector<MultilibBuilder> NewMultilibs;
+
+ auto ParseResult = llvm::RISCVISAInfo::parseArchString(
+ Arch, /*EnableExperimentalExtension=*/true,
+ /*ExperimentalExtensionVersionCheck=*/false);
+ if (!ParseResult) {
+ // Ignore any error here, we assume it will handled in another place.
+ consumeError(ParseResult.takeError());
+ return false;
+ }
+ auto &ISAInfo = *ParseResult;
+
+ auto CurrentExts = ISAInfo->getExtensions();
+
+ addMultilibFlag(ISAInfo->getXLen() == 32, "-m32", NewFlags);
+ addMultilibFlag(ISAInfo->getXLen() == 64, "-m64", NewFlags);
+
+ // Collect all flags except march=*
+ for (StringRef Flag : Flags) {
+ if (Flag.startswith("!march=") || Flag.startswith("-march="))
+ continue;
+
+ NewFlags.push_back(Flag.str());
+ }
+
+ llvm::StringSet<> AllArchExts;
+ // Reconstruct multi-lib list, and break march option into seperated
+ // extension. e.g. march=rv32im -> +i +m
+ for (auto M : RISCVMultilibSet) {
+ bool Skip = false;
+
+ MultilibBuilder NewMultilib =
+ MultilibBuilder(M.gccSuffix(), M.osSuffix(), M.includeSuffix());
+ for (StringRef Flag : M.flags()) {
+ // Add back the all option except -march.
+ if (!Flag.startswith("-march=")) {
+ NewMultilib.flag(Flag);
+ continue;
+ }
+
+ // Break down -march into individual extension.
+ auto MLConfigParseResult = llvm::RISCVISAInfo::parseArchString(
+ Flag.drop_front(7), /*EnableExperimentalExtension=*/true,
+ /*ExperimentalExtensionVersionCheck=*/false);
+ if (!MLConfigParseResult) {
+ // Ignore any error here, we assume it will handled in another place.
+ llvm::consumeError(MLConfigParseResult.takeError());
+
+ // We might got parsing error if rv32e in the list, we could just skip
+ // that and process the rest of multi-lib configs.
+ Skip = true;
+ continue;
+ }
+ auto &MLConfigISAInfo = *MLConfigParseResult;
+
+ auto MLConfigArchExts = MLConfigISAInfo->getExtensions();
+ for (auto MLConfigArchExt : MLConfigArchExts) {
+ auto ExtName = MLConfigArchExt.first;
+ NewMultilib.flag(Twine("-", ExtName).str());
+
+ if (!AllArchExts.contains(ExtName)) {
+ AllArchExts.insert(ExtName);
+ addMultilibFlag(ISAInfo->hasExtension(ExtName),
+ Twine("-", ExtName).str(), NewFlags);
+ }
+ }
+
+ // Check the XLEN explicitly.
+ if (MLConfigISAInfo->getXLen() == 32) {
+ NewMultilib.flag("-m32");
+ NewMultilib.flag("!m64");
+ } else {
+ NewMultilib.flag("!m32");
+ NewMultilib.flag("-m64");
+ }
+
+ // Atomic extension must be explicitly checked, soft and hard atomic
+ // operation never co-work correctly.
+ if (!MLConfigISAInfo->hasExtension("a"))
+ NewMultilib.flag("!a");
+ }
+
+ if (Skip)
+ continue;
+
+ NewMultilibs.emplace_back(NewMultilib);
+ }
+
+ // Build an internal used only multi-lib list, used for checking any
+ // compatible multi-lib.
+ MultilibSet NewRISCVMultilibs =
+ MultilibSetBuilder().Either(NewMultilibs).makeMultilibSet();
+
+ if (NewRISCVMultilibs.select(NewFlags, SelectedMultilibs))
+ for (const Multilib &NewSelectedM : SelectedMultilibs)
+ for (auto M : RISCVMultilibSet)
+ // Look up the corresponding multi-lib entry in original multi-lib set.
+ if (M.gccSuffix() == NewSelectedM.gccSuffix())
+ return true;
+
+ return false;
+}
+
static void findRISCVBareMetalMultilibs(const Driver &D,
const llvm::Triple &TargetTriple,
StringRef Path, const ArgList &Args,
@@ -1727,9 +1851,10 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
// currently only support the set of multilibs like riscv-gnu-toolchain does.
// TODO: support MULTILIB_REUSE
constexpr RiscvMultilib RISCVMultilibSet[] = {
- {"rv32i", "ilp32"}, {"rv32im", "ilp32"}, {"rv32iac", "ilp32"},
- {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"},
- {"rv64imafdc", "lp64d"}};
+ {"rv32i", "ilp32"}, {"rv32ic", "ilp32"}, {"rv32if", "ilp32f"},
+ {"rv32im", "ilp32"}, {"rv32iac", "ilp32"}, {"rv32ifc", "ilp32"},
+ {"rv32imac", "ilp32"}, {"rv32imafc", "ilp32f"}, {"rv64imac", "lp64"},
+ {"rv64imac", "lp64"}, {"rv64imafdc", "lp64d"}};
std::vector<MultilibBuilder> Ms;
for (auto Element : RISCVMultilibSet) {
@@ -1766,7 +1891,8 @@ static void findRISCVBareMetalMultilibs(const Driver &D,
}
}
- if (RISCVMultilibs.select(Flags, Result.SelectedMultilibs))
+ if (RISCVMultilibSelect(RISCVMultilibs, MArch, Flags,
+ Result.SelectedMultilibs))
Result.Multilibs = RISCVMultilibs;
}
diff --git a/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ic/ilp32/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ic/ilp32/crtbegin.o
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32if/ilp32f/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32if/ilp32f/crtbegin.o
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32/crtbegin.o
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32f/crtbegin.o b/clang/test/Driver/Inputs/multilib_riscv_elf_sdk/lib/gcc/riscv64-unknown-elf/8.2.0/rv32ifc/ilp32f/crtbegin.o
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c b/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c
new file mode 100644
index 000000000000000..7a1bca76fee8ec4
--- /dev/null
+++ b/clang/test/Driver/riscv-toolchain-gcc-multilib-reuse.c
@@ -0,0 +1,86 @@
+// Test case for scanning input of GCC output as multilib config
+// Skip this test on Windows, we can't create a dummy GCC to output
+// multilib config, ExecuteAndWait only execute *.exe file.
+// UNSUPPORTED: system-windows
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imc -mabi=ilp32 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMC-ILP32 %s
+// GCC-MULTI-LIB-REUSE-RV32IMC-ILP32: rv32im/ilp32
+// GCC-MULTI-LIB-REUSE-RV32IMC-ILP32-NOT: {{^.+$}}
+
+// Check rv32imac won't reuse rv32im or rv32ic
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imac -mabi=ilp32 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32 %s
+// GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32: rv32imac/ilp32
+// GCC-MULTI-LIB-REUSE-RV32IMAC-ILP32--NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32ifc -mabi=ilp32f \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IFC-ILP32F %s
+// GCC-MULTI-LIB-REUSE-RV32IFC-ILP32F: rv32if/ilp32f
+// GCC-MULTI-LIB-REUSE-RV32IFC-ILP32F-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imafdc -mabi=ilp32f \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F %s
+// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F: rv32imafc/ilp32f
+// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32F-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imafdc -mabi=ilp32d \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D %s
+// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D: .
+// GCC-MULTI-LIB-REUSE-RV32IMAFDC-ILP32D-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv64imafc -mabi=lp64 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64 %s
+// GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64: rv64imac/lp64
+// GCC-MULTI-LIB-REUSE-RV64IMAFC-LP64-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32imafc_zfh -mabi=ilp32 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32 %s
+// GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32: rv32imac/ilp32
+// GCC-MULTI-LIB-REUSE-RV32IMAFC_ZFH-ILP32-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv32i_zvkb -mabi=ilp32 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32 %s
+// GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32: rv32i/ilp32
+// GCC-MULTI-LIB-REUSE-RV32I_ZVKB-ILP32-NOT: {{^.+$}}
+
+// RUN: %clang %s \
+// RUN: -target riscv64-unknown-elf \
+// RUN: --gcc-toolchain=%S/Inputs/multilib_riscv_elf_sdk \
+// RUN: --print-multi-directory \
+// RUN: -march=rv64imfc -mabi=lp64 \
+// RUN: | FileCheck -check-prefix=GCC-MULTI-LIB-REUSE-RV64IMFC-LP64 %s
+// GCC-MULTI-LIB-REUSE-RV64IMFC-LP64: .
+// GCC-MULTI-LIB-REUSE-RV64IMFC-LP64-NOT: {{^.+$}}
|
4f6500b
to
c406872
Compare
c406872
to
fb09422
Compare
Resolved the comments and also fixed the typo of the commit messages. |
Extend the multi-lib re-use selection mechanism for RISC-V. This function will try to re-use multi-lib if they are compatible. Definition of compatible: - ABI must be the same. - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im is a subset of march=rv32imc. - march that contains atomic extension can't reuse multi-lib that doesn't have atomic, vice versa. e.g. multi-lib=march=rv32im and march=rv32ima are not compatible, because software and hardware atomic operation can't work together correctly.
fb09422
to
007fc93
Compare
007fc93
to
6caf21f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The new test is crashing in my Release+Asserts build:
|
Hello, looks like it broke some bots too: |
#75789) …toolchain (#73765)" This reverts commit 111a229, as it broke several bots https://lab.llvm.org/buildbot/#/builders/245/builds/18162 https://lab.llvm.org/buildbot/#/builders/188/builds/39436 https://lab.llvm.org/buildbot/#/builders/187/builds/13723 https://lab.llvm.org/buildbot/#/builders/182/builds/8449 https://lab.llvm.org/buildbot/#/builders/198/builds/7438 https://lab.llvm.org/buildbot/#/builders/176/builds/7419 https://lab.llvm.org/buildbot/#/builders/186/builds/13781 https://lab.llvm.org/buildbot/#/builders/183/builds/18116 https://lab.llvm.org/buildbot/#/builders/197/builds/11410 https://lab.llvm.org/buildbot/#/builders/184/builds/8651 When reapplying, please take care of another commit that have been merged after this one: c7cdf3c [clang] Use 'starts_with' instead of 'startswith' in Gnu.cpp (NFC)
… toolchain (llvm#73765) Extend the multi-lib re-use selection mechanism for RISC-V. This funciton will try to re-use multi-lib if they are compatible. Definition of compatible: - ABI must be the same. - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im is a subset of march=rv32imc. - march that contains atomic extension can't reuse multi-lib that doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and march=rv32ima are not compatible, because software and hardware atomic operation can't work together correctly.
…e-metal toolchain (llvm#73765)
… toolchain (#73765) (#75890) Extend the multi-lib re-use selection mechanism for RISC-V. This funciton will try to re-use multi-lib if they are compatible. Definition of compatible: - ABI must be the same. - multi-lib is a subset of current arch, e.g. multi-lib=march=rv32im is a subset of march=rv32imc. - march that contains atomic extension can't reuse multi-lib that doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and march=rv32ima are not compatible, because software and hardware atomic operation can't work together correctly.
Extend the multi-lib re-use selection mechanism for RISC-V.
This funciton will try to re-use multi-lib if they are compatible.
Definition of compatible:
is a subset of march=rv32imc.
doesn't has atomic, vice versa. e.g. multi-lib=march=rv32im and
march=rv32ima are not compatible, because software and hardware
atomic operation can't work together correctly.