1 //===- TestPasses.cpp - "buggy" passes used to test bugpoint --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains "buggy" passes that are used to test bugpoint, to check
11 // that it is narrowing down testcases correctly.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/IR/BasicBlock.h"
16 #include "llvm/IR/Constant.h"
17 #include "llvm/IR/InstVisitor.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/Type.h"
20 #include "llvm/Pass.h"
21 
22 using namespace llvm;
23 
24 namespace {
25   /// CrashOnCalls - This pass is used to test bugpoint.  It intentionally
26   /// crashes on any call instructions.
27   class CrashOnCalls : public BasicBlockPass {
28   public:
29     static char ID; // Pass ID, replacement for typeid
CrashOnCalls()30     CrashOnCalls() : BasicBlockPass(ID) {}
31   private:
getAnalysisUsage(AnalysisUsage & AU) const32     void getAnalysisUsage(AnalysisUsage &AU) const override {
33       AU.setPreservesAll();
34     }
35 
runOnBasicBlock(BasicBlock & BB)36     bool runOnBasicBlock(BasicBlock &BB) override {
37       for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
38         if (isa<CallInst>(*I))
39           abort();
40 
41       return false;
42     }
43   };
44 }
45 
46 char CrashOnCalls::ID = 0;
47 static RegisterPass<CrashOnCalls>
48   X("bugpoint-crashcalls",
49     "BugPoint Test Pass - Intentionally crash on CallInsts");
50 
51 namespace {
52   /// DeleteCalls - This pass is used to test bugpoint.  It intentionally
53   /// deletes some call instructions, "misoptimizing" the program.
54   class DeleteCalls : public BasicBlockPass {
55   public:
56     static char ID; // Pass ID, replacement for typeid
DeleteCalls()57     DeleteCalls() : BasicBlockPass(ID) {}
58   private:
runOnBasicBlock(BasicBlock & BB)59     bool runOnBasicBlock(BasicBlock &BB) override {
60       for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
61         if (CallInst *CI = dyn_cast<CallInst>(I)) {
62           if (!CI->use_empty())
63             CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
64           CI->getParent()->getInstList().erase(CI);
65           break;
66         }
67       return false;
68     }
69   };
70 }
71 
72 char DeleteCalls::ID = 0;
73 static RegisterPass<DeleteCalls>
74   Y("bugpoint-deletecalls",
75     "BugPoint Test Pass - Intentionally 'misoptimize' CallInsts");
76 
77 namespace {
78   /// CrashOnDeclFunc - This pass is used to test bugpoint.  It intentionally
79 /// crashes if the module has an undefined function (ie a function that is
80 /// defined in an external module).
81 class CrashOnDeclFunc : public ModulePass {
82 public:
83   static char ID; // Pass ID, replacement for typeid
CrashOnDeclFunc()84   CrashOnDeclFunc() : ModulePass(ID) {}
85 
86 private:
runOnModule(Module & M)87   bool runOnModule(Module &M) override {
88     for (auto &F : M.functions()) {
89       if (F.isDeclaration())
90         abort();
91     }
92     return false;
93   }
94   };
95 }
96 
97 char CrashOnDeclFunc::ID = 0;
98 static RegisterPass<CrashOnDeclFunc>
99   Z("bugpoint-crash-decl-funcs",
100     "BugPoint Test Pass - Intentionally crash on declared functions");
101 
102 #include <iostream>
103 namespace {
104 /// CrashOnOneCU - This pass is used to test bugpoint. It intentionally
105 /// crashes if the Module has two or more compile units
106 class CrashOnTooManyCUs : public ModulePass {
107 public:
108   static char ID;
CrashOnTooManyCUs()109   CrashOnTooManyCUs() : ModulePass(ID) {}
110 
111 private:
runOnModule(Module & M)112   bool runOnModule(Module &M) override {
113     NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
114     if (!CU_Nodes)
115       return false;
116     if (CU_Nodes->getNumOperands() >= 2)
117       abort();
118     return false;
119   }
120 };
121 }
122 
123 char CrashOnTooManyCUs::ID = 0;
124 static RegisterPass<CrashOnTooManyCUs>
125     A("bugpoint-crash-too-many-cus",
126       "BugPoint Test Pass - Intentionally crash on too many CUs");
127