[llvm] r349601 - [bugpoint][PR29027] Reduce function attributes

Brian Gesiak via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 18 19:42:19 PST 2018


Author: modocache
Date: Tue Dec 18 19:42:19 2018
New Revision: 349601

URL: http://llvm.org/viewvc/llvm-project?rev=349601&view=rev
Log:
[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

Added:
    llvm/trunk/test/BugPoint/func-attrs-keyval.ll
    llvm/trunk/test/BugPoint/func-attrs.ll
Modified:
    llvm/trunk/tools/bugpoint-passes/TestPasses.cpp
    llvm/trunk/tools/bugpoint/CrashDebugger.cpp

Added: llvm/trunk/test/BugPoint/func-attrs-keyval.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/BugPoint/func-attrs-keyval.ll?rev=349601&view=auto
==============================================================================
--- llvm/trunk/test/BugPoint/func-attrs-keyval.ll (added)
+++ llvm/trunk/test/BugPoint/func-attrs-keyval.ll Tue Dec 18 19:42:19 2018
@@ -0,0 +1,11 @@
+; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashfuncattr -silence-passes
+; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
+; REQUIRES: loadable_module
+
+; CHECK: f() #[[ATTRS:[0-9]+]]
+define void @f() #0 {
+  ret void
+}
+
+; CHECK: attributes #[[ATTRS]] = { "bugpoint-crash"="sure" }
+attributes #0 = { "bugpoint-crash"="sure" noreturn "no-frame-pointer-elim-non-leaf" }

Added: llvm/trunk/test/BugPoint/func-attrs.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/BugPoint/func-attrs.ll?rev=349601&view=auto
==============================================================================
--- llvm/trunk/test/BugPoint/func-attrs.ll (added)
+++ llvm/trunk/test/BugPoint/func-attrs.ll Tue Dec 18 19:42:19 2018
@@ -0,0 +1,11 @@
+; RUN: bugpoint -load %llvmshlibdir/BugpointPasses%shlibext %s -output-prefix %t -bugpoint-crashfuncattr -silence-passes
+; RUN: llvm-dis %t-reduced-simplified.bc -o - | FileCheck %s
+; REQUIRES: loadable_module
+
+; CHECK: f() #[[ATTRS:[0-9]+]]
+define void @f() #0 {
+  ret void
+}
+
+; CHECK: attributes #[[ATTRS]] = { "bugpoint-crash" }
+attributes #0 = { noinline "bugpoint-crash" "no-frame-pointer-elim-non-leaf" }

Modified: llvm/trunk/tools/bugpoint-passes/TestPasses.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint-passes/TestPasses.cpp?rev=349601&r1=349600&r2=349601&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint-passes/TestPasses.cpp (original)
+++ llvm/trunk/tools/bugpoint-passes/TestPasses.cpp Tue Dec 18 19:42:19 2018
@@ -123,3 +123,28 @@ char CrashOnTooManyCUs::ID = 0;
 static RegisterPass<CrashOnTooManyCUs>
     A("bugpoint-crash-too-many-cus",
       "BugPoint Test Pass - Intentionally crash on too many CUs");
+
+namespace {
+class CrashOnFunctionAttribute : public FunctionPass {
+public:
+  static char ID; // Pass ID, replacement for typeid
+  CrashOnFunctionAttribute() : FunctionPass(ID) {}
+
+private:
+  void getAnalysisUsage(AnalysisUsage &AU) const override {
+    AU.setPreservesAll();
+  }
+
+  bool runOnFunction(Function &F) override {
+    AttributeSet A = F.getAttributes().getFnAttributes();
+    if (A.hasAttribute("bugpoint-crash"))
+      abort();
+    return false;
+  }
+};
+} // namespace
+
+char CrashOnFunctionAttribute::ID = 0;
+static RegisterPass<CrashOnFunctionAttribute>
+    B("bugpoint-crashfuncattr", "BugPoint Test Pass - Intentionally crash on "
+                                "function attribute 'bugpoint-crash'");

