mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 07:06:38 +00:00
llvm-reduce: Fix losing callsite attributes when removing arguments (#133407)
The attribute APIs make this cumbersome. There seem to be missing overloads using AttrBuilder for the function attrs. Plus there doesn't seem to be a direct way to set the function attrs on the call.
This commit is contained in:
parent
ea8573aca5
commit
1b86867ab3
@ -20,7 +20,7 @@ declare x86_intrcc void @extern_decl(ptr byval(i32), i32, i32)
|
||||
|
||||
; INTERESTING-LABEL: void @callsite(
|
||||
; INTERESTING: call
|
||||
; REDUCED: call x86_intrcc void @func(ptr %k, i32 %other.keep)
|
||||
; REDUCED: call x86_intrcc void @func(ptr byval(i32) %k, i32 %other.keep)
|
||||
define void @callsite(ptr %k, i32 %other.keep, i32 %other.drop) {
|
||||
call x86_intrcc void @func(ptr byval(i32) %k, i32 %other.keep, i32 %other.drop)
|
||||
ret void
|
||||
|
@ -0,0 +1,55 @@
|
||||
; Check that when removing arguments, existing callsite attributes are preserved
|
||||
|
||||
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=arguments --test FileCheck --test-arg --check-prefixes=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
|
||||
; RUN: FileCheck --check-prefixes=RESULT %s < %t
|
||||
|
||||
; INTERESTING-LABEL: define void @callee0(
|
||||
define void @callee0(ptr %interesting0, ptr %interesting1, i32 %uninteresting2) {
|
||||
ret void
|
||||
}
|
||||
|
||||
; INTERESTING-LABEL: define void @callee1(
|
||||
define void @callee1(ptr byval(i64) %interesting0, ptr %interesting1, i32 %uninteresting2) {
|
||||
ret void
|
||||
}
|
||||
|
||||
; INTERESTING-LABEL: define void @caller0(
|
||||
|
||||
; INTERESTING: byval
|
||||
; INTERESTING-SAME: "some-attr"
|
||||
|
||||
; INTERESTING: byval
|
||||
; INTERESTING-SAME: "more-attr"
|
||||
|
||||
; RESULT-LABEL: define void @caller0(ptr %val0) {
|
||||
; RESULT: call void @callee0(ptr byval(i32) %val0, ptr "some-attr" %alloca0) #0
|
||||
; RESULT: call void @callee1(ptr byval(i64) %alloca1, ptr "more-attr" %alloca1) #1
|
||||
define void @caller0(ptr %val0, i32 %val1) {
|
||||
%alloca0 = alloca i32
|
||||
%alloca1 = alloca i64
|
||||
call void @callee0(ptr byval(i32) %val0, ptr "some-attr" %alloca0, i32 %val1) nounwind memory(none) "a-func-attr"
|
||||
call void @callee1(ptr byval(i64) %alloca1, ptr "more-attr" %alloca1, i32 9) "val-func-attr="="something"
|
||||
ret void
|
||||
}
|
||||
|
||||
; RESULT-LABEL: define ptr @callee2() {
|
||||
; RESULT-NEXT: ret ptr null
|
||||
define ptr @callee2(ptr %val0, i32 %b) {
|
||||
store i32 %b, ptr %val0
|
||||
ret ptr %val0
|
||||
}
|
||||
|
||||
; Make sure ret attributes are preserved
|
||||
; INTERESTING: define ptr @caller1(
|
||||
; INTERESTING: call
|
||||
|
||||
; RESULT-LABEL: define ptr @caller1() {
|
||||
; RESULT: %ret = call align 4 "ret-attr" ptr @callee2()
|
||||
|
||||
define ptr @caller1(ptr %val0, i32 %val1) {
|
||||
%ret = call align 4 "ret-attr" ptr @callee2(ptr %val0, i32 %val1)
|
||||
ret ptr %ret
|
||||
}
|
||||
|
||||
; RESULT: attributes #0 = { nounwind memory(none) "a-func-attr" }
|
||||
; RESULT: attributes #1 = { "val-func-attr="="something" }
|
@ -39,6 +39,8 @@ static bool callingConvRequiresArgument(const Function &F,
|
||||
/// Goes over OldF calls and replaces them with a call to NewF
|
||||
static void replaceFunctionCalls(Function &OldF, Function &NewF,
|
||||
const std::set<int> &ArgIndexesToKeep) {
|
||||
LLVMContext &Ctx = OldF.getContext();
|
||||
|
||||
const auto &Users = OldF.users();
|
||||
for (auto I = Users.begin(), E = Users.end(); I != E; )
|
||||
if (auto *CI = dyn_cast<CallInst>(*I++)) {
|
||||
@ -47,12 +49,30 @@ static void replaceFunctionCalls(Function &OldF, Function &NewF,
|
||||
if (CI->getCalledFunction() != &OldF)
|
||||
continue;
|
||||
SmallVector<Value *, 8> Args;
|
||||
for (auto ArgI = CI->arg_begin(), E = CI->arg_end(); ArgI != E; ++ArgI)
|
||||
if (ArgIndexesToKeep.count(ArgI - CI->arg_begin()))
|
||||
Args.push_back(*ArgI);
|
||||
SmallVector<AttrBuilder, 8> ArgAttrs;
|
||||
|
||||
for (auto ArgI = CI->arg_begin(), E = CI->arg_end(); ArgI != E; ++ArgI) {
|
||||
unsigned ArgIdx = ArgI - CI->arg_begin();
|
||||
if (ArgIndexesToKeep.count(ArgIdx)) {
|
||||
Args.push_back(*ArgI);
|
||||
ArgAttrs.emplace_back(Ctx, CI->getParamAttributes(ArgIdx));
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Losing bundles, fast math flags and metadata
|
||||
CallInst *NewCI = CallInst::Create(&NewF, Args);
|
||||
NewCI->setCallingConv(NewF.getCallingConv());
|
||||
|
||||
AttrBuilder CallSiteAttrs(Ctx, CI->getAttributes().getFnAttrs());
|
||||
NewCI->setAttributes(
|
||||
AttributeList::get(Ctx, AttributeList::FunctionIndex, CallSiteAttrs));
|
||||
NewCI->addRetAttrs(AttrBuilder(Ctx, CI->getRetAttributes()));
|
||||
|
||||
unsigned AttrIdx = 0;
|
||||
for (auto ArgI = NewCI->arg_begin(), E = NewCI->arg_end(); ArgI != E;
|
||||
++ArgI, ++AttrIdx)
|
||||
NewCI->addParamAttrs(AttrIdx, ArgAttrs[AttrIdx]);
|
||||
|
||||
if (!CI->use_empty())
|
||||
CI->replaceAllUsesWith(NewCI);
|
||||
ReplaceInstWithInst(CI, NewCI);
|
||||
|
Loading…
x
Reference in New Issue
Block a user