summaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/MergeFunctions.cpp
diff options
context:
space:
mode:
authorStepan Dyatkovskiy <stpworld@narod.ru>2013-09-17 09:36:11 +0000
committerStepan Dyatkovskiy <stpworld@narod.ru>2013-09-17 09:36:11 +0000
commit80361492ae7ea9fedbb5a55c72d4aea6a3d600b1 (patch)
tree05554a6991b6f0fb1d15df004d0ee5b282392dc1 /lib/Transforms/IPO/MergeFunctions.cpp
parent8e5fae2b1bee2b7a944360b91df0d223d06b7927 (diff)
downloadllvm-80361492ae7ea9fedbb5a55c72d4aea6a3d600b1.tar.gz
llvm-80361492ae7ea9fedbb5a55c72d4aea6a3d600b1.tar.bz2
llvm-80361492ae7ea9fedbb5a55c72d4aea6a3d600b1.tar.xz
Bugfix for PR17099:
Wrong cast operation. MergeFunctions emits Bitcast instead of pointer-to-integer operation. Patch fixes MergeFunctions::writeThunk function. It replaces unconditional Bitcast creation with "Value* createCast(...)" method, that checks operand types and selects proper instruction. See unit-test as example. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190859 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/MergeFunctions.cpp')
-rw-r--r--lib/Transforms/IPO/MergeFunctions.cpp23
1 files changed, 15 insertions, 8 deletions
diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp
index 4ce749cfec..0f09b9026e 100644
--- a/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/lib/Transforms/IPO/MergeFunctions.cpp
@@ -713,6 +713,19 @@ void MergeFunctions::writeThunkOrAlias(Function *F, Function *G) {
writeThunk(F, G);
}
+// Helper for writeThunk,
+// Selects proper bitcast operation,
+// but a bit simplier then CastInst::getCastOpcode.
+static Value* createCast(IRBuilder<false> &Builder, Value *V, Type *DestTy) {
+ Type *SrcTy = V->getType();
+ if (SrcTy->isIntegerTy() && DestTy->isPointerTy())
+ return Builder.CreateIntToPtr(V, DestTy);
+ else if (SrcTy->isPointerTy() && DestTy->isIntegerTy())
+ return Builder.CreatePtrToInt(V, DestTy);
+ else
+ return Builder.CreateBitCast(V, DestTy);
+}
+
// Replace G with a simple tail call to bitcast(F). Also replace direct uses
// of G with bitcast(F). Deletes G.
void MergeFunctions::writeThunk(Function *F, Function *G) {
@@ -738,7 +751,7 @@ void MergeFunctions::writeThunk(Function *F, Function *G) {
FunctionType *FFTy = F->getFunctionType();
for (Function::arg_iterator AI = NewG->arg_begin(), AE = NewG->arg_end();
AI != AE; ++AI) {
- Args.push_back(Builder.CreateBitCast(AI, FFTy->getParamType(i)));
+ Args.push_back(createCast(Builder, (Value*)AI, FFTy->getParamType(i)));
++i;
}
@@ -748,13 +761,7 @@ void MergeFunctions::writeThunk(Function *F, Function *G) {
if (NewG->getReturnType()->isVoidTy()) {
Builder.CreateRetVoid();
} else {
- Type *RetTy = NewG->getReturnType();
- if (CI->getType()->isIntegerTy() && RetTy->isPointerTy())
- Builder.CreateRet(Builder.CreateIntToPtr(CI, RetTy));
- else if (CI->getType()->isPointerTy() && RetTy->isIntegerTy())
- Builder.CreateRet(Builder.CreatePtrToInt(CI, RetTy));
- else
- Builder.CreateRet(Builder.CreateBitCast(CI, RetTy));
+ Builder.CreateRet(createCast(Builder, CI, NewG->getReturnType()));
}
NewG->copyAttributesFrom(G);