1
0
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:
Xin Tong 2018-11-26 22:03:52 +00:00
parent 4b10f1cd41
commit 6c209212a2
2 changed files with 59 additions and 2 deletions

View File

@ -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();
}

View File

@ -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}