Skip to content

Commit 274981e

Browse files
committed
[bugpoint][PR29027] Reduce function attributes
Summary: In addition to reducing the functions in an LLVM module, bugpoint now reduces the function attributes associated with each of the remaining functions. To test this, add a -bugpoint-crashfuncattr test pass, which crashes if a function in the module has a "bugpoint-crash" attribute. A test case demonstrates that the IR is reduced to just that one attribute. Reviewers: MatzeB, silvas, davide, reames Reviewed By: reames Subscribers: reames, llvm-commits Differential Revision: https://reviews.llvm.org/D55216 llvm-svn: 349601
1 parent 0b83209 commit 274981e

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashfuncattr -silence-passes
2+
; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
3+
; REQUIRES: loadable_module
4+
5+
; CHECK: f() #[[ATTRS:[0-9]+]]
6+
define void @f() #0 {
7+
ret void
8+
}
9+
10+
; CHECK: attributes #[[ATTRS]] = { "bugpoint-crash"="sure" }
11+
attributes #0 = { "bugpoint-crash"="sure" noreturn "no-frame-pointer-elim-non-leaf" }

llvm/test/BugPoint/func-attrs.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashfuncattr -silence-passes
2+
; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
3+
; REQUIRES: loadable_module
4+
5+
; CHECK: f() #[[ATTRS:[0-9]+]]
6+
define void @f() #0 {
7+
ret void
8+
}
9+
10+
; CHECK: attributes #[[ATTRS]] = { "bugpoint-crash" }
11+
attributes #0 = { noinline "bugpoint-crash" "no-frame-pointer-elim-non-leaf" }

llvm/tools/bugpoint-passes/TestPasses.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,28 @@ char CrashOnTooManyCUs::ID = 0;
123123
static RegisterPass<CrashOnTooManyCUs>
124124
A("bugpoint-crash-too-many-cus",
125125
"BugPoint Test Pass - Intentionally crash on too many CUs");
126+
127+
namespace {
128+
class CrashOnFunctionAttribute : public FunctionPass {
129+
public:
130+
static char ID; // Pass ID, replacement for typeid
131+
CrashOnFunctionAttribute() : FunctionPass(ID) {}
132+
133+
private:
134+
void getAnalysisUsage(AnalysisUsage &AU) const override {
135+
AU.setPreservesAll();
136+
}
137+
138+
bool runOnFunction(Function &F) override {
139+
AttributeSet A = F.getAttributes().getFnAttributes();
140+
if (A.hasAttribute("bugpoint-crash"))
141+
abort();
142+
return false;
143+
}
144+
};
145+
} // namespace
146+
147+
char CrashOnFunctionAttribute::ID = 0;
148+
static RegisterPass<CrashOnFunctionAttribute>
149+
B("bugpoint-crashfuncattr", "BugPoint Test Pass - Intentionally crash on "
150+
"function attribute 'bugpoint-crash'");

llvm/tools/bugpoint/CrashDebugger.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,66 @@ bool ReduceCrashingFunctions::TestFuncs(std::vector<Function *> &Funcs) {
314314
return false;
315315
}
316316

317+
namespace {
318+
/// ReduceCrashingFunctionAttributes reducer - This works by removing
319+
/// attributes on a particular function and seeing if the program still crashes.
320+
/// If it does, then keep the newer, smaller program.
321+
///
322+
class ReduceCrashingFunctionAttributes : public ListReducer<Attribute> {
323+
BugDriver &BD;
324+
std::string FnName;
325+
BugTester TestFn;
326+
327+
public:
328+
ReduceCrashingFunctionAttributes(BugDriver &bd, const std::string &FnName,
329+
BugTester testFn)
330+
: BD(bd), FnName(FnName), TestFn(testFn) {}
331+
332+
Expected<TestResult> doTest(std::vector<Attribute> &Prefix,
333+
std::vector<Attribute> &Kept) override {
334+
if (!Kept.empty() && TestFuncAttrs(Kept))
335+
return KeepSuffix;
336+
if (!Prefix.empty() && TestFuncAttrs(Prefix))
337+
return KeepPrefix;
338+
return NoFailure;
339+
}
340+
341+
bool TestFuncAttrs(std::vector<Attribute> &Attrs);
342+
};
343+
}
344+
345+
bool ReduceCrashingFunctionAttributes::TestFuncAttrs(
346+
std::vector<Attribute> &Attrs) {
347+
// Clone the program to try hacking it apart...
348+
std::unique_ptr<Module> M = CloneModule(BD.getProgram());
349+
Function *F = M->getFunction(FnName);
350+
351+
// Build up an AttributeList from the attributes we've been given by the
352+
// reducer.
353+
AttrBuilder AB;
354+
for (auto A : Attrs)
355+
AB.addAttribute(A);
356+
AttributeList NewAttrs;
357+
NewAttrs =
358+
NewAttrs.addAttributes(BD.getContext(), AttributeList::FunctionIndex, AB);
359+
360+
// Set this new list of attributes on the function.
361+
F->setAttributes(NewAttrs);
362+
363+
// Try running on the hacked up program...
364+
if (TestFn(BD, M.get())) {
365+
BD.setNewProgram(std::move(M)); // It crashed, keep the trimmed version...
366+
367+
// Pass along the set of attributes that caused the crash.
368+
Attrs.clear();
369+
for (Attribute A : NewAttrs.getFnAttributes()) {
370+
Attrs.push_back(A);
371+
}
372+
return true;
373+
}
374+
return false;
375+
}
376+
317377
namespace {
318378
/// Simplify the CFG without completely destroying it.
319379
/// This is not well defined, but basically comes down to "try to eliminate
@@ -1056,6 +1116,38 @@ static Error DebugACrash(BugDriver &BD, BugTester TestFn) {
10561116
BD.EmitProgressBitcode(BD.getProgram(), "reduced-function");
10571117
}
10581118

1119+
// For each remaining function, try to reduce that function's attributes.
1120+
std::vector<std::string> FunctionNames;
1121+
for (Function &F : BD.getProgram())
1122+
FunctionNames.push_back(F.getName());
1123+
1124+
if (!FunctionNames.empty() && !BugpointIsInterrupted) {
1125+
outs() << "\n*** Attempting to reduce the number of function attributes in "
1126+
"the testcase\n";
1127+
1128+
unsigned OldSize = 0;
1129+
unsigned NewSize = 0;
1130+
for (std::string &Name : FunctionNames) {
1131+
Function *Fn = BD.getProgram().getFunction(Name);
1132+
assert(Fn && "Could not find funcion?");
1133+
1134+
std::vector<Attribute> Attrs;
1135+
for (Attribute A : Fn->getAttributes().getFnAttributes())
1136+
Attrs.push_back(A);
1137+
1138+
OldSize += Attrs.size();
1139+
Expected<bool> Result =
1140+
ReduceCrashingFunctionAttributes(BD, Name, TestFn).reduceList(Attrs);
1141+
if (Error E = Result.takeError())
1142+
return E;
1143+
1144+
NewSize += Attrs.size();
1145+
}
1146+
1147+
if (OldSize < NewSize)
1148+
BD.EmitProgressBitcode(BD.getProgram(), "reduced-function-attributes");
1149+
}
1150+
10591151
// Attempt to change conditional branches into unconditional branches to
10601152
// eliminate blocks.
10611153
if (!DisableSimplifyCFG && !BugpointIsInterrupted) {

0 commit comments

Comments
 (0)