From 61a5983d8ba6eea3f535a33ab80374a5fe6b515b Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Tue, 19 Sep 2017 12:37:23 -0700 Subject: [PATCH 3/3] 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 27dda93387b..53ba8f4dd52 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -225,6 +225,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 || @@ -238,6 +240,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