[clang] [Driver] Have getTargetSubDirPath better match get_compiler_rt_target (PR #100091)
Rainer Orth via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 23 02:39:02 PDT 2024
https://github.com/rorth created https://github.com/llvm/llvm-project/pull/100091
As explained in [[Driver] Support non-canonical triples with new runtime lib layout](https://reviews.llvm.org/D133407), there are massive problems if `clang`'s and `compiler-rt`'s ideas of the target triple don't match. This can happen e.g. on Solaris/amd64 (`amd64-pc-solaris2.11`, `amd64` being the customary name of 64-bit x86 on that target) or Linux/sparc64 (`sparc64-unknown-linux-gnu`, where `config.sub` returns the `sparc64` form by default).
While some adjustments have been made in `compiler-rt` ([[compiler-rt] Handle non-canonical triples with new runtime lib
layout](https://reviews.llvm.org/D133406)), the `clang` side is still unfixed and the previous patch doesn't work any longer.
As the stop-gap measure, this patch takes two of the adjustments made in `CompilerRTUtils.cmake` (`get_compiler_rt_target`) and applies them to `ToolChain.cpp` (`getTargetSubDirPath`) which currently takes the target triple as is, creating a mismatch between `clang`s idea of the layout of `lib/clang/<vers>/<triple>` and where `compiler-rt` actually installs the runtime libs.
The tests had to be trimmed massively because `clang -print-runtime-dir` lies since PR #87866: when the runtime libs are installed in the projects/classic layout, `clang` still emits the nonexisting runtimes layout.
Tested on `amd64-pc-solaris2.11` and `x86_64-pc-linux-gnu`.
>From 4513f179765b432305bf79c71f691fcbb3fdc264 Mon Sep 17 00:00:00 2001
From: Rainer Orth <ro at gcc.gnu.org>
Date: Tue, 23 Jul 2024 11:36:07 +0200
Subject: [PATCH] [Driver] Have getTargetSubDirPath better match
get_compiler_rt_target
As explained in [[Driver] Support non-canonical triples with new runtime
lib layout](https://reviews.llvm.org/D133407), there are massive problems
if `clang`'s and `compiler-rt`'s ideas of the target triple don't match.
This can happen e.g. on Solaris/amd64 (`amd64-pc-solaris2.11`, `amd64`
being the customary name of 64-bit x86 on that target) or Linux/sparc64
(`sparc64-unknown-linux-gnu`, where `config.sub` returns the `sparc64` form
by default).
While some adjustments have been made in `compiler-rt` ([[compiler-rt]
Handle non-canonical triples with new runtime lib
layout](https://reviews.llvm.org/D133406)), the `clang` side is still
unfixed and the previous patch doesn't work any longer.
As the stop-gap measure, this patch takes two of the adjustments made in
`CompilerRTUtils.cmake` (`get_compiler_rt_target`) and applies them to
`ToolChain.cpp` (`getTargetSubDirPath`) which currently takes the target
triple as is, creating a mismatch between `clang`s idea of the layout of
`lib/clang/<vers>/<triple>` and where `compiler-rt` actually installs the
runtime libs.
The tests had to be trimmed massively because `clang -print-runtime-dir`
lies since PR #87866: when the runtime libs are installed in the
projects/classic layout, `clang` still emits the nonexisting runtimes
layout.
Tested on `amd64-pc-solaris2.11` and `x86_64-pc-linux-gnu`.
---
clang/lib/Driver/ToolChain.cpp | 25 ++++++++-----
.../lib/sparc64-linux-gnu/Scrt1.o | 0
.../lib/sparc64-linux-gnu/crti.o | 0
.../lib/sparc64-linux-gnu/crtn.o | 0
.../lib/gcc/sparc64-linux-gnu/12/crtbeginS.o | 0
.../lib/gcc/sparc64-linux-gnu/12/crtendS.o | 0
.../usr/lib/gcc/sparc64-linux-gnu/12/libgcc.a | 0
.../lib/gcc/sparc64-linux-gnu/12/libgcc_s.so | 0
.../usr/lib/sparc64-linux-gnu/libc.so | 0
.../usr/lib/sparc64-linux-gnu/libdl.so | 0
.../usr/lib/sparc64-linux-gnu/libm.so | 0
.../usr/lib/sparc64-linux-gnu/libpthread.so | 0
.../usr/lib/sparc64-linux-gnu/libresolv.so | 0
.../usr/lib/sparc64-linux-gnu/librt.so | 0
.../libclang_rt.ubsan_standalone.a | 0
.../libclang_rt.ubsan_standalone.a | 0
.../Driver/noncanon-per-target-runtime-dir.c | 20 +++++++++++
clang/test/Driver/runtime-layout.c | 35 +++++++++++++++++++
18 files changed, 72 insertions(+), 8 deletions(-)
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/Scrt1.o
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crti.o
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crtn.o
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtbeginS.o
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtendS.o
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc.a
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc_s.so
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libc.so
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libdl.so
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libm.so
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libpthread.so
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libresolv.so
create mode 100644 clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/librt.so
create mode 100644 clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/sparcv9-unknown-linux-gnu/libclang_rt.ubsan_standalone.a
create mode 100644 clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-pc-solaris2.11/libclang_rt.ubsan_standalone.a
create mode 100644 clang/test/Driver/noncanon-per-target-runtime-dir.c
create mode 100644 clang/test/Driver/runtime-layout.c
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 20a555afb8092..10434b987ae1d 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -766,9 +766,19 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
return {};
};
- if (auto Path = getPathForTriple(getTriple()))
+ llvm::Triple Triple = getTriple();
+
+ // Try triple as is.
+ if (auto Path = getPathForTriple(Triple))
return *Path;
+ // Match transformations in CompilerRTUtils.cmake:get_compiler_rt_target.
+ if (Triple.getArchName() == "amd64")
+ Triple.setArch(Triple::x86_64);
+
+ if (Triple.getArchName() == "sparc64")
+ Triple.setArch(Triple::sparcv9);
+
// When building with per target runtime directories, various ways of naming
// the Arm architecture may have been normalised to simply "arm".
// For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm".
@@ -784,16 +794,15 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
//
// M profile Arm is bare metal and we know they will not be using the per
// target runtime directory layout.
- if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) {
- llvm::Triple ArmTriple = getTriple();
- ArmTriple.setArch(Triple::arm);
- if (auto Path = getPathForTriple(ArmTriple))
- return *Path;
- }
+ if (Triple.getArch() == Triple::arm && !Triple.isArmMClass())
+ Triple.setArch(Triple::arm);
- if (getTriple().isAndroid())
+ if (Triple.isAndroid())
return getFallbackAndroidTargetPath(BaseDir);
+ if (auto Path = getPathForTriple(Triple))
+ return *Path;
+
return {};
}
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/Scrt1.o b/clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/Scrt1.o
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crti.o b/clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crti.o
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crtn.o b/clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crtn.o
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtbeginS.o b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtbeginS.o
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtendS.o b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtendS.o
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc.a b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc.a
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc_s.so b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc_s.so
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libc.so b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libc.so
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libdl.so b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libdl.so
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libm.so b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libm.so
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libpthread.so b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libpthread.so
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libresolv.so b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libresolv.so
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/librt.so b/clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/librt.so
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/sparcv9-unknown-linux-gnu/libclang_rt.ubsan_standalone.a b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/sparcv9-unknown-linux-gnu/libclang_rt.ubsan_standalone.a
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-pc-solaris2.11/libclang_rt.ubsan_standalone.a b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-pc-solaris2.11/libclang_rt.ubsan_standalone.a
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/Driver/noncanon-per-target-runtime-dir.c b/clang/test/Driver/noncanon-per-target-runtime-dir.c
new file mode 100644
index 0000000000000..79ebd6bfbb11b
--- /dev/null
+++ b/clang/test/Driver/noncanon-per-target-runtime-dir.c
@@ -0,0 +1,20 @@
+/// Check that clang's and compiler-rt's ideas of per-target runtime dirs match.
+
+// RUN: %clang -### %s 2>&1 \
+// RUN: --target=amd64-pc-solaris2.11 -fsanitize=undefined \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: --sysroot=%S/Inputs/solaris_x86_tree \
+// RUN: | FileCheck --check-prefix=CHECK-SOLARIS-AMD64 %s
+
+// CHECK-SOLARIS-AMD64: x86_64-pc-solaris2.11/libclang_rt.ubsan_standalone.a
+// CHECK-SOLARIS-AMD64-NOT: lib/sunos/libclang_rt.ubsan_standalone-x86_64.a"
+
+// RUN: %clang -### %s 2>&1 \
+// RUN: --target=sparc64-unknown-linux-gnu -fsanitize=undefined \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: --sysroot=%S/Inputs/debian_sparc64_tree \
+// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC64 %s
+
+// CHECK-DEBIAN-SPARC64: sparcv9-unknown-linux-gnu/libclang_rt.ubsan_standalone.a
+// CHECK-DEBIAN-SPARC64-NOT: lib/linux/libclang_rt.ubsan_standalone-sparcv9.a"
+
diff --git a/clang/test/Driver/runtime-layout.c b/clang/test/Driver/runtime-layout.c
new file mode 100644
index 0000000000000..55021d45d35e4
--- /dev/null
+++ b/clang/test/Driver/runtime-layout.c
@@ -0,0 +1,35 @@
+/// Check that clang's idea of runtime dir layout matches e.g. compiler-rt's.
+
+/// Classical runtime layout.
+///
+/// Cannot be tested: clang -print-runtime-dir always prints the new path even
+/// if only the old directories exist.
+
+/// New runtime layout.
+
+// RUN: mkdir -p %t-runtime/lib/x86_64-pc-solaris2.11
+
+/// Canonical triple, 64-bit.
+// RUN: %clang -print-runtime-dir --target=x86_64-pc-solaris2.11 \
+// RUN: -resource-dir=%t-runtime \
+// RUN: | FileCheck --check-prefix=RUNTIME-DIR-X86_64 %s
+
+/// Non-canonical triple, 64-bit.
+// RUN: %clang -print-runtime-dir --target=amd64-pc-solaris2.11 \
+// RUN: -resource-dir=%t-runtime \
+// RUN: | FileCheck --check-prefix=RUNTIME-DIR-X86_64 %s
+
+// RUNTIME-DIR-X86_64: {{.*}}/lib/x86_64-pc-solaris2.11
+
+// RUN: mkdir -p %t-runtime/lib/i386-pc-solaris2.11
+
+/// Canonical triple, 32-bit.
+// RUN: %clang -print-runtime-dir --target=i386-pc-solaris2.11 \
+// RUN: -resource-dir=%t-runtime \
+// RUN: | FileCheck --check-prefix=RUNTIME-DIR-I386 %s
+
+/// Non-canonical triple, 32-bit.
+/// clang doesn't normalize --target=i686-pc-solaris2.11 to i386-pc-solaris2.11
+/// subdir.
+
+// RUNTIME-DIR-I386: {{.*}}/lib/i386-pc-solaris2.11
More information about the cfe-commits
mailing list