//===- TestPasses.cpp - "buggy" passes used to test bugpoint --------------===//
//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains "buggy" passes that are used to test bugpoint, to check
// that it is narrowing down testcases correctly.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Type.h"
#include "llvm/Pass.h"

#include "llvm/IR/PatternMatch.h"
using namespace llvm::PatternMatch;
using namespace llvm;

namespace {
/// CrashOnCalls - This pass is used to test bugpoint.  It intentionally
/// crashes on any call instructions.
class CrashOnCalls : public FunctionPass {
public:
  static char ID; // Pass ID, replacement for typeid
  CrashOnCalls() : FunctionPass(ID) {}

private:
  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesAll();
  }

  bool runOnFunction(Function &F) override {
    for (auto &BB : F)
      for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
        if (isa<CallInst>(*I))
          abort();

    return false;
  }
};
}

char CrashOnCalls::ID = 0;
static RegisterPass<CrashOnCalls>
  X("bugpoint-crashcalls",
    "BugPoint Test Pass - Intentionally crash on CallInsts");

namespace {
/// DeleteCalls - This pass is used to test bugpoint.  It intentionally
/// deletes some call instructions, "misoptimizing" the program.
class DeleteCalls : public FunctionPass {
public:
  static char ID; // Pass ID, replacement for typeid
  DeleteCalls() : FunctionPass(ID) {}

private:
  bool runOnFunction(Function &F) override {
    for (auto &BB : F)
      for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
        if (CallInst *CI = dyn_cast<CallInst>(I)) {
          if (!CI->use_empty())
            CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
          CI->getParent()->getInstList().erase(CI);
          break;
        }
    return false;
  }
};
}

char DeleteCalls::ID = 0;
static RegisterPass<DeleteCalls>
  Y("bugpoint-deletecalls",
    "BugPoint Test Pass - Intentionally 'misoptimize' CallInsts");

namespace {
  /// CrashOnDeclFunc - This pass is used to test bugpoint.  It intentionally
/// crashes if the module has an undefined function (ie a function that is
/// defined in an external module).
class CrashOnDeclFunc : public ModulePass {
public:
  static char ID; // Pass ID, replacement for typeid
  CrashOnDeclFunc() : ModulePass(ID) {}

private:
  bool runOnModule(Module &M) override {
    for (auto &F : M.functions()) {
      if (F.isDeclaration())
        abort();
    }
    return false;
  }
  };
}

char CrashOnDeclFunc::ID = 0;
static RegisterPass<CrashOnDeclFunc>
  Z("bugpoint-crash-decl-funcs",
    "BugPoint Test Pass - Intentionally crash on declared functions");

namespace {
/// CrashOnOneCU - This pass is used to test bugpoint. It intentionally
/// crashes if the Module has two or more compile units
class CrashOnTooManyCUs : public ModulePass {
public:
  static char ID;
  CrashOnTooManyCUs() : ModulePass(ID) {}

private:
  bool runOnModule(Module &M) override {
    NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
    if (!CU_Nodes)
      return false;
    if (CU_Nodes->getNumOperands() >= 2)
      abort();
    return false;
  }
};
}

char CrashOnTooManyCUs::ID = 0;
static RegisterPass<CrashOnTooManyCUs>
    A("bugpoint-crash-too-many-cus",
      "BugPoint Test Pass - Intentionally crash on too many CUs");

namespace {
class CrashOnFunctionAttribute : public FunctionPass {
public:
  static char ID; // Pass ID, replacement for typeid
  CrashOnFunctionAttribute() : FunctionPass(ID) {}

private:
  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesAll();
  }

  bool runOnFunction(Function &F) override {
    AttributeSet A = F.getAttributes().getFnAttrs();
    if (A.hasAttribute("bugpoint-crash"))
      abort();
    return false;
  }
};
} // namespace

char CrashOnFunctionAttribute::ID = 0;
static RegisterPass<CrashOnFunctionAttribute>
    B("bugpoint-crashfuncattr", "BugPoint Test Pass - Intentionally crash on "
                                "function attribute 'bugpoint-crash'");

namespace {
class CrashOnMetadata : public FunctionPass {
public:
  static char ID; // Pass ID, replacement for typeid
  CrashOnMetadata() : FunctionPass(ID) {}

private:
  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesAll();
  }

  // Crash on fabs calls with fpmath metdata and an fadd as argument. This
  // ensures the fadd instruction sticks around and we can check that the
  // metadata there is dropped correctly.
  bool runOnFunction(Function &F) override {
    for (Instruction &I : instructions(F))
      if (match(&I, m_FAbs(m_FAdd(m_Value(), m_Value()))) &&
          I.hasMetadata("fpmath"))
        abort();
    return false;
  }
};
} // namespace

char CrashOnMetadata::ID = 0;
static RegisterPass<CrashOnMetadata>
    C("bugpoint-crashmetadata",
      "BugPoint Test Pass - Intentionally crash on "
      "fabs calls with fpmath metadata and an fadd as argument");
