Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / IR / StructuralHashTest.cpp
blob64e66aa5f97a6d00b9ad3c516544886e0dc314f3
1 //===- llvm/unittest/IR/StructuralHashTest.cpp ----------------------------===//
2 //
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
6 //
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"
15 #include <memory>
17 using namespace llvm;
19 namespace {
21 std::unique_ptr<Module> parseIR(LLVMContext &Context, const char *IR) {
22 SMDiagnostic Err;
23 std::unique_ptr<Module> M = parseAssemblyString(IR, Err, Context);
24 if (!M)
25 Err.print("StructuralHashTest", errs());
26 return M;
29 TEST(StructuralHashTest, Empty) {
30 LLVMContext Ctx;
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) {
37 LLVMContext Ctx;
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) {
51 LLVMContext Ctx;
52 std::unique_ptr<Module> M = parseIR(Ctx, "define void @f() {\n"
53 " ret void\n"
54 "}\n"
55 "define void @g() {\n"
56 " ret void\n"
57 "}\n"
58 "define i32 @h(i32 %i) {\n"
59 " ret i32 %i\n"
60 "}\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) {
68 LLVMContext Ctx;
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) {
77 LLVMContext Ctx;
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) {
84 LLVMContext Ctx;
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) {
91 LLVMContext Ctx;
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) {
99 LLVMContext Ctx;
100 std::unique_ptr<Module> M1 = parseIR(Ctx, "define void @f(ptr %p) {\n"
101 " %a = load i32, ptr %p\n"
102 " ret void\n"
103 "}\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"
107 " ret void\n"
108 "}\n");
109 EXPECT_NE(StructuralHash(*M1), StructuralHash(*M2));
112 TEST(StructuralHashTest, InstructionSubType) {
113 LLVMContext Ctx;
114 std::unique_ptr<Module> M1 = parseIR(Ctx, "define void @f(ptr %p) {\n"
115 " %a = load i32, ptr %p\n"
116 " ret void\n"
117 "}\n");
118 std::unique_ptr<Module> M2 = parseIR(Ctx, "define void @f(ptr %p) {\n"
119 " %a = load i64, ptr %p\n"
120 " ret void\n"
121 "}\n");
122 EXPECT_EQ(StructuralHash(*M1), StructuralHash(*M2));
123 EXPECT_NE(StructuralHash(*M1, true), StructuralHash(*M2, true));
126 TEST(StructuralHashTest, InstructionType) {
127 LLVMContext Ctx;
128 std::unique_ptr<Module> M1 = parseIR(Ctx, "define void @f(ptr %p) {\n"
129 " %1 = load i32, ptr %p\n"
130 " ret void\n"
131 "}\n");
132 std::unique_ptr<Module> M2 = parseIR(Ctx, "define void @f(ptr %p) {\n"
133 " %1 = load float, ptr %p\n"
134 " ret void\n"
135 "}\n");
136 EXPECT_EQ(StructuralHash(*M1), StructuralHash(*M2));
137 EXPECT_NE(StructuralHash(*M1, true), StructuralHash(*M2, true));
140 TEST(StructuralHashTest, IgnoredMetadata) {
141 LLVMContext Ctx;
142 std::unique_ptr<Module> M1 = parseIR(Ctx, "@a = global i32 1\n");
143 // clang-format off
144 std::unique_ptr<Module> M2 = parseIR(
145 Ctx, R"(
146 @a = global i32 1
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}
152 !0 = !{}
153 !1 = !{ptr @llvm.embedded.object, !".llvm.lto"}
154 )");
155 // clang-format on
156 EXPECT_EQ(StructuralHash(*M1), StructuralHash(*M2));
159 TEST(StructuralHashTest, ComparisonInstructionPredicate) {
160 LLVMContext Ctx;
161 std::unique_ptr<Module> M1 = parseIR(Ctx, "define i1 @f(i64 %a, i64 %b) {\n"
162 " %1 = icmp eq i64 %a, %b\n"
163 " ret i1 %1\n"
164 "}\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"
167 " ret i1 %1\n"
168 "}\n");
169 EXPECT_EQ(StructuralHash(*M1), StructuralHash(*M2));
170 EXPECT_NE(StructuralHash(*M1, true), StructuralHash(*M2, true));
173 TEST(StructuralHashTest, IntrinsicInstruction) {
174 LLVMContext Ctx;
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"
178 " ret float %b\n"
179 "}\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"
184 " ret float %b\n"
185 "}\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) {
192 LLVMContext Ctx;
193 std::unique_ptr<Module> M1 = parseIR(Ctx, "define i64 @f(i64 %a) {\n"
194 " %b = call i64 @f1(i64 %a)\n"
195 " ret i64 %b\n"
196 "}\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"
200 " ret i64 %b\n"
201 "}\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) {
208 LLVMContext Ctx;
209 std::unique_ptr<Module> M1 = parseIR(Ctx, "define i64 @f1() {\n"
210 " ret i64 1\n"
211 "}\n");
212 std::unique_ptr<Module> M2 = parseIR(Ctx, "define i64 @f2() {\n"
213 " ret i64 2\n"
214 "}\n");
215 EXPECT_EQ(StructuralHash(*M1), StructuralHash(*M2));
216 EXPECT_NE(StructuralHash(*M1, true), StructuralHash(*M2, true));
219 TEST(StructuralHashTest, BigConstantInteger) {
220 LLVMContext Ctx;
221 std::unique_ptr<Module> M1 = parseIR(Ctx, "define i128 @f1() {\n"
222 " ret i128 18446744073709551616\n"
223 "}\n");
224 std::unique_ptr<Module> M2 = parseIR(Ctx, "define i128 @f2() {\n"
225 " ret i128 18446744073709551617\n"
226 "}\n");
227 EXPECT_EQ(StructuralHash(*M1), StructuralHash(*M2));
228 EXPECT_NE(StructuralHash(*M1, true), StructuralHash(*M2, true));
231 TEST(StructuralHashTest, ArgumentNumber) {
232 LLVMContext Ctx;
233 std::unique_ptr<Module> M1 = parseIR(Ctx, "define i64 @f1(i64 %a, i64 %b) {\n"
234 " ret i64 %a\n"
235 "}\n");
236 std::unique_ptr<Module> M2 = parseIR(Ctx, "define i64 @f2(i64 %a, i64 %b) {\n"
237 " ret i64 %b\n"
238 "}\n");
239 EXPECT_EQ(StructuralHash(*M1), StructuralHash(*M2));
240 EXPECT_NE(StructuralHash(*M1, true), StructuralHash(*M2, true));
242 } // end anonymous namespace