[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