mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-27 06:08:11 +00:00
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
This commit is contained in:
parent
8e5fae2b1b
commit
80361492ae
@ -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);
|
||||
|
18
test/Transforms/MergeFunc/merge-ptr-and-int.ll
Normal file
18
test/Transforms/MergeFunc/merge-ptr-and-int.ll
Normal file
@ -0,0 +1,18 @@
|
||||
; RUN: opt -S -mergefunc < %s | FileCheck %s
|
||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
|
||||
|
||||
; CHECK-LABEL: f0
|
||||
define void @f0(i64 %p0) {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: f1
|
||||
; CHECK: ptrtoint i64*
|
||||
; CHECK: tail call void @f0(i64
|
||||
|
||||
define void @f1(i64* %p0) {
|
||||
entry:
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user