diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -578,6 +578,27 @@ addPathForTriple(getTriple()); + // 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". + // Since an armv8l system can use libraries built for earlier architecture + // versions assuming endian and float ABI match. + // + // Original triple: armv8l-unknown-linux-gnueabihf + // Runtime triple: arm-unknown-linux-gnueabihf + // + // We do not do this for armeb (big endian) because doing so could make us + // select little endian libraries. In addition, all known armeb triples only + // use the "armeb" architecture name. + // + // 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); + 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() && diff --git a/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-pc-windows-msvc/.keep b/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-pc-windows-msvc/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-unknown-linux-gnueabi/.keep b/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-unknown-linux-gnueabi/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-unknown-linux-gnueabihf/.keep b/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/arm-unknown-linux-gnueabihf/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/armeb-unknown-linux-gnueabi/.keep b/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/armeb-unknown-linux-gnueabi/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/armeb-unknown-linux-gnueabihf/.keep b/clang/test/Driver/Inputs/arm_float_abi_runtime_path/lib/armeb-unknown-linux-gnueabihf/.keep new file mode 100644 diff --git a/clang/test/Driver/arm-float-abi-runtime-path.c b/clang/test/Driver/arm-float-abi-runtime-path.c new file mode 100644 --- /dev/null +++ b/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{{$}} diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/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() diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -817,8 +817,7 @@ set(LLVM_TARGET_TRIPLE_ENV CACHE STRING "The name of environment variable to override default target. Disabled by blank.") 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)