summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2014-03-10 20:49:45 +0000
committerEvan Cheng <evan.cheng@apple.com>2014-03-10 20:49:45 +0000
commit0e8f4612a9cd90f047652bb8689cd7aa3c231c4a (patch)
tree4e300fd37f216dfb563c855b9b3143946b230ca8 /llvm/lib/Transforms/Utils/BuildLibCalls.cpp
parentbde27d2451a9bbfe759c51224f218e3dc62c2e9c (diff)
downloadbcm5719-llvm-0e8f4612a9cd90f047652bb8689cd7aa3c231c4a.tar.gz
bcm5719-llvm-0e8f4612a9cd90f047652bb8689cd7aa3c231c4a.zip
For functions with ARM target specific calling convention, when simplify-libcall
optimize a call to a llvm intrinsic to something that invovles a call to a C library call, make sure it sets the right calling convention on the call. e.g. extern double pow(double, double); double t(double x) { return pow(10, x); } Compiles to something like this for AAPCS-VFP: define arm_aapcs_vfpcc double @t(double %x) #0 { entry: %0 = call double @llvm.pow.f64(double 1.000000e+01, double %x) ret double %0 } declare double @llvm.pow.f64(double, double) #1 Simplify libcall (part of instcombine) will turn the above into: define arm_aapcs_vfpcc double @t(double %x) #0 { entry: %__exp10 = call double @__exp10(double %x) #1 ret double %__exp10 } declare double @__exp10(double) The pre-instcombine code works because calls to LLVM builtins are special. Instruction selection will chose the right calling convention for the call. However, the code after instcombine is wrong. The call to __exp10 will use the C calling convention. I can think of 3 options to fix this. 1. Make "C" calling convention just work since the target should know what CC is being used. This doesn't work because each function can use different CC with the "pcs" attribute. 2. Have Clang add the right CC keyword on the calls to LLVM builtin. This will work but it doesn't match the LLVM IR specification which states these are "Standard C Library Intrinsics". 3. Fix simplify libcall so the resulting calls to the C routines will have the proper CC keyword. e.g. %__exp10 = call arm_aapcs_vfpcc double @__exp10(double %x) #1 This works and is the solution I implemented here. Both solutions #2 and #3 would work. After carefully considering the pros and cons, I decided to implement #3 for the following reasons. 1. It doesn't change the "spec" of the intrinsics. 2. It's a self-contained fix. There are a couple of potential downsides. 1. There could be other places in the optimizer that is broken in the same way that's not addressed by this. 2. There could be other calling conventions that need to be propagated by simplify-libcall that's not handled. But for now, this is the fix that I'm most comfortable with. llvm-svn: 203488
Diffstat (limited to 'llvm/lib/Transforms/Utils/BuildLibCalls.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/BuildLibCalls.cpp281
1 files changed, 233 insertions, 48 deletions
diff --git a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
index 82384a1edf5..8b126a4d9c4 100644
--- a/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/BuildLibCalls.cpp
@@ -37,7 +37,8 @@ Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
if (!TLI->has(LibFunc::strlen))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[2];
AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
@@ -52,8 +53,18 @@ Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
B.getInt8PtrTy(),
NULL);
CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
- if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(StrLen->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
return CI;
}
@@ -66,7 +77,8 @@ Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
if (!TLI->has(LibFunc::strnlen))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[2];
AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
@@ -82,8 +94,18 @@ Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
TD->getIntPtrType(Context),
NULL);
CallInst *CI = B.CreateCall2(StrNLen, CastToCStr(Ptr, B), MaxLen, "strnlen");
- if (const Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(StrNLen->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
return CI;
}
@@ -96,7 +118,8 @@ Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
if (!TLI->has(LibFunc::strchr))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
AttributeSet AS =
AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
@@ -110,8 +133,19 @@ Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
I8Ptr, I8Ptr, I32Ty, NULL);
CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
ConstantInt::get(I32Ty, C), "strchr");
- if (const Function *F = dyn_cast<Function>(StrChr->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(StrChr->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
@@ -122,7 +156,8 @@ Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
if (!TLI->has(LibFunc::strncmp))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[3];
AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
@@ -141,8 +176,18 @@ Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
CallInst *CI = B.CreateCall3(StrNCmp, CastToCStr(Ptr1, B),
CastToCStr(Ptr2, B), Len, "strncmp");
- if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
return CI;
}
@@ -155,7 +200,8 @@ Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
if (!TLI->has(LibFunc::strcpy))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[2];
AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
@@ -166,8 +212,19 @@ Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
I8Ptr, I8Ptr, I8Ptr, NULL);
CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
Name);
- if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
@@ -179,7 +236,8 @@ Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
if (!TLI->has(LibFunc::strncpy))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[2];
AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
@@ -192,8 +250,19 @@ Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
Len->getType(), NULL);
CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
Len, "strncpy");
- if (const Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(StrNCpy->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
@@ -206,7 +275,8 @@ Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
if (!TLI->has(LibFunc::memcpy_chk))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS;
AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
Attribute::NoUnwind);
@@ -221,8 +291,19 @@ Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Dst = CastToCStr(Dst, B);
Src = CastToCStr(Src, B);
CallInst *CI = B.CreateCall4(MemCpy, Dst, Src, Len, ObjSize);
- if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
@@ -234,7 +315,8 @@ Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
if (!TLI->has(LibFunc::memchr))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS;
Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind };
AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
@@ -249,8 +331,18 @@ Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
NULL);
CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
- if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
return CI;
}
@@ -262,7 +354,8 @@ Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
if (!TLI->has(LibFunc::memcmp))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[3];
AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
@@ -280,8 +373,18 @@ Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
Len, "memcmp");
- if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
return CI;
}
@@ -310,13 +413,24 @@ Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
SmallString<20> NameBuffer;
AppendTypeSuffix(Op, Name, NameBuffer);
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Op->getType(), NULL);
CallInst *CI = B.CreateCall(Callee, Op, Name);
CI->setAttributes(Attrs);
- if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
return CI;
}
@@ -331,13 +445,24 @@ Value *llvm::EmitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
SmallString<20> NameBuffer;
AppendTypeSuffix(Op1, Name, NameBuffer);
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
Value *Callee = M->getOrInsertFunction(Name, Op1->getType(),
Op1->getType(), Op2->getType(), NULL);
CallInst *CI = B.CreateCall2(Callee, Op1, Op2, Name);
CI->setAttributes(Attrs);
- if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
return CI;
}
@@ -349,7 +474,8 @@ Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
if (!TLI->has(LibFunc::putchar))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
Value *PutChar = M->getOrInsertFunction("putchar", B.getInt32Ty(),
B.getInt32Ty(), NULL);
CallInst *CI = B.CreateCall(PutChar,
@@ -359,8 +485,19 @@ Value *llvm::EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
"chari"),
"putchar");
- if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(PutChar->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
@@ -371,7 +508,8 @@ Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
if (!TLI->has(LibFunc::puts))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[2];
AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
@@ -383,8 +521,19 @@ Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
B.getInt8PtrTy(),
NULL);
CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
- if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
- CI->setCallingConv(F->getCallingConv());
+ if (Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) {
+ CallingConv::ID CC = F->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ F->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
@@ -395,7 +544,8 @@ Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
if (!TLI->has(LibFunc::fputc))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[2];
AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex,
@@ -416,8 +566,19 @@ Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
"chari");
CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
- if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
- CI->setCallingConv(Fn->getCallingConv());
+ if (Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) {
+ CallingConv::ID CC = Fn->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ Fn->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
@@ -428,7 +589,8 @@ Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
if (!TLI->has(LibFunc::fputs))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[3];
AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture);
@@ -448,8 +610,19 @@ Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
File->getType(), NULL);
CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
- if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
- CI->setCallingConv(Fn->getCallingConv());
+ if (Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) {
+ CallingConv::ID CC = Fn->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ Fn->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
@@ -461,7 +634,8 @@ Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
if (!TLI->has(LibFunc::fwrite))
return 0;
- Module *M = B.GetInsertBlock()->getParent()->getParent();
+ Function *CallerF = B.GetInsertBlock()->getParent();
+ Module *M = CallerF->getParent();
AttributeSet AS[3];
AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture);
AS[1] = AttributeSet::get(M->getContext(), 4, Attribute::NoCapture);
@@ -487,8 +661,19 @@ Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
ConstantInt::get(TD->getIntPtrType(Context), 1), File);
- if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
- CI->setCallingConv(Fn->getCallingConv());
+ if (Function *Fn = dyn_cast<Function>(F->stripPointerCasts())) {
+ CallingConv::ID CC = Fn->getCallingConv();
+ CallingConv::ID CallerCC = CallerF->getCallingConv();
+ if (CC == CallingConv::C && CallingConv::isARMTargetCC(CallerCC)) {
+ // If caller is using ARM target specific CC such as AAPCS-VFP,
+ // make sure the call uses it or it would introduce a calling
+ // convention mismatch.
+ CI->setCallingConv(CallerCC);
+ Fn->setCallingConv(CallerCC);
+ } else
+ CI->setCallingConv(CC);
+ }
+
return CI;
}
OpenPOWER on IntegriCloud