Modified: llvm/trunk/tools/bugpoint/CrashDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/CrashDebugger.cpp?rev=349601&r1=349600&r2=349601&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/CrashDebugger.cpp (original)
+++ llvm/trunk/tools/bugpoint/CrashDebugger.cpp Tue Dec 18 19:42:19 2018
@@ -315,6 +315,66 @@ bool ReduceCrashingFunctions::TestFuncs(
 }
 
 namespace {
+/// ReduceCrashingFunctionAttributes reducer - This works by removing
+/// attributes on a particular function and seeing if the program still crashes.
+/// If it does, then keep the newer, smaller program.
+///
+class ReduceCrashingFunctionAttributes : public ListReducer<Attribute> {
+  BugDriver &BD;
+  std::string FnName;
+  BugTester TestFn;
+
+public:
+  ReduceCrashingFunctionAttributes(BugDriver &bd, const std::string &FnName,
+                                   BugTester testFn)
+      : BD(bd), FnName(FnName), TestFn(testFn) {}
+
+  Expected<TestResult> doTest(std::vector<Attribute> &Prefix,
+                              std::vector<Attribute> &Kept) override {
+    if (!Kept.empty() && TestFuncAttrs(Kept))
+      return KeepSuffix;
+    if (!Prefix.empty() && TestFuncAttrs(Prefix))
+      return KeepPrefix;
+    return NoFailure;
+  }
+
+  bool TestFuncAttrs(std::vector<Attribute> &Attrs);
+};
+}
+
+bool ReduceCrashingFunctionAttributes::TestFuncAttrs(
+    std::vector<Attribute> &Attrs) {
+  // Clone the program to try hacking it apart...
+  std::unique_ptr<Module> M = CloneModule(BD.getProgram());
+  Function *F = M->getFunction(FnName);
+
+  // Build up an AttributeList from the attributes we've been given by the
+  // reducer.
+  AttrBuilder AB;
+  for (auto A : Attrs)
+    AB.addAttribute(A);
+  AttributeList NewAttrs;
+  NewAttrs =
+      NewAttrs.addAttributes(BD.getContext(), AttributeList::FunctionIndex, AB);
+
+  // Set this new list of attributes on the function.
+  F->setAttributes(NewAttrs);
+
+  // Try running on the hacked up program...
+  if (TestFn(BD, M.get())) {
+    BD.setNewProgram(std::move(M)); // It crashed, keep the trimmed version...
+
+    // Pass along the set of attributes that caused the crash.
+    Attrs.clear();
+    for (Attribute A : NewAttrs.getFnAttributes()) {
+      Attrs.push_back(A);
+    }
+    return true;
+  }
+  return false;
+}
+
+namespace {
 /// Simplify the CFG without completely destroying it.
 /// This is not well defined, but basically comes down to "try to eliminate
 /// unreachable blocks and constant fold terminators without deciding that
@@ -1056,6 +1116,38 @@ static Error DebugACrash(BugDriver &BD,
       BD.EmitProgressBitcode(BD.getProgram(), "reduced-function");
   }
 
+  // For each remaining function, try to reduce that function's attributes.
+  std::vector<std::string> FunctionNames;
+  for (Function &F : BD.getProgram())
+    FunctionNames.push_back(F.getName());
+
+  if (!FunctionNames.empty() && !BugpointIsInterrupted) {
+    outs() << "\n*** Attempting to reduce the number of function attributes in "
+              "the testcase\n";
+
+    unsigned OldSize = 0;
+    unsigned NewSize = 0;
+    for (std::string &Name : FunctionNames) {
+      Function *Fn = BD.getProgram().getFunction(Name);
+      assert(Fn && "Could not find funcion?");
+
+      std::vector<Attribute> Attrs;
+      for (Attribute A : Fn->getAttributes().getFnAttributes())
+        Attrs.push_back(A);
+
+      OldSize += Attrs.size();
+      Expected<bool> Result =
+          ReduceCrashingFunctionAttributes(BD, Name, TestFn).reduceList(Attrs);
+      if (Error E = Result.takeError())
+        return E;
+
+      NewSize += Attrs.size();
+    }
+
+    if (OldSize < NewSize)
+      BD.EmitProgressBitcode(BD.getProgram(), "reduced-function-attributes");
+  }
+
   // Attempt to change conditional branches into unconditional branches to
   // eliminate blocks.
   if (!DisableSimplifyCFG && !BugpointIsInterrupted) {




More information about the llvm-commits mailing list