Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -226,6 +226,8 @@ 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 || @@ -239,6 +241,75 @@ 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()) { Index: test/CodeGen/Thumb2/intrinsics-cc.ll =================================================================== --- test/CodeGen/Thumb2/intrinsics-cc.ll +++ 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 @@ 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 @@ ; 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