xref: /llvm-project/llvm/unittests/Transforms/Utils/FunctionComparatorTest.cpp (revision 8267b333ee9aaa7cedc6d8aab6ddf15629d9e255)
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