brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.3 KiB · aad1377 Raw
188 lines · cpp
1//===- TestPasses.cpp - "buggy" passes used to test bugpoint --------------===//2//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9//10// This file contains "buggy" passes that are used to test bugpoint, to check11// 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/InstIterator.h"18#include "llvm/IR/InstVisitor.h"19#include "llvm/IR/Instructions.h"20#include "llvm/IR/Type.h"21#include "llvm/Pass.h"22 23#include "llvm/IR/PatternMatch.h"24using namespace llvm::PatternMatch;25using namespace llvm;26 27namespace {28/// CrashOnCalls - This pass is used to test bugpoint.  It intentionally29/// crashes on any call instructions.30class CrashOnCalls : public FunctionPass {31public:32  static char ID; // Pass ID, replacement for typeid33  CrashOnCalls() : FunctionPass(ID) {}34 35private:36  void getAnalysisUsage(AnalysisUsage &AU) const override {37    AU.setPreservesAll();38  }39 40  bool runOnFunction(Function &F) override {41    for (auto &BB : F)42      for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)43        if (isa<CallInst>(*I))44          abort();45 46    return false;47  }48};49}50 51char CrashOnCalls::ID = 0;52static RegisterPass<CrashOnCalls>53  X("bugpoint-crashcalls",54    "BugPoint Test Pass - Intentionally crash on CallInsts");55 56namespace {57/// DeleteCalls - This pass is used to test bugpoint.  It intentionally58/// deletes some call instructions, "misoptimizing" the program.59class DeleteCalls : public FunctionPass {60public:61  static char ID; // Pass ID, replacement for typeid62  DeleteCalls() : FunctionPass(ID) {}63 64private:65  bool runOnFunction(Function &F) override {66    for (auto &BB : F)67      for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)68        if (CallInst *CI = dyn_cast<CallInst>(I)) {69          if (!CI->use_empty())70            CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));71          CI->eraseFromParent();72          break;73        }74    return false;75  }76};77}78 79char DeleteCalls::ID = 0;80static RegisterPass<DeleteCalls>81  Y("bugpoint-deletecalls",82    "BugPoint Test Pass - Intentionally 'misoptimize' CallInsts");83 84namespace {85  /// CrashOnDeclFunc - This pass is used to test bugpoint.  It intentionally86/// crashes if the module has an undefined function (ie a function that is87/// defined in an external module).88class CrashOnDeclFunc : public ModulePass {89public:90  static char ID; // Pass ID, replacement for typeid91  CrashOnDeclFunc() : ModulePass(ID) {}92 93private:94  bool runOnModule(Module &M) override {95    for (auto &F : M.functions()) {96      if (F.isDeclaration())97        abort();98    }99    return false;100  }101  };102}103 104char CrashOnDeclFunc::ID = 0;105static RegisterPass<CrashOnDeclFunc>106  Z("bugpoint-crash-decl-funcs",107    "BugPoint Test Pass - Intentionally crash on declared functions");108 109namespace {110/// CrashOnOneCU - This pass is used to test bugpoint. It intentionally111/// crashes if the Module has two or more compile units112class CrashOnTooManyCUs : public ModulePass {113public:114  static char ID;115  CrashOnTooManyCUs() : ModulePass(ID) {}116 117private:118  bool runOnModule(Module &M) override {119    NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");120    if (!CU_Nodes)121      return false;122    if (CU_Nodes->getNumOperands() >= 2)123      abort();124    return false;125  }126};127}128 129char CrashOnTooManyCUs::ID = 0;130static RegisterPass<CrashOnTooManyCUs>131    A("bugpoint-crash-too-many-cus",132      "BugPoint Test Pass - Intentionally crash on too many CUs");133 134namespace {135class CrashOnFunctionAttribute : public FunctionPass {136public:137  static char ID; // Pass ID, replacement for typeid138  CrashOnFunctionAttribute() : FunctionPass(ID) {}139 140private:141  void getAnalysisUsage(AnalysisUsage &AU) const override {142    AU.setPreservesAll();143  }144 145  bool runOnFunction(Function &F) override {146    AttributeSet A = F.getAttributes().getFnAttrs();147    if (A.hasAttribute("bugpoint-crash"))148      abort();149    return false;150  }151};152} // namespace153 154char CrashOnFunctionAttribute::ID = 0;155static RegisterPass<CrashOnFunctionAttribute>156    B("bugpoint-crashfuncattr", "BugPoint Test Pass - Intentionally crash on "157                                "function attribute 'bugpoint-crash'");158 159namespace {160class CrashOnMetadata : public FunctionPass {161public:162  static char ID; // Pass ID, replacement for typeid163  CrashOnMetadata() : FunctionPass(ID) {}164 165private:166  void getAnalysisUsage(AnalysisUsage &AU) const override {167    AU.setPreservesAll();168  }169 170  // Crash on fabs calls with fpmath metdata and an fadd as argument. This171  // ensures the fadd instruction sticks around and we can check that the172  // metadata there is dropped correctly.173  bool runOnFunction(Function &F) override {174    for (Instruction &I : instructions(F))175      if (match(&I, m_FAbs(m_FAdd(m_Value(), m_Value()))) &&176          I.hasMetadata("fpmath"))177        abort();178    return false;179  }180};181} // namespace182 183char CrashOnMetadata::ID = 0;184static RegisterPass<CrashOnMetadata>185    C("bugpoint-crashmetadata",186      "BugPoint Test Pass - Intentionally crash on "187      "fabs calls with fpmath metadata and an fadd as argument");188