DavidSpickett created this revision.
Herald added subscribers: Enna1, kristof.beyls, dberris.
Herald added a project: All.
DavidSpickett requested review of this revision.
Herald added subscribers: llvm-commits, Sanitizers, cfe-commits, MaskRay.
Herald added projects: clang, Sanitizers, LLVM.

The orginal single folder layout produced libraries in the form:
lib/linux/<libname>-<archname>.a

That archname for Arm depended on whether you had hard or soft float.
This is sometimes shown as "arm" (soft) vs. "armhf" (hard).

If this is set in a triple we do it in the final portion, the ABI.
"gnueabi" for soft float, "gnueabihf" for hard float.

Meaning that the expected triple is:
arm-unknown-linux-gnueabihf
Not this:
armhf-unknown-linux-gnueabihf

For the per target layout I have decided to rely on the ABI portion
of the triple instead of the arch name used for the old layout
(doing that would produce the invalid triple above).

This means that building with triple:
armv8l-unknown-linux-gnueabihf
Will result in libraries in:
lib/arm-unknown-linux-gnueabihf/

And clang will now know to look for "arm" instead of "armv8l".
Meaning that we can share libraries between an armv8 and armv7 build
as we did with the previous layout. In addition to handling spelling
differences e.g. "armv8l" with an "l" on some Linux distros.

compiler-rt will autodetect that the "armhf" and/or "arm" architecture
can be built. We then replace the given triple's architecture with that.
Then if the triple's float ABI doesn't match, we change that. That new
triple is then used as the folder name.

If you select to build only the given triple, with 
COMPILER_RT_DEFAULT_TARGET_ONLY,
compiler-rt will not autodetect the architecture and for that I assume you
know what you're doing. In that case the library path will use the unomdified 
triple.

>From what I can tell, this is how most large builds e.g Android and
Arm's Embedded Toolchain for llvm do things. I assume that big endian "armeb"
builds would end up doing this too.

Bare metal builds will not be using per target runtime dirs so they
remain as they were.

Depends on D139536 <https://reviews.llvm.org/D139536>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D140011

Files:
  clang/lib/Driver/ToolChain.cpp
  
clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-pc-windows-msvc/.keep
  
clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-unknown-linux-gnueabi/.keep
  
clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-unknown-linux-gnueabihf/.keep
  
clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/armeb-unknown-linux-gnueabi/.keep
  
clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/armeb-unknown-linux-gnueabihf/.keep
  clang/test/Driver/arm-float-abi-runtime-path.c
  compiler-rt/cmake/Modules/CompilerRTUtils.cmake
  llvm/CMakeLists.txt

Index: llvm/CMakeLists.txt
===================================================================
--- llvm/CMakeLists.txt
+++ llvm/CMakeLists.txt
@@ -816,7 +816,7 @@
 mark_as_advanced(LLVM_TARGET_TRIPLE_ENV)
 
 # Per target dir not yet supported on Arm 32 bit due to arm vs armhf handling
-if(CMAKE_SYSTEM_NAME MATCHES "BSD|Linux" AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
+if(CMAKE_SYSTEM_NAME MATCHES "BSD|Linux")
   set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default ON)
 else()
   set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR_default OFF)
Index: compiler-rt/cmake/Modules/CompilerRTUtils.cmake
===================================================================
--- compiler-rt/cmake/Modules/CompilerRTUtils.cmake
+++ compiler-rt/cmake/Modules/CompilerRTUtils.cmake
@@ -433,6 +433,25 @@
     string(REGEX REPLACE "mipsisa64" "mipsisa32" triple_cpu_mips "${triple_cpu}")
     string(REGEX REPLACE "mips64" "mips" triple_cpu_mips "${triple_cpu_mips}")
     set(target "${triple_cpu_mips}${triple_suffix_gnu}")
