1 //===- FunctionComparator.cpp - Unit tests for FunctionComparator ---------===// 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 #include "llvm/Transforms/Utils/FunctionComparator.h" 10 #include "llvm/IR/BasicBlock.h" 11 #include "llvm/IR/IRBuilder.h" 12 #include "llvm/IR/Instructions.h" 13 #include "llvm/IR/LLVMContext.h" 14 #include "llvm/IR/Module.h" 15 #include "gtest/gtest.h" 16 17 using namespace llvm; 18 19 /// Generates a simple test function. 20 struct TestFunction { 21 Function *F; 22 BasicBlock *BB; 23 Constant *C; 24 Instruction *I; 25 Type *T; 26 27 TestFunction(LLVMContext &Ctx, Module &M, int addVal) { 28 IRBuilder<> B(Ctx); 29 T = B.getInt8Ty(); 30 F = Function::Create(FunctionType::get(T, {B.getInt8PtrTy()}, false), 31 GlobalValue::ExternalLinkage, "F", &M); 32 BB = BasicBlock::Create(Ctx, "", F); 33 B.SetInsertPoint(BB); 34 Argument *PointerArg = &*F->arg_begin(); 35 LoadInst *LoadInst = B.CreateLoad(PointerArg); 36 C = B.getInt8(addVal); 37 I = cast<Instruction>(B.CreateAdd(LoadInst, C)); 38 B.CreateRet(I); 39 } 40 }; 41 42 /// A class for testing the FunctionComparator API. 43 /// 44 /// The main purpose is to test if the required protected functions are 45 /// accessible from a derived class of FunctionComparator. 46 class TestComparator : public FunctionComparator { 47 public: 48 TestComparator(const Function *F1, const Function *F2, 49 GlobalNumberState *GN) 50 : FunctionComparator(F1, F2, GN) { 51 } 52 53 bool testFunctionAccess(const Function *F1, const Function *F2) { 54 // Test if FnL and FnR are accessible. 55 return F1 == FnL && F2 == FnR; 56 } 57 58 int testCompare() { 59 return compare(); 60 } 61 62 int testCompareSignature() { 63 beginCompare(); 64 return compareSignature(); 65 } 66 67 int testCmpBasicBlocks(BasicBlock *BBL, BasicBlock *BBR) { 68 beginCompare(); 69 return cmpBasicBlocks(BBL, BBR); 70 } 71 72 int testCmpConstants(const Constant *L, const Constant *R) { 73 beginCompare(); 74 return cmpConstants(L, R); 75 } 76 77 int testCmpGlobalValues(GlobalValue *L, GlobalValue *R) { 78 beginCompare(); 79 return cmpGlobalValues(L, R); 80 } 81 82 int testCmpValues(const Value *L, const Value *R) { 83 beginCompare(); 84 return cmpValues(L, R); 85 } 86 87 int testCmpOperations(const Instruction *L, const Instruction *R, 88 bool &needToCmpOperands) { 89 beginCompare(); 90 return cmpOperations(L, R, needToCmpOperands); 91 } 92 93 int testCmpTypes(Type *TyL, Type *TyR) { 94 beginCompare(); 95 return cmpTypes(TyL, TyR); 96 } 97 98 int testCmpPrimitives() { 99 beginCompare(); 100 return 101 cmpNumbers(2, 3) + 102 cmpAPInts(APInt(32, 2), APInt(32, 3)) + 103 cmpAPFloats(APFloat(2.0), APFloat(3.0)) + 104 cmpMem("2", "3"); 105 } 106 }; 107 108 /// A sanity check for the FunctionComparator API. 109 TEST(FunctionComparatorTest, TestAPI) { 110 LLVMContext C; 111 Module M("test", C); 112 TestFunction F1(C, M, 27); 113 TestFunction F2(C, M, 28); 114 115 GlobalNumberState GN; 116 TestComparator Cmp(F1.F, F2.F, &GN); 117 118 EXPECT_TRUE(Cmp.testFunctionAccess(F1.F, F2.F)); 119 EXPECT_EQ(Cmp.testCompare(), -1); 120 EXPECT_EQ(Cmp.testCompareSignature(), 0); 121 EXPECT_EQ(Cmp.testCmpBasicBlocks(F1.BB, F2.BB), -1); 122 EXPECT_EQ(Cmp.testCmpConstants(F1.C, F2.C), -1); 123 EXPECT_EQ(Cmp.testCmpGlobalValues(F1.F, F2.F), -1); 124 EXPECT_EQ(Cmp.testCmpValues(F1.I, F2.I), 0); 125 bool needToCmpOperands = false; 126 EXPECT_EQ(Cmp.testCmpOperations(F1.I, F2.I, needToCmpOperands), 0); 127 EXPECT_TRUE(needToCmpOperands); 128 EXPECT_EQ(Cmp.testCmpTypes(F1.T, F2.T), 0); 129 EXPECT_EQ(Cmp.testCmpPrimitives(), -4); 130 } 131