mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[ICP] Remove incompatible attributes at indirect-call promoted callsites.
Summary: Removing ncompatible attributes at indirect-call promoted callsites, not removing it results in at least a IR verification error. Reviewers: davidxl, xur, mssimpso Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D54913 llvm-svn: 347605
This commit is contained in:
parent
4b10f1cd41
commit
6c209212a2
@ -393,6 +393,13 @@ Instruction *llvm::promoteCall(CallSite CS, Function *Callee,
|
||||
// to the correct type.
|
||||
auto CalleeType = Callee->getFunctionType();
|
||||
auto CalleeParamNum = CalleeType->getNumParams();
|
||||
|
||||
LLVMContext &Ctx = Callee->getContext();
|
||||
const AttributeList &CallerPAL = CS.getAttributes();
|
||||
// The new list of argument attributes.
|
||||
SmallVector<AttributeSet, 4> NewArgAttrs;
|
||||
bool AttributeChanged = false;
|
||||
|
||||
for (unsigned ArgNo = 0; ArgNo < CalleeParamNum; ++ArgNo) {
|
||||
auto *Arg = CS.getArgument(ArgNo);
|
||||
Type *FormalTy = CalleeType->getParamType(ArgNo);
|
||||
@ -401,13 +408,31 @@ Instruction *llvm::promoteCall(CallSite CS, Function *Callee,
|
||||
auto *Cast = CastInst::CreateBitOrPointerCast(Arg, FormalTy, "",
|
||||
CS.getInstruction());
|
||||
CS.setArgument(ArgNo, Cast);
|
||||
}
|
||||
|
||||
// Remove any incompatible attributes for the argument.
|
||||
AttrBuilder ArgAttrs(CallerPAL.getParamAttributes(ArgNo));
|
||||
ArgAttrs.remove(AttributeFuncs::typeIncompatible(FormalTy));
|
||||
NewArgAttrs.push_back(AttributeSet::get(Ctx, ArgAttrs));
|
||||
AttributeChanged = true;
|
||||
} else
|
||||
NewArgAttrs.push_back(CallerPAL.getParamAttributes(ArgNo));
|
||||
}
|
||||
|
||||
// If the return type of the call site doesn't match that of the callee, cast
|
||||
// the returned value to the appropriate type.
|
||||
if (!CallSiteRetTy->isVoidTy() && CallSiteRetTy != CalleeRetTy)
|
||||
// Remove any incompatible return value attribute.
|
||||
AttrBuilder RAttrs(CallerPAL, AttributeList::ReturnIndex);
|
||||
if (!CallSiteRetTy->isVoidTy() && CallSiteRetTy != CalleeRetTy) {
|
||||
createRetBitCast(CS, CallSiteRetTy, RetBitCast);
|
||||
RAttrs.remove(AttributeFuncs::typeIncompatible(CalleeRetTy));
|
||||
AttributeChanged = true;
|
||||
}
|
||||
|
||||
// Set the new callsite attribute.
|
||||
if (AttributeChanged)
|
||||
CS.setAttributes(AttributeList::get(Ctx, CallerPAL.getFnAttributes(),
|
||||
AttributeSet::get(Ctx, RAttrs),
|
||||
NewArgAttrs));
|
||||
|
||||
return CS.getInstruction();
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
; RUN: opt -S -pgo-icall-prom -icp-total-percent-threshold=0 < %s 2>&1 | FileCheck %s
|
||||
|
||||
; Test that CallPromotionUtils will promote calls which require pointer cast
|
||||
; safely, i.e. drop incompatible attributes.
|
||||
|
||||
@foo = common global i8* (i8*)* null, align 8
|
||||
|
||||
; casting to i64 and pointer attribute at callsite dropped.
|
||||
define i64 @func2(i64 %a) {
|
||||
ret i64 undef
|
||||
}
|
||||
|
||||
; no casting needed, attribute at callsite preserved.
|
||||
define i8* @func4(i8* %a) {
|
||||
ret i8* undef
|
||||
}
|
||||
|
||||
define i8* @bar(i8* %arg) {
|
||||
%tmp = load i8* (i8*)*, i8* (i8*)** @foo, align 8
|
||||
|
||||
; Make sure callsite attributes are preserved on arguments and retval.
|
||||
; CHECK: call noalias i8* @func4(i8* nonnull
|
||||
|
||||
; Make sure callsite attributes are dropped on arguments and retval.
|
||||
; CHECK: [[ARG:%[0-9]+]] = ptrtoint i8* %arg to i64
|
||||
; CHECK-NEXT: call i64 @func2(i64 [[ARG]])
|
||||
|
||||
%call = call noalias i8* %tmp(i8* nonnull %arg), !prof !1
|
||||
ret i8* %call
|
||||
}
|
||||
|
||||
!1 = !{!"VP", i32 0, i64 1440, i64 7651369219802541373, i64 1030, i64 -4377547752858689819, i64 410}
|
Loading…
x
Reference in New Issue
Block a user