From 2c1619639ee5b4331c78c794fdfd2a0d5d778b2f Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Thu, 21 Sep 2017 14:51:23 -0700 Subject: llvm: Fix wrong code generation when floor() libm function is called see https://reviews.llvm.org/D38050 Signed-off-by: Khem Raj --- recipes-devtools/clang/clang.inc | 8 +- ...M-Use-correct-calling-convention-for-libm.patch | 152 +++++++++++++++++++++ recipes-devtools/clang/clang_git.bb | 1 + 3 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 recipes-devtools/clang/clang/0005-llvm-ARM-Use-correct-calling-convention-for-libm.patch diff --git a/recipes-devtools/clang/clang.inc b/recipes-devtools/clang/clang.inc index b8bf28f..3f488ad 100644 --- a/recipes-devtools/clang/clang.inc +++ b/recipes-devtools/clang/clang.inc @@ -9,16 +9,16 @@ LLVM_GIT_PROTOCOL ?= "git" # MAJOR_VER="4" MINOR_VER="0" -PATCH_VER="0" +PATCH_VER="1" PV = "${MAJOR_VER}.${MINOR_VER}.${PATCH_VER}" BRANCH = "release_40" -SRCREV_llvm = "5ed13a6cd922be74ad12b1ba36c15906336e0e3b" -SRCREV_clang = "21fe7e8f8ab44b67238af7bf9ba9d8afdf0c0e2c" +SRCREV_llvm = "c8fccc53ed66d505898f8850bcc690c977a7c9a7" +SRCREV_clang = "3c8961bedc65c9a15cbe67a2ef385a0938f7cfef" SRCREV_compiler-rt = "76ab2e5c9b2a2e3d638e217cc21622f9be54f633" SRCREV_cxxabi = "c4e6c8a10dea6f569fa99d56945ec1eba4be40dd" SRCREV_libcxx = "2a0436688e5f1cf233b5cef9d9d0a4dc6acf8a97" SRCREV_libunwind = "e1a24d4951a60ea51a7bd2505d6cc16c0bcb2c61" -SRCREV_lld = "ada5756959e1356d1911702872ba625b8ee67210" +SRCREV_lld = "4439e42e1a3dcc6bf15fdb00114e4fc598b9d614" SRCREV_lldb = "fcd2aac9f179b968a20cf0231c3386dcef8a6659" LLVMMD5SUM = "e825e017edc35cfd58e26116e5251771" diff --git a/recipes-devtools/clang/clang/0005-llvm-ARM-Use-correct-calling-convention-for-libm.patch b/recipes-devtools/clang/clang/0005-llvm-ARM-Use-correct-calling-convention-for-libm.patch new file mode 100644 index 0000000..7fdcdaa --- /dev/null +++ b/recipes-devtools/clang/clang/0005-llvm-ARM-Use-correct-calling-convention-for-libm.patch @@ -0,0 +1,152 @@ +From 5531764382f76556fe79c1584e0461d25be2f47f Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Tue, 19 Sep 2017 12:37:23 -0700 +Subject: [PATCH 4/4] llvm: [ARM] Use correct calling convention for libm + +-mfloat-abi doesn't control the calling convention for compiler-rt: it's built with the compiler, so it can only have one calling convention for a given target. -mfloat-abi does control the calling convention for any function provided by libm: libm is built by the user, so the user should have control over its calling convention. See https://bugs.llvm.org/show_bug.cgi?id=30543 for previous discussion on the subject. + +Signed-off-by: Khem Raj +--- + lib/Target/ARM/ARMISelLowering.cpp | 71 ++++++++++++++++++++++++++++++++++++ + test/CodeGen/Thumb2/intrinsics-cc.ll | 25 ++++++++++++- + 2 files changed, 94 insertions(+), 2 deletions(-) + +diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp +index d75d6968f68..87d25a252cd 100644 +--- a/lib/Target/ARM/ARMISelLowering.cpp ++++ b/lib/Target/ARM/ARMISelLowering.cpp +@@ -186,6 +186,8 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, + + if (!Subtarget->isTargetDarwin() && !Subtarget->isTargetIOS() && + !Subtarget->isTargetWatchOS()) { ++ // Most builtins have their calling convention determined by the ++ // target (they don't vary with -float-abi). + const auto &E = Subtarget->getTargetTriple().getEnvironment(); + + bool IsHFTarget = E == Triple::EABIHF || E == Triple::GNUEABIHF || +@@ -199,6 +201,75 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, + setLibcallCallingConv(static_cast(LCID), + IsHFTarget ? CallingConv::ARM_AAPCS_VFP + : CallingConv::ARM_AAPCS); ++ ++ // Builtins provided by libm have their calling convention determined by ++ // -float-abi. ++ bool IsHFMode = TM.Options.FloatABIType == FloatABI::Hard; ++ CallingConv::ID LibmConv = IsHFMode ? CallingConv::ARM_AAPCS_VFP ++ : CallingConv::ARM_AAPCS; ++ setLibcallCallingConv(RTLIB::REM_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::REM_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::REM_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::FMA_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::FMA_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::FMA_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::SQRT_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::SQRT_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::SQRT_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG2_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG2_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG2_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG10_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG10_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::LOG10_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::EXP_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::EXP_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::EXP_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::EXP2_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::EXP2_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::EXP2_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::SIN_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::SIN_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::SIN_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::COS_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::COS_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::COS_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::SINCOS_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::SINCOS_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::SINCOS_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::POW_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::POW_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::POW_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::CEIL_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::CEIL_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::CEIL_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::TRUNC_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::TRUNC_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::TRUNC_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::RINT_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::RINT_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::RINT_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::NEARBYINT_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::NEARBYINT_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::NEARBYINT_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::ROUND_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::ROUND_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::ROUND_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::FLOOR_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::FLOOR_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::FLOOR_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::COPYSIGN_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::COPYSIGN_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::COPYSIGN_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::FMIN_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::FMIN_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::FMIN_F128, LibmConv); ++ setLibcallCallingConv(RTLIB::FMAX_F32, LibmConv); ++ setLibcallCallingConv(RTLIB::FMAX_F64, LibmConv); ++ setLibcallCallingConv(RTLIB::FMAX_F128, LibmConv); + } + + if (Subtarget->isTargetMachO()) { +diff --git a/test/CodeGen/Thumb2/intrinsics-cc.ll b/test/CodeGen/Thumb2/intrinsics-cc.ll +index ab5081e3ab9..3a3014fc919 100644 +--- a/test/CodeGen/Thumb2/intrinsics-cc.ll ++++ b/test/CodeGen/Thumb2/intrinsics-cc.ll +@@ -15,7 +15,7 @@ + + declare float @llvm.powi.f32(float, i32) + +-define float @f(float %f, i32 %i) { ++define float @powi_f32(float %f, i32 %i) { + entry: + %0 = call float @llvm.powi.f32(float %f, i32 %i) + ret float %0 +@@ -28,7 +28,7 @@ entry: + + declare double @llvm.powi.f64(double, i32) + +-define double @g(double %d, i32 %i) { ++define double @powi_f64(double %d, i32 %i) { + entry: + %0 = call double @llvm.powi.f64(double %d, i32 %i) + ret double %0 +@@ -39,3 +39,24 @@ entry: + ; CHECK-TO-SOFT: vmov d0, r0, r1 + ; CHECK-TO-HARD: vmov r0, r1, d0 + ++declare float @llvm.floor.f32(float) ++ ++define float @floor_f32(float %f) { ++entry: ++ %0 = call float @llvm.floor.f32(float %f) ++ ret float %0 ++} ++ ++; CHECK-MATCH: b floorf ++; CHECK-MISMATCH: b floorf ++ ++declare double @llvm.floor.f64(double) ++ ++define double @floor_f64(double %d) { ++entry: ++ %0 = call double @llvm.floor.f64(double %d) ++ ret double %0 ++} ++ ++; CHECK-MATCH: b floor ++; CHECK-MISMATCH: b floor +-- +2.14.1 + diff --git a/recipes-devtools/clang/clang_git.bb b/recipes-devtools/clang/clang_git.bb index 2942dff..8a89005 100644 --- a/recipes-devtools/clang/clang_git.bb +++ b/recipes-devtools/clang/clang_git.bb @@ -23,6 +23,7 @@ SRC_URI += "\ file://0002-llvm-Do-not-assume-linux-glibc.patch \ file://0003-llvm-TargetLibraryInfo-Undefine-libc-functions-if-th.patch \ file://0004-llvm-allow-env-override-of-exe-path.patch \ + file://0005-llvm-ARM-Use-correct-calling-convention-for-libm.patch \ " # Clang patches -- cgit v1.2.3-54-g00ecf