llvm/llvm/tools/bugpoint/Miscompilation.cpp

//===- Miscompilation.cpp - Debug program miscompilations -----------------===//
//
// 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 implements optimizer and code generation miscompilation debugging
// support.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "ListReducer.h"
#include "ToolRunner.h"
#include "llvm/Config/config.h" // for HAVE_LINK_R
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Linker/Linker.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Transforms/Utils/Cloning.h"

usingnamespacellvm;

namespace llvm {
extern cl::opt<std::string> OutputPrefix;
extern cl::list<std::string> InputArgv;
} // end namespace llvm

namespace {
static llvm::cl::opt<bool> DisableLoopExtraction(
    "disable-loop-extraction",
    cl::desc("Don't extract loops when searching for miscompilations"),
    cl::init(false));
static llvm::cl::opt<bool> DisableBlockExtraction(
    "disable-block-extraction",
    cl::desc("Don't extract blocks when searching for miscompilations"),
    cl::init(false));

class ReduceMiscompilingPasses : public ListReducer<std::string> {};
} // end anonymous namespace

/// TestResult - After passes have been split into a test group and a control
/// group, see if they still break the program.
///
Expected<ReduceMiscompilingPasses::TestResult>
ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix,
                                 std::vector<std::string> &Suffix) {}

namespace {
class ReduceMiscompilingFunctions : public ListReducer<Function *> {};
} // end anonymous namespace

/// Given two modules, link them together and run the program, checking to see
/// if the program matches the diff. If there is an error, return NULL. If not,
/// return the merged module. The Broken argument will be set to true if the
/// output is different. If the DeleteInputs argument is set to true then this
/// function deletes both input modules before it returns.
///
static Expected<std::unique_ptr<Module>> testMergedProgram(const BugDriver &BD,
                                                           const Module &M1,
                                                           const Module &M2,
                                                           bool &Broken) {}

/// split functions in a Module into two groups: those that are under
/// consideration for miscompilation vs. those that are not, and test
/// accordingly. Each group of functions becomes a separate Module.
Expected<bool>
ReduceMiscompilingFunctions::TestFuncs(const std::vector<Function *> &Funcs) {}

/// Give anonymous global values names.
static void DisambiguateGlobalSymbols(Module &M) {}

/// Given a reduced list of functions that still exposed the bug, check to see
/// if we can extract the loops in the region without obscuring the bug.  If so,
/// it reduces the amount of code identified.
///
static Expected<bool>
ExtractLoops(BugDriver &BD,
             Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>,
                                      std::unique_ptr<Module>),
             std::vector<Function *> &MiscompiledFunctions) {}

namespace {
class ReduceMiscompiledBlocks : public ListReducer<BasicBlock *> {};
} // end anonymous namespace

/// TestFuncs - Extract all blocks for the miscompiled functions except for the
/// specified blocks.  If the problem still exists, return true.
///
Expected<bool>
ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock *> &BBs) {}

/// Given a reduced list of functions that still expose the bug, extract as many
/// basic blocks from the region as possible without obscuring the bug.
///
static Expected<bool>
ExtractBlocks(BugDriver &BD,
              Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>,
                                       std::unique_ptr<Module>),
              std::vector<Function *> &MiscompiledFunctions) {}

/// This is a generic driver to narrow down miscompilations, either in an
/// optimization or a code generator.
///
static Expected<std::vector<Function *>> DebugAMiscompilation(
    BugDriver &BD,
    Expected<bool> (*TestFn)(BugDriver &, std::unique_ptr<Module>,
                             std::unique_ptr<Module>)) {}

/// This is the predicate function used to check to see if the "Test" portion of
/// the program is misoptimized.  If so, return true.  In any case, both module
/// arguments are deleted.
///
static Expected<bool> TestOptimizer(BugDriver &BD, std::unique_ptr<Module> Test,
                                    std::unique_ptr<Module> Safe) {}

/// debugMiscompilation - This method is used when the passes selected are not
/// crashing, but the generated output is semantically different from the
/// input.
///
Error BugDriver::debugMiscompilation() {}

/// Get the specified modules ready for code generator testing.
///
static std::unique_ptr<Module>
CleanupAndPrepareModules(BugDriver &BD, std::unique_ptr<Module> Test,
                         Module *Safe) {}

/// This is the predicate function used to check to see if the "Test" portion of
/// the program is miscompiled by the code generator under test.  If so, return
/// true.  In any case, both module arguments are deleted.
///
static Expected<bool> TestCodeGenerator(BugDriver &BD,
                                        std::unique_ptr<Module> Test,
                                        std::unique_ptr<Module> Safe) {}

/// debugCodeGenerator - debug errors in LLC, LLI, or CBE.
///
Error BugDriver::debugCodeGenerator() {}