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