+  elseif("${arch}" MATCHES "^arm")
+    # Arch is arm, armhf, armv6m (anything else would come from using
+    # COMPILER_RT_DEFAULT_TARGET_ONLY, which is checked above).
+    if (${arch} STREQUAL "armhf")
+      # If we are building for hard float but our ABI is soft float.
+      if ("${triple_suffix}" MATCHES ".*eabi$")
+        # Change "eabi" -> "eabihf"
+        set(triple_suffix "${triple_suffix}hf")
+      endif()
+      # ABI is already set in the triple, don't repeat it in the architecture.
+      set(arch "arm")
+    else ()
+      # If we are building for soft float, but the triple's ABI is hard float.
+      if ("${triple_suffix}" MATCHES ".*eabihf$")
+        # Change "eabihf" -> "eabi"
+        string(REGEX REPLACE "hf$" "" triple_suffix "${triple_suffix}")
+      endif()
+    endif()
+    set(target "${arch}${triple_suffix}")
   else()
     set(target "${arch}${triple_suffix}")
   endif()
Index: clang/test/Driver/arm-float-abi-runtime-path.c
===================================================================
--- /dev/null
+++ clang/test/Driver/arm-float-abi-runtime-path.c
@@ -0,0 +1,33 @@
+/// Check that libraries built with the per target runtime directory layout
+/// are selected correctly when using variations of Arm triples.
+
+// REQUIRES: arm-registered-target
+
+// RUN: %clang %s -target arm-unknown-linux-gnueabihf -print-runtime-dir \
+// RUN:        -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARMHF %s
+/// "armv7l" should be normalised to just "arm".
+// RUN: %clang %s -target armv7l-unknown-linux-gnueabihf -print-runtime-dir \
+// RUN:        -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARMHF %s
+
+// RUN: %clang %s -target arm-unknown-linux-gnueabi -print-runtime-dir \
+// RUN:        -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARM %s
+// RUN: %clang %s -target armv7l-unknown-linux-gnueabi -print-runtime-dir \
+// RUN:        -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARM %s
+
+/// armeb triples should be unmodified.
+// RUN: %clang %s -target armeb-unknown-linux-gnueabihf -print-runtime-dir \
+// RUN:        -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARMEBHF %s
+// RUN: %clang %s -target armeb-unknown-linux-gnueabi -print-runtime-dir \
+// RUN:        -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=ARMEB %s
+
+// RUN: %clang %s -target arm-pc-windows-msvc -print-runtime-dir \
+// RUN:        -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=WINDOWS %s
+/// armhf-pc... isn't recognised so just check that the float-abi option is ignored
+// RUN: %clang %s -target arm-pc-windows-msvc -mfloat-abi=hard -print-runtime-dir \
+// RUN:        -resource-dir=%S/Inputs/arm_float_abi_runtime_path 2>&1 | FileCheck -check-prefix=WINDOWS %s
+
+// ARMHF:   lib{{/|\\}}arm-unknown-linux-gnueabihf{{$}}
+// ARM:     lib{{/|\\}}arm-unknown-linux-gnueabi{{$}}
+// ARMEBHF: lib{{/|\\}}armeb-unknown-linux-gnueabihf{{$}}
+// ARMEB:   lib{{/|\\}}armeb-unknown-linux-gnueabi{{$}}
+// WINDOWS: lib{{/|\\}}arm-pc-windows-msvc{{$}}
Index: clang/lib/Driver/ToolChain.cpp
===================================================================
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -550,6 +550,16 @@
 
   addPathForTriple(getTriple());
 
+  // armeb (big endian) is left out here on purpose so that we don't try to use
+  // little endian libraries in that case.
+  if (getTriple().getArch() == Triple::arm && !getTriple().isArmMClass()) {
+    // When building with per target runtime directories the architecture may
+    // have been normalised to simply "arm" from something like "armv8l".
+    llvm::Triple ArmTriple = getTriple();
+    ArmTriple.setArch(Triple::arm);
+    addPathForTriple(ArmTriple);
+  }
+
   // Android targets may include an API level at the end. We still want to fall
   // back on a path without the API level.
   if (getTriple().isAndroid() &&
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to