| //===- FunctionComparator.cpp - Unit tests for FunctionComparator ---------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #include "llvm/Transforms/Utils/FunctionComparator.h" |
| #include "llvm/IR/BasicBlock.h" |
| #include "llvm/IR/IRBuilder.h" |
| #include "llvm/IR/Instructions.h" |
| #include "llvm/IR/LLVMContext.h" |
| #include "llvm/IR/Module.h" |
| #include "gtest/gtest.h" |
| |
| using namespace llvm; |
| |
| /// Generates a simple test function. |
| struct TestFunction { |
| Function *F; |
| BasicBlock *BB; |
| Constant *C; |
| Instruction *I; |
| Type *T; |
| |
| TestFunction(LLVMContext &Ctx, Module &M, int addVal) { |
| IRBuilder<> B(Ctx); |
| T = B.getInt8Ty(); |
| F = Function::Create(FunctionType::get(T, {B.getInt8PtrTy()}, false), |
| GlobalValue::ExternalLinkage, "F", &M); |
| BB = BasicBlock::Create(Ctx, "", F); |
| B.SetInsertPoint(BB); |
| Argument *PointerArg = &*F->arg_begin(); |
| LoadInst *LoadInst = B.CreateLoad(PointerArg); |
| C = B.getInt8(addVal); |
| I = cast<Instruction>(B.CreateAdd(LoadInst, C)); |
| B.CreateRet(I); |
| } |
| }; |
| |
| /// A class for testing the FunctionComparator API. |
| /// |
| /// The main purpose is to test if the required protected functions are |
| /// accessible from a derived class of FunctionComparator. |
| class TestComparator : public FunctionComparator { |
| public: |
| TestComparator(const Function *F1, const Function *F2, |
| GlobalNumberState *GN) |
| : FunctionComparator(F1, F2, GN) { |
| } |
| |
| bool testFunctionAccess(const Function *F1, const Function *F2) { |
| // Test if FnL and FnR are accessible. |
| return F1 == FnL && F2 == FnR; |
| } |
| |
| int testCompare() { |
| return compare(); |
| } |
| |
| int testCompareSignature() { |
| beginCompare(); |
| return compareSignature(); |
| } |
| |
| int testCmpBasicBlocks(BasicBlock *BBL, BasicBlock *BBR) { |
| beginCompare(); |
| return cmpBasicBlocks(BBL, BBR); |
| } |
| |
| int testCmpConstants(const Constant *L, const Constant *R) { |
| beginCompare(); |
| return cmpConstants(L, R); |
| } |
| |
| int testCmpGlobalValues(GlobalValue *L, GlobalValue *R) { |
| beginCompare(); |
| return cmpGlobalValues(L, R); |
| } |
| |
| int testCmpValues(const Value *L, const Value *R) { |
| beginCompare(); |
| return cmpValues(L, R); |
| } |
| |
| int testCmpOperations(const Instruction *L, const Instruction *R, |
| bool &needToCmpOperands) { |
| beginCompare(); |
| return cmpOperations(L, R, needToCmpOperands); |
| } |
| |
| int testCmpTypes(Type *TyL, Type *TyR) { |
| beginCompare(); |
| return cmpTypes(TyL, TyR); |
| } |
| |
| int testCmpPrimitives() { |
| beginCompare(); |
| return |
| cmpNumbers(2, 3) + |
| cmpAPInts(APInt(32, 2), APInt(32, 3)) + |
| cmpAPFloats(APFloat(2.0), APFloat(3.0)) + |
| cmpMem("2", "3"); |
| } |
| }; |
| |
| /// A sanity check for the FunctionComparator API. |
| TEST(FunctionComparatorTest, TestAPI) { |
| LLVMContext C; |
| Module M("test", C); |
| TestFunction F1(C, M, 27); |
| TestFunction F2(C, M, 28); |
| |
| GlobalNumberState GN; |
| TestComparator Cmp(F1.F, F2.F, &GN); |
| |
| EXPECT_TRUE(Cmp.testFunctionAccess(F1.F, F2.F)); |
| EXPECT_EQ(Cmp.testCompare(), -1); |
| EXPECT_EQ(Cmp.testCompareSignature(), 0); |
| EXPECT_EQ(Cmp.testCmpBasicBlocks(F1.BB, F2.BB), -1); |
| EXPECT_EQ(Cmp.testCmpConstants(F1.C, F2.C), -1); |
| EXPECT_EQ(Cmp.testCmpGlobalValues(F1.F, F2.F), -1); |
| EXPECT_EQ(Cmp.testCmpValues(F1.I, F2.I), 0); |
| bool needToCmpOperands = false; |
| EXPECT_EQ(Cmp.testCmpOperations(F1.I, F2.I, needToCmpOperands), 0); |
| EXPECT_TRUE(needToCmpOperands); |
| EXPECT_EQ(Cmp.testCmpTypes(F1.T, F2.T), 0); |
| EXPECT_EQ(Cmp.testCmpPrimitives(), -4); |
| } |