Skip to content

Commit 2ee2c34

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 dba33af commit 2ee2c34

File tree

4 files changed

+122
-4
lines changed

4 files changed

+122
-4
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/tools/llvm-reduce/DeltaPasses.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ DELTA_PASS_IR("attributes", reduceAttributesDeltaPass, "Reducing Attributes")
4949
DELTA_PASS_IR("target-features-attr", reduceTargetFeaturesAttrDeltaPass, "Reducing target-features")
5050
DELTA_PASS_IR("module-data", reduceModuleDataDeltaPass, "Reducing Module Data")
5151
DELTA_PASS_IR("opcodes", reduceOpcodesDeltaPass, "Reducing Opcodes")
52-
DELTA_PASS_IR("instructions-to-return", reduceInstructionsToReturnDeltaPass, "Early return of instructions")
52+
53+
DELTA_PASS_IR("arguments-to-return", reduceArgumentsToReturnDeltaPass,
54+
"Converting arguments to function return value")
55+
DELTA_PASS_IR("instructions-to-return", reduceInstructionsToReturnDeltaPass,
56+
"Early return of instructions")
5357
DELTA_PASS_IR("volatile", reduceVolatileInstructionsDeltaPass, "Reducing Volatile Instructions")
5458
DELTA_PASS_IR("atomic-ordering", reduceAtomicOrderingDeltaPass, "Reducing Atomic Ordering")
5559
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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "Delta.h"
1313

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

0 commit comments

Comments
 (0)