Skip to content

Commit 9660563

Browse files
committed
[llvm-reduce] Add reduction passes to reduce operands to undef/1/0
Having non-undef constants in a final llvm-reduce output is nicer than having undefs. This splits the existing reduce-operands pass into three, one which does the same as the current pass of reducing to undef, and two more to reduce to the constant 1 and the constant 0. Do not reduce to undef if the operand is a ConstantData, and do not reduce 0s to 1s. Reducing GEP operands very frequently causes invalid IR (since types may not match up if we index differently into a struct), so don't touch GEPs. Reviewed By: Meinersbur Differential Revision: https://reviews.llvm.org/D111765
1 parent 922bf57 commit 9660563

File tree

5 files changed

+120
-54
lines changed

5 files changed

+120
-54
lines changed

llvm/test/tools/llvm-reduce/remove-invoked-functions.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
define i32 @maybe_throwing_callee(i32 %arg) {
77
; CHECK-ALL: call void @thrown()
88
; CHECK-INTERESTINGNESS: ret i32
9-
; CHECK-FINAL: ret i32 undef
9+
; CHECK-FINAL: ret i32 0
1010
call void @thrown()
1111
ret i32 %arg
1212
}
Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,52 @@
1-
; Test that llvm-reduce can reduce operands to their default values.
1+
; Test that llvm-reduce can reduce operands
22
;
3-
; RUN: llvm-reduce --delta-passes=operands --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
4-
; RUN: cat %t | FileCheck %s
3+
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=operands-undef --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
4+
; RUN: cat %t | FileCheck %s --check-prefixes=CHECK,UNDEF
5+
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=operands-one --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
6+
; RUN: cat %t | FileCheck %s --check-prefixes=CHECK,ONE
7+
; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=operands-zero --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
8+
; RUN: cat %t | FileCheck %s --check-prefixes=CHECK,ZERO
9+
; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
10+
; RUN: cat %t | FileCheck %s --check-prefixes=CHECK,ZERO
511

12+
; CHECK-INTERESTINGNESS: inttoptr
13+
; CHECK-INTERESTINGNESS: inttoptr
14+
; CHECK-INTERESTINGNESS: inttoptr
15+
; CHECK-INTERESTINGNESS: inttoptr
16+
; CHECK-INTERESTINGNESS: br label
617
; CHECK-INTERESTINGNESS: ret i32
718

