Skip to content

Commit 349a15d

Browse files
committed
llvm-reduce: Reduce with early return of arguments
Extend the instruction -> return reduction with one that inserts return of function arguments. Not sure how useful this really is. This has more freedom since we could insert the return anywhere in the function, but this just inserts the return in the entry block.
1 parent d1a9a08 commit 349a15d

File tree

6 files changed

+124
-7
lines changed

6 files changed

+124
-7
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=arguments-to-return --test FileCheck --test-arg --check-prefixes=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
2+
; RUN: FileCheck --check-prefixes=RESULT %s < %t
3+
4+
5+
; INTERESTING-LABEL: @move_entry_block_use_argument_to_return(i32 %arg, ptr %ptr) {
6+
; INTERESTING: %arg
7+
8+
; RESULT-LABEL: define i32 @move_entry_block_use_argument_to_return(
9+
; RESULT-NEXT: ret i32 %arg
10+
; RESULT-NEXT: }
11+
define void @move_entry_block_use_argument_to_return(i32 %arg, ptr %ptr) {
12+
store i32 %arg, ptr %ptr
13+
ret void
14+
}
15+
16+
; INTERESTING-LABEL: @move_entry_block_use_argument_to_return_existing_ret(i32 %arg, ptr %ptr) {
17+
; INTERESTING: %arg
18+
19+
; RESULT-LABEL: define i32 @move_entry_block_use_argument_to_return_existing_ret(
20+
; RESULT-NEXT: ret i32 %arg
21+
; RESULT-NEXT: }
22+
define i32 @move_entry_block_use_argument_to_return_existing_ret(i32 %arg, ptr %ptr) {
23+
store i32 %arg, ptr %ptr
24+
ret i32 0
25+
}
26+
27+
; INTERESTING-LABEL: @move_phi_block_use_argument_to_return(i32 %arg, ptr %ptr0, ptr %ptr1, i1 %cond0, i1 %cond1) {
28+
; INTERESTING: %arg
29+
30+
; RESULT-LABEL: define i32 @move_phi_block_use_argument_to_return(
31+
; RESULT-NEXT: entry:
32+
; RESULT-NEXT: ret i32 %arg
33+
define void @move_phi_block_use_argument_to_return(i32 %arg, ptr %ptr0, ptr %ptr1, i1 %cond0, i1 %cond1) {
34+
entry:
35+
br i1 %cond0, label %bb0, label %bb1
36+
37+
bb0:
38+
%phi = phi i32 [ %arg, %entry ], [ 123, %bb1 ]
39+
store i32 %arg, ptr %ptr0
40+
store i32 %phi, ptr %ptr1
41+
br label %bb1
42+
43+
bb1:
44+
br i1 %cond1, label %bb0, label %bb2
45+
46+
bb2:
47+
ret void
48+
}
49+
50+
; INTERESTING-LABEL: define {{.*}} @keep_second_arg(i32 %arg0, ptr %arg1) {
51+
; INTERESTING: %arg1
52+
53+
; RESULT-LABEL: define ptr @keep_second_arg(
54+
; RESULT-NEXT: ret ptr %arg1
55+
; RESULT-NEXT: }
56+
define void @keep_second_arg(i32 %arg0, ptr %arg1) {
57+
store i32 %arg0, ptr %arg1
58+
ret void
59+
}
60+
61+
; INTERESTING-LABEL: @multi_void_return_arg(i1 %arg0, ptr %arg1, i32 %arg2) {
62+
; INTERESTING: i32 %arg2
63+
64+
; RESULT-LABEL: define i32 @multi_void_return_arg(i1 %arg0, ptr %arg1, i32 %arg2) {
65+
; RESULT-NEXT: entry:
66+
; RESULT-NEXT: ret i32 %arg2
67+
define void @multi_void_return_arg(i1 %arg0, ptr %arg1, i32 %arg2) {
68+
entry:
69+
br i1 %arg0, label %bb0, label %bb1
70+
71+
bb0:
72+
store i32 %arg2, ptr %arg1
73+
ret void
74+
75+
bb1:
76+
ret void
77+
}

llvm/test/tools/llvm-reduce/reduce-values-to-return-nonvoid-noncallee-use.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; Make sure we don't break on non-callee uses of funtions with a
22
; non-void return type.
33

4-
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=values-to-return --test FileCheck --test-arg --check-prefix=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
4+
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=instructions-to-return --test FileCheck --test-arg --check-prefix=INTERESTING --test-arg %s --test-arg --input-file %s -o %t
55
; RUN: FileCheck --check-prefix=RESULT %s < %t
66

77
; INTERESTING-LABEL: @interesting(

llvm/test/tools/llvm-reduce/reduce-values-to-return.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
; Test that llvm-reduce can move intermediate values by inserting
22
; early returns
33
;
4-
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=values-to-return --test FileCheck --test-arg --check-prefixes=CHECK,INTERESTING --test-arg %s --test-arg --input-file %s -o %t
4+
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=instructions-to-return --test FileCheck --test-arg --check-prefixes=CHECK,INTERESTING --test-arg %s --test-arg --input-file %s -o %t
55
; RUN: FileCheck --check-prefixes=CHECK,RESULT %s < %t
66

77
@gv = global i32 0, align 4

llvm/tools/llvm-reduce/DeltaPasses.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ DELTA_PASS_IR("operand-bundles", reduceOperandBundesDeltaPass, "Reducing Operand
4747
DELTA_PASS_IR("attributes", reduceAttributesDeltaPass, "Reducing Attributes")
4848
DELTA_PASS_IR("module-data", reduceModuleDataDeltaPass, "Reducing Module Data")
4949
DELTA_PASS_IR("opcodes", reduceOpcodesDeltaPass, "Reducing Opcodes")
50-
DELTA_PASS_IR("values-to-return", reduceValuesToReturnDeltaPass, "Converting values to function return value")
50+
DELTA_PASS_IR("arguments-to-return", reduceArgumentsToReturnDeltaPass,
51+
"Converting arguments to function return value")
52+
DELTA_PASS_IR("instructions-to-return", reduceInstructionsToReturnDeltaPass,
53+
"Converting instructions to function return value")
5154
DELTA_PASS_IR("volatile", reduceVolatileInstructionsDeltaPass, "Reducing Volatile Instructions")
5255
DELTA_PASS_IR("atomic-ordering", reduceAtomicOrderingDeltaPass, "Reducing Atomic Ordering")
5356
DELTA_PASS_IR("syncscopes", reduceAtomicSyncScopesDeltaPass, "Reducing Atomic Sync Scopes")

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

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ static void rewriteFuncWithReturnType(Function &OldF, Value *NewRetValue) {
4848
FunctionType::get(NewRetTy, OldFuncTy->params(), OldFuncTy->isVarArg());
4949

5050
LLVMContext &Ctx = OldF.getContext();
51-
Instruction *NewRetI = cast<Instruction>(NewRetValue);
52-
BasicBlock *NewRetBlock = NewRetI->getParent();
51+
BasicBlock &EntryBB = OldF.getEntryBlock();
52+
Instruction *NewRetI = dyn_cast<Instruction>(NewRetValue);
53+
BasicBlock *NewRetBlock = NewRetI ? NewRetI->getParent() : &EntryBB;
5354

54-
BasicBlock::iterator NewValIt = NewRetI->getIterator();
55+
BasicBlock::iterator NewValIt =
56+
NewRetI ? NewRetI->getIterator() : EntryBB.end();
5557

5658
// Hack up any return values in other blocks, we can't leave them as ret void.
5759
if (OldFuncTy->getReturnType()->isVoidTy()) {
@@ -226,6 +228,40 @@ static bool tryForwardingInstructionsToReturn(
226228
return false;
227229
}
228230

231+
static bool tryForwardingArgumentsToReturn(
232+
Function &F, Oracle &O,
233+
std::vector<std::pair<Function *, Value *>> &FuncsToReplace) {
234+
235+
Type *RetTy = F.getReturnType();
236+
BasicBlock &EntryBB = F.getEntryBlock();
237+
238+
for (Argument &A : F.args()) {
239+
if (shouldForwardValueToReturn(EntryBB, &A, RetTy) && !O.shouldKeep()) {
240+
FuncsToReplace.emplace_back(&F, &A);
241+
return true;
242+
}
243+
}
244+
245+
return false;
246+
}
247+
248+
void llvm::reduceArgumentsToReturnDeltaPass(Oracle &O,
249+
ReducerWorkItem &WorkItem) {
250+
Module &Program = WorkItem.getModule();
251+
252+
// We're going to chaotically hack on the other users of the function in other
253+
// functions, so we need to collect a worklist of returns to replace.
254+
std::vector<std::pair<Function *, Value *>> FuncsToReplace;
255+
256+
for (Function &F : Program.functions()) {
257+
if (!F.isDeclaration() && canUseNonVoidReturnType(F))
258+
tryForwardingArgumentsToReturn(F, O, FuncsToReplace);
259+
}
260+
261+
for (auto [F, NewRetVal] : FuncsToReplace)
262+
rewriteFuncWithReturnType(*F, NewRetVal);
263+
}
264+
229265
void llvm::reduceInstructionsToReturnDeltaPass(Oracle &O,
230266
ReducerWorkItem &WorkItem) {
231267
Module &Program = WorkItem.getModule();

llvm/tools/llvm-reduce/deltas/ReduceValuesToReturn.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
#include "Delta.h"
1313

1414
namespace llvm {
15-
void reduceValuesToReturnDeltaPass(Oracle &O, ReducerWorkItem &WorkItem);
15+
void reduceArgumentsToReturnDeltaPass(Oracle &O, ReducerWorkItem &WorkItem);
16+
void reduceInstructionsToReturnDeltaPass(Oracle &O, ReducerWorkItem &WorkItem);
1617
} // namespace llvm
1718

1819
#endif

0 commit comments

Comments
 (0)