Simplify test for sret attribute in instcombine

This change is correct because the verifier requires that at most one
argument be marked 'sret'.

NFC, removes a use of AttributeList slot APIs.

llvm-svn: 300784
This commit is contained in:
Reid Kleckner 2017-04-19 23:17:47 +00:00
parent 2cc97d92ce
commit aa0cec7d6d
3 changed files with 35 additions and 27 deletions

View File

@ -4068,21 +4068,15 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
}
if (FT->getNumParams() < NumActualArgs && FT->isVarArg() &&
!CallerPAL.isEmpty())
!CallerPAL.isEmpty()) {
// In this case we have more arguments than the new function type, but we
// won't be dropping them. Check that these extra arguments have attributes
// that are compatible with being a vararg call argument.
for (unsigned i = CallerPAL.getNumSlots(); i; --i) {
unsigned Index = CallerPAL.getSlotIndex(i - 1);
if (Index <= FT->getNumParams())
break;
// Check if it has an attribute that's incompatible with varargs.
AttributeList PAttrs = CallerPAL.getSlotAttributes(i - 1);
if (PAttrs.hasAttribute(Index, Attribute::StructRet))
return false;
}
unsigned SRetIdx;
if (CallerPAL.hasAttrSomewhere(Attribute::StructRet, &SRetIdx) &&
SRetIdx > FT->getNumParams())
return false;
}
// Okay, we decided that this is a safe thing to do: go ahead and start
// inserting cast instructions as necessary.

View File

@ -1,15 +0,0 @@
; RUN: opt < %s -instcombine -S | grep bitcast | count 2
define signext i32 @b(i32* inreg %x) {
ret i32 0
}
define void @c(...) {
ret void
}
define void @g(i32* %y) {
call i32 bitcast (i32 (i32*)* @b to i32 (i32)*)( i32 zeroext 0 ) ; <i32>:2 [#uses=0]
call void bitcast (void (...)* @c to void (i32*)*)( i32* sret null )
ret void
}

View File

@ -0,0 +1,29 @@
; RUN: opt < %s -instcombine -S | FileCheck %s
define signext i32 @b(i32* inreg %x) {
ret i32 0
}
define void @c(...) {
ret void
}
declare void @useit(i32)
define void @d(i32 %x, ...) {
call void @useit(i32 %x)
ret void
}
define void @g(i32* %y) {
call i32 bitcast (i32 (i32*)* @b to i32 (i32)*)(i32 zeroext 0)
call void bitcast (void (...)* @c to void (i32*)*)(i32* %y)
call void bitcast (void (...)* @c to void (i32*)*)(i32* sret %y)
call void bitcast (void (i32, ...)* @d to void (i32, i32*)*)(i32 0, i32* sret %y)
ret void
}
; CHECK-LABEL: define void @g(i32* %y)
; CHECK: call i32 bitcast (i32 (i32*)* @b to i32 (i32)*)(i32 zeroext 0)
; CHECK: call void (...) @c(i32* %y)
; CHECK: call void bitcast (void (...)* @c to void (i32*)*)(i32* sret %y)
; CHECK: call void bitcast (void (i32, ...)* @d to void (i32, i32*)*)(i32 0, i32* sret %y)