8-
; CHECK-LABEL: define i32 @main() {
9-
define i32 @main() {
19+
%t = type { i32, i8 }
20+
21+
; CHECK-LABEL: define i32 @main
22+
define i32 @main(%t* %a, i32 %a2) {
1023

1124
; CHECK-LABEL: lb1:
12-
; CHECK-NEXT: br label %lb2
25+
; UNDEF: inttoptr i16 0
26+
; UNDEF: inttoptr i16 1
27+
; UNDEF: inttoptr i16 2
28+
; UNDEF: inttoptr i16 undef
29+
; ONE: inttoptr i16 0
30+
; ONE: inttoptr i16 1
31+
; ONE: inttoptr i16 1
32+
; ONE: inttoptr i16 1
33+
; ZERO: inttoptr i16 0
34+
; ZERO: inttoptr i16 0
35+
; ZERO: inttoptr i16 0
36+
; ZERO: inttoptr i16 0
37+
; CHECK: br label %lb2
1338
lb1:
39+
%b = getelementptr %t, %t* %a, i32 1, i32 0
40+
%i1 = inttoptr i16 0 to i8*
41+
%i2 = inttoptr i16 1 to i8*
42+
%i3 = inttoptr i16 2 to i8*
43+
%i4 = inttoptr i16 undef to i8*
1444
br label %lb2
1545

1646
; CHECK-LABEL: lb2:
17-
; CHECK-NEXT: ret i32 undef
47+
; UNDEF: ret i32 undef
48+
; ONE: ret i32 1
49+
; ZERO: ret i32 0
1850
lb2:
19-
ret i32 10
51+
ret i32 %a2
2052
}

llvm/tools/llvm-reduce/DeltaManager.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ static cl::opt<std::string>
5151
DELTA_PASS("metadata", reduceMetadataDeltaPass) \
5252
DELTA_PASS("arguments", reduceArgumentsDeltaPass) \
5353
DELTA_PASS("instructions", reduceInstructionsDeltaPass) \
54-
DELTA_PASS("operands", reduceOperandsDeltaPass) \
54+
DELTA_PASS("operands-zero", reduceOperandsZeroDeltaPass) \
55+
DELTA_PASS("operands-one", reduceOperandsOneDeltaPass) \
56+
DELTA_PASS("operands-undef", reduceOperandsUndefDeltaPass) \
5557
DELTA_PASS("operands-to-args", reduceOperandsToArgsDeltaPass) \
5658
DELTA_PASS("operand-bundles", reduceOperandBundesDeltaPass) \
5759
DELTA_PASS("attributes", reduceAttributesDeltaPass) \
Lines changed: 72 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,105 @@
1-
//===- ReduceOperands.cpp - Specialized Delta Pass ------------------------===//
1+
//===----------------------------------------------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
//
9-
// This file implements a function to reduce operands to undef.
10-
//
11-
//===----------------------------------------------------------------------===//
128

139
#include "ReduceOperands.h"
1410
#include "llvm/IR/Constants.h"
1511
#include "llvm/IR/InstIterator.h"
12+
#include "llvm/IR/Operator.h"
13+
#include "llvm/IR/Type.h"
1614

1715
using namespace llvm;
1816

19-
/// Returns if the given operand is undef.
20-
static bool operandIsUndefValue(Use &Op) {
21-
if (auto *C = dyn_cast<Constant>(Op)) {
22-
return isa<UndefValue>(C);
23-
}
24-
return false;
25-
}
26-
27-
/// Returns if an operand can be reduced to undef.
28-
/// TODO: make this logic check what types are reducible rather than
29-
/// check what types that are not reducible.
30-
static bool canReduceOperand(Use &Op) {
31-
auto *Ty = Op->getType();
32-
// Can't reduce labels to undef
33-
return !Ty->isLabelTy() && !operandIsUndefValue(Op);
34-
}
35-
36-
/// Sets Operands to undef.
37-
static void extractOperandsFromModule(Oracle &O, Module &Program) {
38-
// Extract Operands from the module.
17+
static void
18+
extractOperandsFromModule(Oracle &O, Module &Program,
19+
function_ref<Value *(Use &)> ReduceValue) {
3920
for (auto &F : Program.functions()) {
4021
for (auto &I : instructions(&F)) {
4122
for (auto &Op : I.operands()) {
42-
// Filter Operands then set to undef.
43-
if (canReduceOperand(Op) && !O.shouldKeep()) {
44-
auto *Ty = Op->getType();
45-
Op.set(UndefValue::get(Ty));
46-
}
23+
Value *Reduced = ReduceValue(Op);
24+
if (Reduced && !O.shouldKeep())
25+
Op.set(Reduced);
4726
}
4827
}
4928
}
5029
}
5130

52-
/// Counts the amount of operands in the module that can be reduced.
53-
static int countOperands(Module &Program) {
31+
static int countOperands(Module &Program,
32+
function_ref<Value *(Use &)> ReduceValue) {
5433
int Count = 0;
5534
for (auto &F : Program.functions()) {
5635
for (auto &I : instructions(&F)) {
5736
for (auto &Op : I.operands()) {
58-
if (canReduceOperand(Op)) {
37+
if (ReduceValue(Op))
5938
Count++;
60-
}
6139
}
6240
}
6341
}
6442
return Count;
6543
}
6644

67-
void llvm::reduceOperandsDeltaPass(TestRunner &Test) {
68-
errs() << "*** Reducing Operands...\n";
69-
int Count = countOperands(Test.getProgram());
70-
runDeltaPass(Test, Count, extractOperandsFromModule);
45+
static bool isOne(Use &Op) {
46+
auto *C = dyn_cast<Constant>(Op);
47+
return C && C->isOneValue();
48+
}
49+
50+
static bool isZero(Use &Op) {
51+
auto *C = dyn_cast<Constant>(Op);
52+
return C && C->isNullValue();
53+
}
54+
55+
void llvm::reduceOperandsUndefDeltaPass(TestRunner &Test) {
56+
errs() << "*** Reducing Operands to undef...\n";
57+
auto ReduceValue = [](Use &Op) -> Value * {
58+
if (isa<GEPOperator>(Op.getUser()))
59+
return nullptr;
60+
if (Op->getType()->isLabelTy())
61+
return nullptr;
62+
// Don't replace existing ConstantData Uses.
63+
return isa<ConstantData>(*Op) ? nullptr : UndefValue::get(Op->getType());
64+
};
65+
int Count = countOperands(Test.getProgram(), ReduceValue);
66+
runDeltaPass(Test, Count, [ReduceValue](Oracle &O, Module &Program) {
67+
extractOperandsFromModule(O, Program, ReduceValue);
68+
});
69+
}
70+
71+
void llvm::reduceOperandsOneDeltaPass(TestRunner &Test) {
72+
errs() << "*** Reducing Operands to one...\n";
73+
auto ReduceValue = [](Use &Op) -> Value * {
74+
// TODO: support floats
75+
if (isa<GEPOperator>(Op.getUser()))
76+
return nullptr;
77+
auto *Ty = dyn_cast<IntegerType>(Op->getType());
78+
if (!Ty)
79+
return nullptr;
80+
// Don't replace existing ones and zeroes.
81+
return (isOne(Op) || isZero(Op)) ? nullptr : ConstantInt::get(Ty, 1);
82+
};
83+
int Count = countOperands(Test.getProgram(), ReduceValue);
84+
runDeltaPass(Test, Count, [ReduceValue](Oracle &O, Module &Program) {
85+
extractOperandsFromModule(O, Program, ReduceValue);
86+
});
87+
}
88+
89+
void llvm::reduceOperandsZeroDeltaPass(TestRunner &Test) {
90+
errs() << "*** Reducing Operands to zero...\n";
91+
auto ReduceValue = [](Use &Op) -> Value * {
92+
// TODO: be more precise about which GEP operands we can reduce (e.g. array
93+
// indexes)
94+
if (isa<GEPOperator>(Op.getUser()))
95+
return nullptr;
96+
if (Op->getType()->isLabelTy())
97+
return nullptr;
98+
// Don't replace existing zeroes.
99+
return isZero(Op) ? nullptr : Constant::getNullValue(Op->getType());
100+
};
101+
int Count = countOperands(Test.getProgram(), ReduceValue);
102+
runDeltaPass(Test, Count, [ReduceValue](Oracle &O, Module &Program) {
103+
extractOperandsFromModule(O, Program, ReduceValue);
104+
});
71105
}
Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
1-
//===- ReduceOperands.h - Specialized Delta Pass --------------------------===//
1+
//===----------------------------------------------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
//
9-
// This file implements a function to reduce operands to undef.
10-
//
11-
//===----------------------------------------------------------------------===//
128

139
#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEOPERANDS_H
1410
#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEOPERANDS_H
1511

1612
#include "Delta.h"
1713

1814
namespace llvm {
19-
void reduceOperandsDeltaPass(TestRunner &Test);
15+
void reduceOperandsUndefDeltaPass(TestRunner &Test);
16+
void reduceOperandsOneDeltaPass(TestRunner &Test);
17+
void reduceOperandsZeroDeltaPass(TestRunner &Test);
2018
} // namespace llvm
2119

2220
#endif

0 commit comments

Comments
 (0)