1 //===- llvm/unittest/IR/StructuralHashTest.cpp ----------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/IR/StructuralHash.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Module.h"
12 #include "llvm/Support/SourceMgr.h"
13 #include "gtest/gtest.h"
21 std::unique_ptr
<Module
> parseIR(LLVMContext
&Context
, const char *IR
) {
23 std::unique_ptr
<Module
> M
= parseAssemblyString(IR
, Err
, Context
);
25 Err
.print("StructuralHashTest", errs());
29 TEST(StructuralHashTest
, Empty
) {
31 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "");
32 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "");
33 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
36 TEST(StructuralHashTest
, Basic
) {
38 std::unique_ptr
<Module
> M0
= parseIR(Ctx
, "");
39 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define void @f() { ret void }");
40 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define void @f() { ret void }");
41 std::unique_ptr
<Module
> M3
= parseIR(Ctx
, "@g = global i32 2");
42 std::unique_ptr
<Module
> M4
= parseIR(Ctx
, "@g = global i32 2");
43 EXPECT_NE(StructuralHash(*M0
), StructuralHash(*M1
));
44 EXPECT_NE(StructuralHash(*M0
), StructuralHash(*M3
));
45 EXPECT_NE(StructuralHash(*M1
), StructuralHash(*M3
));
46 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
47 EXPECT_EQ(StructuralHash(*M3
), StructuralHash(*M4
));
50 TEST(StructuralHashTest
, BasicFunction
) {
52 std::unique_ptr
<Module
> M
= parseIR(Ctx
, "define void @f() {\n"
55 "define void @g() {\n"
58 "define i32 @h(i32 %i) {\n"
61 EXPECT_EQ(StructuralHash(*M
->getFunction("f")),
62 StructuralHash(*M
->getFunction("g")));
63 EXPECT_NE(StructuralHash(*M
->getFunction("f")),
64 StructuralHash(*M
->getFunction("h")));
67 TEST(StructuralHashTest
, Declaration
) {
69 std::unique_ptr
<Module
> M0
= parseIR(Ctx
, "");
70 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "declare void @f()");
71 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "@g = external global i32");
72 EXPECT_EQ(StructuralHash(*M0
), StructuralHash(*M1
));
73 EXPECT_EQ(StructuralHash(*M0
), StructuralHash(*M2
));
76 TEST(StructuralHashTest
, GlobalType
) {
78 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "@g = global i32 1");
79 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "@g = global float 1.0");
80 EXPECT_NE(StructuralHash(*M1
), StructuralHash(*M2
));
83 TEST(StructuralHashTest
, Function
) {
85 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define void @f() { ret void }");
86 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define void @f(i32) { ret void }");
87 EXPECT_NE(StructuralHash(*M1
), StructuralHash(*M2
));
90 TEST(StructuralHashTest
, FunctionRetType
) {
92 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define void @f() { ret void }");
93 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define i32 @f() { ret i32 0 }");
94 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
95 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
98 TEST(StructuralHashTest
, InstructionOpCode
) {
100 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define void @f(ptr %p) {\n"
101 " %a = load i32, ptr %p\n"
104 std::unique_ptr
<Module
> M2
=
105 parseIR(Ctx
, "define void @f(ptr %p) {\n"
106 " %a = getelementptr i8, ptr %p, i32 1\n"
109 EXPECT_NE(StructuralHash(*M1
), StructuralHash(*M2
));
112 TEST(StructuralHashTest
, InstructionSubType
) {
114 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define void @f(ptr %p) {\n"
115 " %a = load i32, ptr %p\n"
118 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define void @f(ptr %p) {\n"
119 " %a = load i64, ptr %p\n"
122 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
123 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
126 TEST(StructuralHashTest
, InstructionType
) {
128 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define void @f(ptr %p) {\n"
129 " %1 = load i32, ptr %p\n"
132 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define void @f(ptr %p) {\n"
133 " %1 = load float, ptr %p\n"
136 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
137 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
140 TEST(StructuralHashTest
, IgnoredMetadata
) {
142 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "@a = global i32 1\n");
144 std::unique_ptr
<Module
> M2
= parseIR(
147 @llvm.embedded.object = private constant [4 x i8] c"BC\C0\
00", section ".llvm
.lto
", align 1, !exclude !0
148 @llvm.compiler.used = appending global [1 x ptr] [ptr @llvm.embedded.object], section "llvm
.metadata
"
150 !llvm.embedded.objects = !{!1}
153 !1 = !{ptr @llvm.embedded.object, !".llvm
.lto
"}
156 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
159 TEST(StructuralHashTest
, ComparisonInstructionPredicate
) {
161 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define i1 @f(i64 %a, i64 %b) {\n"
162 " %1 = icmp eq i64 %a, %b\n"
165 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define i1 @f(i64 %a, i64 %b) {\n"
166 " %1 = icmp ne i64 %a, %b\n"
169 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
170 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
173 TEST(StructuralHashTest
, IntrinsicInstruction
) {
175 std::unique_ptr
<Module
> M1
=
176 parseIR(Ctx
, "define float @f(float %a) {\n"
177 " %b = call float @llvm.sin.f32(float %a)\n"
180 "declare float @llvm.sin.f32(float)\n");
181 std::unique_ptr
<Module
> M2
=
182 parseIR(Ctx
, "define float @f(float %a) {\n"
183 " %b = call float @llvm.cos.f32(float %a)\n"
186 "declare float @llvm.cos.f32(float)\n");
187 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
188 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
191 TEST(StructuralHashTest
, CallInstruction
) {
193 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define i64 @f(i64 %a) {\n"
194 " %b = call i64 @f1(i64 %a)\n"
197 "declare i64 @f1(i64)");
198 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define i64 @f(i64 %a) {\n"
199 " %b = call i64 @f2(i64 %a)\n"
202 "declare i64 @f2(i64)");
203 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
204 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
207 TEST(StructuralHashTest
, ConstantInteger
) {
209 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define i64 @f1() {\n"
212 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define i64 @f2() {\n"
215 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
216 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
219 TEST(StructuralHashTest
, BigConstantInteger
) {
221 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define i128 @f1() {\n"
222 " ret i128 18446744073709551616\n"
224 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define i128 @f2() {\n"
225 " ret i128 18446744073709551617\n"
227 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
228 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
231 TEST(StructuralHashTest
, ArgumentNumber
) {
233 std::unique_ptr
<Module
> M1
= parseIR(Ctx
, "define i64 @f1(i64 %a, i64 %b) {\n"
236 std::unique_ptr
<Module
> M2
= parseIR(Ctx
, "define i64 @f2(i64 %a, i64 %b) {\n"
239 EXPECT_EQ(StructuralHash(*M1
), StructuralHash(*M2
));
240 EXPECT_NE(StructuralHash(*M1
, true), StructuralHash(*M2
, true));
242 } // end anonymous namespace