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
22using namespace llvm;
23
24namespace {
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
30    CrashOnCalls() : BasicBlockPass(ID) {}
31  private:
32    void getAnalysisUsage(AnalysisUsage &AU) const override {
33      AU.setPreservesAll();
34    }
35
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
46char CrashOnCalls::ID = 0;
47static RegisterPass<CrashOnCalls>
48  X("bugpoint-crashcalls",
49    "BugPoint Test Pass - Intentionally crash on CallInsts");
50
51namespace {
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
57    DeleteCalls() : BasicBlockPass(ID) {}
58  private:
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
72char DeleteCalls::ID = 0;
73static RegisterPass<DeleteCalls>
74  Y("bugpoint-deletecalls",
75    "BugPoint Test Pass - Intentionally 'misoptimize' CallInsts");
76
77namespace {
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).
81class CrashOnDeclFunc : public ModulePass {
82public:
83  static char ID; // Pass ID, replacement for typeid
84  CrashOnDeclFunc() : ModulePass(ID) {}
85
86private:
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
97char CrashOnDeclFunc::ID = 0;
98static RegisterPass<CrashOnDeclFunc>
99  Z("bugpoint-crash-decl-funcs",
100    "BugPoint Test Pass - Intentionally crash on declared functions");
101
102#include <iostream>
103namespace {
104/// CrashOnOneCU - This pass is used to test bugpoint. It intentionally
105/// crashes if the Module has two or more compile units
106class CrashOnTooManyCUs : public ModulePass {
107public:
108  static char ID;
109  CrashOnTooManyCUs() : ModulePass(ID) {}
110
111private:
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
123char CrashOnTooManyCUs::ID = 0;
124static RegisterPass<CrashOnTooManyCUs>
125    A("bugpoint-crash-too-many-cus",
126      "BugPoint Test Pass - Intentionally crash on too many CUs");
127