change instcombine to not turn a call to non-varargs bitcast of

function prototype into a call to a varargs prototype.  We do
allow the xform if we have a definition, but otherwise we don't
want to risk that we're changing the abi in a subtle way.  On
X86-64, for example, varargs require passing stuff in %al.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126363 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2011-02-24 05:10:56 +00:00
parent 7558e2e415
commit 091b1e3c74
3 changed files with 29 additions and 17 deletions

View File

@ -953,10 +953,19 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
if (Callee->isDeclaration() && !isConvertible) return false;
}
if (FT->getNumParams() < NumActualArgs && !FT->isVarArg() &&
Callee->isDeclaration())
return false; // Do not delete arguments unless we have a function body.
if (Callee->isDeclaration()) {
// Do not delete arguments unless we have a function body.
if (FT->getNumParams() < NumActualArgs && !FT->isVarArg())
return false;
// If the callee is just a declaration, don't change the varargsness of the
// call. We don't want to introduce a varargs call where one doesn't
// already exist.
const PointerType *APTy = cast<PointerType>(CS.getCalledValue()->getType());
if (FT->isVarArg()!=cast<FunctionType>(APTy->getElementType())->isVarArg())
return false;
}
if (FT->getNumParams() < NumActualArgs && FT->isVarArg() &&
!CallerPAL.isEmpty())
// In this case we have more arguments than the new function type, but we
@ -970,8 +979,9 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
return false;
}
// Okay, we decided that this is a safe thing to do: go ahead and start
// inserting cast instructions as necessary...
// inserting cast instructions as necessary.
std::vector<Value*> Args;
Args.reserve(NumActualArgs);
SmallVector<AttributeWithIndex, 8> attrVec;

View File

@ -1,12 +0,0 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
declare void @free(i8*)
define void @test(i32* %X) {
call void (...)* bitcast (void (i8*)* @free to void (...)*)( i32* %X ) ; <i32>:1 [#uses=0]
; CHECK: %tmp = bitcast i32* %X to i8*
; CHECK: call void @free(i8* %tmp)
ret void
; CHECK: ret void
}

View File

@ -32,7 +32,7 @@ define i32 @test2(i32 %A) {
; Resolving this should insert a cast from sbyte to int, following the C
; promotion rules.
declare void @test3a(i8, ...)
define void @test3a(i8, ...) {unreachable }
define void @test3(i8 %A, i8 %B) {
call void bitcast (void (i8, ...)* @test3a to void (i8, i8)*)( i8 %A, i8 %B
@ -116,3 +116,17 @@ try.handler: ; preds = %entry
; CHECK: @test8() {
; CHECK-NEXT: invoke void @test8a()
; Don't turn this into a direct call, because test9x is just a prototype and
; doing so will make it varargs.
; rdar://9038601
declare i8* @test9x(i8*, i8*, ...) noredzone
define i8* @test9(i8* %arg, i8* %tmp3) nounwind ssp noredzone {
entry:
%call = call i8* bitcast (i8* (i8*, i8*, ...)* @test9x to i8* (i8*, i8*)*)(i8* %arg, i8* %tmp3) noredzone
ret i8* %call
; CHECK: @test9(
; CHECK: call i8* bitcast
}