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