Skip to content

Commit 4513f17

Browse files
committed
[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 llvm#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`.
1 parent 430b254 commit 4513f17

File tree

18 files changed

+72
-8
lines changed

18 files changed

+72
-8
lines changed

clang/lib/Driver/ToolChain.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -766,9 +766,19 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
766766
return {};
767767
};
768768

769-
if (auto Path = getPathForTriple(getTriple()))
769+
llvm::Triple Triple = getTriple();
770+
771+
// Try triple as is.
772+
if (auto Path = getPathForTriple(Triple))
770773
return *Path;
771774

775+
// Match transformations in CompilerRTUtils.cmake:get_compiler_rt_target.
776+
if (Triple.getArchName() == "amd64")
777+
Triple.setArch(Triple::x86_64);
778+
779+
if (Triple.getArchName() == "sparc64")
780+
Triple.setArch(Triple::sparcv9);
781+
772782
// When building with per target runtime directories, various ways of naming
773783
// the Arm architecture may have been normalised to simply "arm".
774784
// For example "armv8l" (Armv8 AArch32 little endian) is replaced with "arm".
@@ -784,16 +794,15 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
784794
//
785795
// M profile Arm is bare metal and we know they will not be using the per
786796
// target runtime directory layout.
787-
if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) {
788-
llvm::Triple ArmTriple = getTriple();
789-
ArmTriple.setArch(Triple::arm);
790-
if (auto Path = getPathForTriple(ArmTriple))
791-
return *Path;
792-
}
797+
if (Triple.getArch() == Triple::arm && !Triple.isArmMClass())
798+
Triple.setArch(Triple::arm);
793799

794-
if (getTriple().isAndroid())
800+
if (Triple.isAndroid())
795801
return getFallbackAndroidTargetPath(BaseDir);
796802

803+
if (auto Path = getPathForTriple(Triple))
804+
return *Path;
805+
797806
return {};
798807
}
799808

clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/Scrt1.o

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crti.o

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/lib/sparc64-linux-gnu/crtn.o

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtbeginS.o

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/crtendS.o

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc.a

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/gcc/sparc64-linux-gnu/12/libgcc_s.so

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libc.so

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libdl.so

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libm.so

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libpthread.so

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/libresolv.so

Whitespace-only changes.

clang/test/Driver/Inputs/debian_sparc64_tree/usr/lib/sparc64-linux-gnu/librt.so

Whitespace-only changes.

clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/sparcv9-unknown-linux-gnu/libclang_rt.ubsan_standalone.a

Whitespace-only changes.

clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/x86_64-pc-solaris2.11/libclang_rt.ubsan_standalone.a

Whitespace-only changes.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/// Check that clang's and compiler-rt's ideas of per-target runtime dirs match.
2+
3+
// RUN: %clang -### %s 2>&1 \
4+
// RUN: --target=amd64-pc-solaris2.11 -fsanitize=undefined \
5+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
6+
// RUN: --sysroot=%S/Inputs/solaris_x86_tree \
7+
// RUN: | FileCheck --check-prefix=CHECK-SOLARIS-AMD64 %s
8+
9+
// CHECK-SOLARIS-AMD64: x86_64-pc-solaris2.11/libclang_rt.ubsan_standalone.a
10+
// CHECK-SOLARIS-AMD64-NOT: lib/sunos/libclang_rt.ubsan_standalone-x86_64.a"
11+
12+
// RUN: %clang -### %s 2>&1 \
13+
// RUN: --target=sparc64-unknown-linux-gnu -fsanitize=undefined \
14+
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
15+
// RUN: --sysroot=%S/Inputs/debian_sparc64_tree \
16+
// RUN: | FileCheck --check-prefix=CHECK-DEBIAN-SPARC64 %s
17+
18+
// CHECK-DEBIAN-SPARC64: sparcv9-unknown-linux-gnu/libclang_rt.ubsan_standalone.a
19+
// CHECK-DEBIAN-SPARC64-NOT: lib/linux/libclang_rt.ubsan_standalone-sparcv9.a"
20+

clang/test/Driver/runtime-layout.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/// Check that clang's idea of runtime dir layout matches e.g. compiler-rt's.
2+
3+
/// Classical runtime layout.
4+
///
5+
/// Cannot be tested: clang -print-runtime-dir always prints the new path even
6+
/// if only the old directories exist.
7+
8+
/// New runtime layout.
9+
10+
// RUN: mkdir -p %t-runtime/lib/x86_64-pc-solaris2.11
11+
12+
/// Canonical triple, 64-bit.
13+
// RUN: %clang -print-runtime-dir --target=x86_64-pc-solaris2.11 \
14+
// RUN: -resource-dir=%t-runtime \
15+
// RUN: | FileCheck --check-prefix=RUNTIME-DIR-X86_64 %s
16+
17+
/// Non-canonical triple, 64-bit.
18+
// RUN: %clang -print-runtime-dir --target=amd64-pc-solaris2.11 \
19+
// RUN: -resource-dir=%t-runtime \
20+
// RUN: | FileCheck --check-prefix=RUNTIME-DIR-X86_64 %s
21+
22+
// RUNTIME-DIR-X86_64: {{.*}}/lib/x86_64-pc-solaris2.11
23+
24+
// RUN: mkdir -p %t-runtime/lib/i386-pc-solaris2.11
25+
26+
/// Canonical triple, 32-bit.
27+
// RUN: %clang -print-runtime-dir --target=i386-pc-solaris2.11 \
28+
// RUN: -resource-dir=%t-runtime \
29+
// RUN: | FileCheck --check-prefix=RUNTIME-DIR-I386 %s
30+
31+
/// Non-canonical triple, 32-bit.
32+
/// clang doesn't normalize --target=i686-pc-solaris2.11 to i386-pc-solaris2.11
33+
/// subdir.
34+
35+
// RUNTIME-DIR-I386: {{.*}}/lib/i386-pc-solaris2.11

0 commit comments

Comments
 (0)