1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

InstCombine: correctly change byval type attribute alongside call args.

When the byval attribute has a type, it must match the pointee type of
any parameter; but InstCombine was not updating the attribute when
folding casts of various kinds away.

llvm-svn: 362643
This commit is contained in:
Tim Northover 2019-06-05 20:38:17 +00:00
parent 3ab3deccc7
commit 5e8439beff
2 changed files with 44 additions and 4 deletions

View File

@ -4015,7 +4015,9 @@ static bool isSafeToEliminateVarargsCast(const CallBase &Call,
Type* SrcTy =
cast<PointerType>(CI->getOperand(0)->getType())->getElementType();
Type* DstTy = cast<PointerType>(CI->getType())->getElementType();
Type *DstTy = Call.isByValArgument(ix)
? Call.getParamByValType(ix)
: cast<PointerType>(CI->getType())->getElementType();
if (!SrcTy->isSized() || !DstTy->isSized())
return false;
if (DL.getTypeAllocSize(SrcTy) != DL.getTypeAllocSize(DstTy))
@ -4223,6 +4225,15 @@ Instruction *InstCombiner::visitCallBase(CallBase &Call) {
CastInst *CI = dyn_cast<CastInst>(*I);
if (CI && isSafeToEliminateVarargsCast(Call, DL, CI, ix)) {
*I = CI->getOperand(0);
// Update the byval type to match the argument type.
if (Call.isByValArgument(ix)) {
Call.removeParamAttr(ix, Attribute::ByVal);
Call.addParamAttr(
ix, Attribute::getWithByValType(
Call.getContext(),
CI->getOperand(0)->getType()->getPointerElementType()));
}
Changed = true;
}
}
@ -4353,7 +4364,7 @@ bool InstCombiner::transformConstExprCastCall(CallBase &Call) {
if (!ParamPTy || !ParamPTy->getElementType()->isSized())
return false;
Type *CurElTy = ActTy->getPointerElementType();
Type *CurElTy = Call.getParamByValType(i);
if (DL.getTypeAllocSize(CurElTy) !=
DL.getTypeAllocSize(ParamPTy->getElementType()))
return false;
@ -4407,6 +4418,7 @@ bool InstCombiner::transformConstExprCastCall(CallBase &Call) {
// with the existing attributes. Wipe out any problematic attributes.
RAttrs.remove(AttributeFuncs::typeIncompatible(NewRetTy));
LLVMContext &Ctx = Call.getContext();
AI = Call.arg_begin();
for (unsigned i = 0; i != NumCommonArgs; ++i, ++AI) {
Type *ParamTy = FT->getParamType(i);
@ -4417,7 +4429,12 @@ bool InstCombiner::transformConstExprCastCall(CallBase &Call) {
Args.push_back(NewArg);
// Add any parameter attributes.
ArgAttrs.push_back(CallerPAL.getParamAttributes(i));
if (CallerPAL.hasParamAttribute(i, Attribute::ByVal)) {
AttrBuilder AB(CallerPAL.getParamAttributes(i));
AB.addByValAttr(NewArg->getType()->getPointerElementType());
ArgAttrs.push_back(AttributeSet::get(Ctx, AB));
} else
ArgAttrs.push_back(CallerPAL.getParamAttributes(i));
}
// If the function takes more arguments than the call was taking, add them
@ -4456,7 +4473,6 @@ bool InstCombiner::transformConstExprCastCall(CallBase &Call) {
assert((ArgAttrs.size() == FT->getNumParams() || FT->isVarArg()) &&
"missing argument attributes");
LLVMContext &Ctx = Callee->getContext();
AttributeList NewCallerPAL = AttributeList::get(
Ctx, FnAttrs, AttributeSet::get(Ctx, RAttrs), ArgAttrs);

View File

@ -0,0 +1,24 @@
; RUN: opt -S -instcombine %s | FileCheck %s
declare void @add_byval_callee(double*)
; CHECK-LABEL: define void @add_byval
; CHECK: [[ARG:%.*]] = bitcast i64* %in to double*
; CHECK: call void @add_byval_callee(double* byval(double) [[ARG]])
define void @add_byval(i64* %in) {
%tmp = bitcast void (double*)* @add_byval_callee to void (i64*)*
call void %tmp(i64* byval(i64) %in)
ret void
}
%t2 = type { i8 }
; CHECK-LABEL: define void @vararg_byval
; CHECK: call void (i8, ...) @vararg_callee(i8 undef, i8* byval(i8) %p)
define void @vararg_byval(i8* %p) {
%tmp = bitcast i8* %p to %t2*
call void (i8, ...) @vararg_callee(i8 undef, %t2* byval(%t2) %tmp)
ret void
}
declare void @vararg_callee(i8, ...)