Skip to content

Commit a33d789

Browse files
authored
llvm-reduce: Avoid invalid reductions on x86_intrcc (#133396)
If there are arguments, the first one must be byval.
1 parent f7f479b commit a33d789

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
; RUN: llvm-reduce %s -o %t --abort-on-invalid-reduction --delta-passes=arguments --test FileCheck --test-arg %s --test-arg --check-prefix=INTERESTING --test-arg --input-file
2+
; RUN: FileCheck %s --input-file %t --check-prefix=REDUCED
3+
4+
@gv = global i32 0
5+
6+
; INTERESTING-LABEL: void @func(
7+
; INTERESTING-SAME: i32 %other.keep
8+
9+
; REDUCED: define x86_intrcc void @func(ptr byval(i32) %k, i32 %other.keep)
10+
define x86_intrcc void @func(ptr byval(i32) %k, i32 %other.keep, i32 %other.drop) {
11+
store i32 %other.keep, ptr @gv
12+
ret void
13+
}
14+
15+
; INTERESTING-LABEL: void @extern_decl(
16+
; INTERESTING-SAME: i32
17+
18+
; REDUCED: declare x86_intrcc void @extern_decl(ptr byval(i32))
19+
declare x86_intrcc void @extern_decl(ptr byval(i32), i32, i32)
20+
21+
; INTERESTING-LABEL: void @callsite(
22+
; INTERESTING: call
23+
; REDUCED: call x86_intrcc void @func(ptr %k, i32 %other.keep)
24+
define void @callsite(ptr %k, i32 %other.keep, i32 %other.drop) {
25+
call x86_intrcc void @func(ptr byval(i32) %k, i32 %other.keep, i32 %other.drop)
26+
ret void
27+
}
28+
29+
; INTERESTING-LABEL: void @keep_none(
30+
; REDUCED-LABEL: define x86_intrcc void @keep_none()
31+
define x86_intrcc void @keep_none(ptr byval(i32) %k, i32 %other0, float %other1) {
32+
store i32 %other0, ptr @gv
33+
store float %other1, ptr @gv
34+
ret void
35+
}

llvm/tools/llvm-reduce/deltas/ReduceArguments.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@
2323

2424
using namespace llvm;
2525

26+
static bool callingConvRequiresArgument(const Function &F,
27+
const Argument &Arg) {
28+
switch (F.getCallingConv()) {
29+
case CallingConv::X86_INTR:
30+
// If there are any arguments, the first one must by byval.
31+
return Arg.getArgNo() == 0 && F.arg_size() != 1;
32+
default:
33+
return false;
34+
}
35+
36+
llvm_unreachable("covered calling conv switch");
37+
}
38+
2639
/// Goes over OldF calls and replaces them with a call to NewF
2740
static void replaceFunctionCalls(Function &OldF, Function &NewF,
2841
const std::set<int> &ArgIndexesToKeep) {
@@ -60,14 +73,18 @@ static void extractArgumentsFromModule(Oracle &O, ReducerWorkItem &WorkItem) {
6073
Module &Program = WorkItem.getModule();
6174
std::vector<Argument *> InitArgsToKeep;
6275
std::vector<Function *> Funcs;
76+
6377
// Get inside-chunk arguments, as well as their parent function
64-
for (auto &F : Program)
65-
if (shouldRemoveArguments(F)) {
66-
Funcs.push_back(&F);
67-
for (auto &A : F.args())
68-
if (O.shouldKeep())
69-
InitArgsToKeep.push_back(&A);
78+
for (auto &F : Program) {
79+
if (!shouldRemoveArguments(F))
80+
continue;
81+
82+
Funcs.push_back(&F);
83+
for (auto &A : F.args()) {
84+
if (callingConvRequiresArgument(F, A) || O.shouldKeep())
85+
InitArgsToKeep.push_back(&A);
7086
}
87+
}
7188

7289
// We create a vector first, then convert it to a set, so that we don't have
7390
// to pay the cost of rebalancing the set frequently if the order we insert

0 commit comments

Comments
 (0)