diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2014-12-02 16:04:58 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2014-12-02 16:04:58 +0000 |
commit | d90dd7977e2d25a4f190c833114d97d354ce0590 (patch) | |
tree | 62459a8646ce57164c8f687edfeb4665580f5455 /clang/lib/CodeGen/CGExprComplex.cpp | |
parent | 870e7909243e0e7c02d40ce363aaf6bd53c28d21 (diff) | |
download | bcm5719-llvm-d90dd7977e2d25a4f190c833114d97d354ce0590.tar.gz bcm5719-llvm-d90dd7977e2d25a4f190c833114d97d354ce0590.zip |
Fix invalid calling convention used for libcalls on ARM.
ARM ABI specifies that all the libcalls use soft FP ABI
(even hard FP binaries). These days clang emits _mulsc3 / _muldc3
calls with default (C) calling convention which would be translated
into AAPCS_VFP LLVM calling and thus the result of complex
multiplication will be bogus.
Introduce a way for a target to specify explicitly calling
convention for libcalls. Right now this is temporary correctness
fix. Ultimately, we'll end with intrinsic for complex
multiplication and all calling convention decisions for libcalls
will be put into backend.
llvm-svn: 223123
Diffstat (limited to 'clang/lib/CodeGen/CGExprComplex.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExprComplex.cpp | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index 4700c7eef35..6b7826eef5d 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -582,13 +582,22 @@ ComplexPairTy ComplexExprEmitter::EmitComplexBinOpLibCall(StringRef LibCallName, Op.Ty->castAs<ComplexType>()->getElementType()); // We *must* use the full CG function call building logic here because the - // complex type has special ABI handling. - const CGFunctionInfo &FuncInfo = CGF.CGM.getTypes().arrangeFreeFunctionCall( - Op.Ty, Args, FunctionType::ExtInfo(), RequiredArgs::All); + // complex type has special ABI handling. We also should not forget about + // special calling convention which may be used for compiler builtins. + const CGFunctionInfo &FuncInfo = + CGF.CGM.getTypes().arrangeFreeFunctionCall( + Op.Ty, Args, FunctionType::ExtInfo(/* No CC here - will be added later */), + RequiredArgs::All); llvm::FunctionType *FTy = CGF.CGM.getTypes().GetFunctionType(FuncInfo); - llvm::Constant *Func = CGF.CGM.CreateRuntimeFunction(FTy, LibCallName); + llvm::Constant *Func = CGF.CGM.CreateBuiltinFunction(FTy, LibCallName); + llvm::Instruction *Call; - return CGF.EmitCall(FuncInfo, Func, ReturnValueSlot(), Args).getComplexVal(); + RValue Res = CGF.EmitCall(FuncInfo, Func, ReturnValueSlot(), Args, + nullptr, &Call); + cast<llvm::CallInst>(Call)->setCallingConv(CGF.CGM.getBuiltinCC()); + cast<llvm::CallInst>(Call)->setDoesNotThrow(); + + return Res.getComplexVal(); } /// \brief Lookup the libcall name for a given floating point type complex |