Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / IR / ModuleTest.cpp
blobc18301d5e6d7580ac523af703dcb82f43f23b11c
1 //===- unittests/IR/ModuleTest.cpp - Module unit tests --------------------===//
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/Module.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Constants.h"
12 #include "llvm/IR/GlobalVariable.h"
13 #include "llvm/IR/ModuleSummaryIndex.h"
14 #include "llvm/Pass.h"
15 #include "llvm/Support/RandomNumberGenerator.h"
16 #include "llvm/Support/SourceMgr.h"
17 #include "gtest/gtest.h"
19 #include <random>
21 using namespace llvm;
23 namespace {
25 bool sortByName(const GlobalVariable &L, const GlobalVariable &R) {
26 return L.getName() < R.getName();
29 bool sortByNameReverse(const GlobalVariable &L, const GlobalVariable &R) {
30 return sortByName(R, L);
33 TEST(ModuleTest, sortGlobalsByName) {
34 LLVMContext Context;
35 for (auto compare : {&sortByName, &sortByNameReverse}) {
36 Module M("M", Context);
37 Type *T = Type::getInt8Ty(Context);
38 GlobalValue::LinkageTypes L = GlobalValue::ExternalLinkage;
39 (void)new GlobalVariable(M, T, false, L, nullptr, "A");
40 (void)new GlobalVariable(M, T, false, L, nullptr, "F");
41 (void)new GlobalVariable(M, T, false, L, nullptr, "G");
42 (void)new GlobalVariable(M, T, false, L, nullptr, "E");
43 (void)new GlobalVariable(M, T, false, L, nullptr, "B");
44 (void)new GlobalVariable(M, T, false, L, nullptr, "H");
45 (void)new GlobalVariable(M, T, false, L, nullptr, "C");
46 (void)new GlobalVariable(M, T, false, L, nullptr, "D");
48 // Sort the globals by name.
49 EXPECT_FALSE(std::is_sorted(M.global_begin(), M.global_end(), compare));
53 TEST(ModuleTest, randomNumberGenerator) {
54 LLVMContext Context;
55 static char ID;
56 struct DummyPass : ModulePass {
57 DummyPass() : ModulePass(ID) {}
58 bool runOnModule(Module &) override { return true; }
59 } DP;
61 Module M("R", Context);
63 std::uniform_int_distribution<int> dist;
64 const size_t NBCheck = 10;
66 std::array<int, NBCheck> RandomStreams[2];
67 for (auto &RandomStream : RandomStreams) {
68 std::unique_ptr<RandomNumberGenerator> RNG = M.createRNG(DP.getPassName());
69 std::generate(RandomStream.begin(), RandomStream.end(),
70 [&]() { return dist(*RNG); });
73 EXPECT_TRUE(std::equal(RandomStreams[0].begin(), RandomStreams[0].end(),
74 RandomStreams[1].begin()));
77 TEST(ModuleTest, setModuleFlag) {
78 LLVMContext Context;
79 Module M("M", Context);
80 StringRef Key = "Key";
81 Metadata *Val1 = MDString::get(Context, "Val1");
82 Metadata *Val2 = MDString::get(Context, "Val2");
83 EXPECT_EQ(nullptr, M.getModuleFlag(Key));
84 M.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val1);
85 EXPECT_EQ(Val1, M.getModuleFlag(Key));
86 M.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val2);
87 EXPECT_EQ(Val2, M.getModuleFlag(Key));
90 TEST(ModuleTest, setModuleFlagInt) {
91 LLVMContext Context;
92 Module M("M", Context);
93 StringRef Key = "Key";
94 uint32_t Val1 = 1;
95 uint32_t Val2 = 2;
96 EXPECT_EQ(nullptr, M.getModuleFlag(Key));
97 M.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val1);
98 auto A1 = mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(Key));
99 EXPECT_EQ(Val1, A1->getZExtValue());
100 M.setModuleFlag(Module::ModFlagBehavior::Error, Key, Val2);
101 auto A2 = mdconst::extract_or_null<ConstantInt>(M.getModuleFlag(Key));
102 EXPECT_EQ(Val2, A2->getZExtValue());
105 const char *IRString = R"IR(
106 !llvm.module.flags = !{!0}
108 !0 = !{i32 1, !"ProfileSummary", !1}
109 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9}
110 !2 = !{!"ProfileFormat", !"SampleProfile"}
111 !3 = !{!"TotalCount", i64 10000}
112 !4 = !{!"MaxCount", i64 10}
113 !5 = !{!"MaxInternalCount", i64 1}
114 !6 = !{!"MaxFunctionCount", i64 1000}
115 !7 = !{!"NumCounts", i64 200}
116 !8 = !{!"NumFunctions", i64 3}
117 !9 = !{!"DetailedSummary", !10}
118 !10 = !{!11, !12, !13}
119 !11 = !{i32 10000, i64 1000, i32 1}
120 !12 = !{i32 990000, i64 300, i32 10}
121 !13 = !{i32 999999, i64 5, i32 100}
122 )IR";
124 TEST(ModuleTest, setProfileSummary) {
125 SMDiagnostic Err;
126 LLVMContext Context;
127 std::unique_ptr<Module> M = parseAssemblyString(IRString, Err, Context);
128 auto *PS = ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false));
129 EXPECT_NE(nullptr, PS);
130 EXPECT_FALSE(PS->isPartialProfile());
131 PS->setPartialProfile(true);
132 M->setProfileSummary(PS->getMD(Context), ProfileSummary::PSK_Sample);
133 delete PS;
134 PS = ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false));
135 EXPECT_NE(nullptr, PS);
136 EXPECT_EQ(true, PS->isPartialProfile());
137 delete PS;
140 TEST(ModuleTest, setPartialSampleProfileRatio) {
141 const char *IRString = R"IR(
142 !llvm.module.flags = !{!0}
144 !0 = !{i32 1, !"ProfileSummary", !1}
145 !1 = !{!2, !3, !4, !5, !6, !7, !8, !9, !10, !11}
146 !2 = !{!"ProfileFormat", !"SampleProfile"}
147 !3 = !{!"TotalCount", i64 10000}
148 !4 = !{!"MaxCount", i64 10}
149 !5 = !{!"MaxInternalCount", i64 1}
150 !6 = !{!"MaxFunctionCount", i64 1000}
151 !7 = !{!"NumCounts", i64 200}
152 !8 = !{!"NumFunctions", i64 3}
153 !9 = !{!"IsPartialProfile", i64 1}
154 !10 = !{!"PartialProfileRatio", double 0.0}
155 !11 = !{!"DetailedSummary", !12}
156 !12 = !{!13, !14, !15}
157 !13 = !{i32 10000, i64 1000, i32 1}
158 !14 = !{i32 990000, i64 300, i32 10}
159 !15 = !{i32 999999, i64 5, i32 100}
160 )IR";
162 SMDiagnostic Err;
163 LLVMContext Context;
164 std::unique_ptr<Module> M = parseAssemblyString(IRString, Err, Context);
165 ModuleSummaryIndex Index(/*HaveGVs*/ false);
166 const unsigned BlockCount = 100;
167 const unsigned NumCounts = 200;
168 Index.setBlockCount(BlockCount);
169 M->setPartialSampleProfileRatio(Index);
170 double Ratio = (double)BlockCount / NumCounts;
171 std::unique_ptr<ProfileSummary> ProfileSummary(
172 ProfileSummary::getFromMD(M->getProfileSummary(/*IsCS*/ false)));
173 EXPECT_EQ(Ratio, ProfileSummary->getPartialProfileRatio());
176 TEST(ModuleTest, AliasList) {
177 // This tests all Module's functions that interact with Module::AliasList.
178 LLVMContext C;
179 SMDiagnostic Err;
180 LLVMContext Context;
181 std::unique_ptr<Module> M = parseAssemblyString(R"(
182 declare void @Foo()
183 @GA = alias void (), ptr @Foo
185 Err, Context);
186 Function *Foo = M->getFunction("Foo");
187 auto *GA = M->getNamedAlias("GA");
188 EXPECT_EQ(M->alias_size(), 1u);
189 auto *NewGA =
190 GlobalAlias::create(Foo->getType(), 0, GlobalValue::ExternalLinkage,
191 "NewGA", Foo, /*Parent=*/nullptr);
192 EXPECT_EQ(M->alias_size(), 1u);
194 M->insertAlias(NewGA);
195 EXPECT_EQ(&*std::prev(M->aliases().end()), NewGA);
197 M->removeAlias(NewGA);
198 EXPECT_EQ(M->alias_size(), 1u);
199 M->insertAlias(NewGA);
200 EXPECT_EQ(M->alias_size(), 2u);
201 EXPECT_EQ(&*std::prev(M->aliases().end()), NewGA);
203 auto Range = M->aliases();
204 EXPECT_EQ(&*Range.begin(), GA);
205 EXPECT_EQ(&*std::next(Range.begin()), NewGA);
206 EXPECT_EQ(std::next(Range.begin(), 2), Range.end());
208 M->removeAlias(NewGA);
209 EXPECT_EQ(M->alias_size(), 1u);
211 M->insertAlias(NewGA);
212 M->eraseAlias(NewGA);
213 EXPECT_EQ(M->alias_size(), 1u);
216 TEST(ModuleTest, IFuncList) {
217 // This tests all Module's functions that interact with Module::IFuncList.
218 LLVMContext C;
219 SMDiagnostic Err;
220 LLVMContext Context;
221 std::unique_ptr<Module> M = parseAssemblyString(R"(
222 declare void @Foo()
223 @GIF = ifunc void (), ptr @Foo
225 Err, Context);
226 Function *Foo = M->getFunction("Foo");
227 auto *GIF = M->getNamedIFunc("GIF");
228 EXPECT_EQ(M->ifunc_size(), 1u);
229 auto *NewGIF =
230 GlobalIFunc::create(Foo->getType(), 0, GlobalValue::ExternalLinkage,
231 "NewGIF", Foo, /*Parent=*/nullptr);
232 EXPECT_EQ(M->ifunc_size(), 1u);
234 M->insertIFunc(NewGIF);
235 EXPECT_EQ(&*std::prev(M->ifuncs().end()), NewGIF);
237 M->removeIFunc(NewGIF);
238 EXPECT_EQ(M->ifunc_size(), 1u);
239 M->insertIFunc(NewGIF);
240 EXPECT_EQ(M->ifunc_size(), 2u);
241 EXPECT_EQ(&*std::prev(M->ifuncs().end()), NewGIF);
243 auto Range = M->ifuncs();
244 EXPECT_EQ(&*Range.begin(), GIF);
245 EXPECT_EQ(&*std::next(Range.begin()), NewGIF);
246 EXPECT_EQ(std::next(Range.begin(), 2), Range.end());
248 M->removeIFunc(NewGIF);
249 EXPECT_EQ(M->ifunc_size(), 1u);
251 M->insertIFunc(NewGIF);
252 M->eraseIFunc(NewGIF);
253 EXPECT_EQ(M->ifunc_size(), 1u);
256 TEST(ModuleTest, NamedMDList) {
257 // This tests all Module's functions that interact with Module::NamedMDList.
258 LLVMContext C;
259 SMDiagnostic Err;
260 LLVMContext Context;
261 auto M = std::make_unique<Module>("M", C);
262 NamedMDNode *MDN1 = M->getOrInsertNamedMetadata("MDN1");
263 EXPECT_EQ(M->named_metadata_size(), 1u);
264 NamedMDNode *MDN2 = M->getOrInsertNamedMetadata("MDN2");
265 EXPECT_EQ(M->named_metadata_size(), 2u);
266 auto *NewMDN = M->getOrInsertNamedMetadata("NewMDN");
267 EXPECT_EQ(M->named_metadata_size(), 3u);
269 M->removeNamedMDNode(NewMDN);
270 EXPECT_EQ(M->named_metadata_size(), 2u);
272 M->insertNamedMDNode(NewMDN);
273 EXPECT_EQ(&*std::prev(M->named_metadata().end()), NewMDN);
275 M->removeNamedMDNode(NewMDN);
276 M->insertNamedMDNode(NewMDN);
277 EXPECT_EQ(M->named_metadata_size(), 3u);
278 EXPECT_EQ(&*std::prev(M->named_metadata().end()), NewMDN);
280 auto Range = M->named_metadata();
281 EXPECT_EQ(&*Range.begin(), MDN1);
282 EXPECT_EQ(&*std::next(Range.begin(), 1), MDN2);
283 EXPECT_EQ(&*std::next(Range.begin(), 2), NewMDN);
284 EXPECT_EQ(std::next(Range.begin(), 3), Range.end());
286 M->eraseNamedMDNode(NewMDN);
287 EXPECT_EQ(M->named_metadata_size(), 2u);
290 TEST(ModuleTest, GlobalList) {
291 // This tests all Module's functions that interact with Module::GlobalList.
292 LLVMContext C;
293 SMDiagnostic Err;
294 LLVMContext Context;
295 std::unique_ptr<Module> M = parseAssemblyString(R"(
296 @GV = external global i32
298 Err, Context);
299 auto *GV = cast<GlobalVariable>(M->getNamedValue("GV"));
300 EXPECT_EQ(M->global_size(), 1u);
301 GlobalVariable *NewGV = new GlobalVariable(
302 Type::getInt32Ty(C), /*isConstant=*/true, GlobalValue::InternalLinkage,
303 /*Initializer=*/nullptr, "NewGV");
304 EXPECT_EQ(M->global_size(), 1u);
305 // Insert before
306 M->insertGlobalVariable(M->globals().begin(), NewGV);
307 EXPECT_EQ(M->global_size(), 2u);
308 EXPECT_EQ(&*M->globals().begin(), NewGV);
309 // Insert at end()
310 M->removeGlobalVariable(NewGV);
311 EXPECT_EQ(M->global_size(), 1u);
312 M->insertGlobalVariable(NewGV);
313 EXPECT_EQ(M->global_size(), 2u);
314 EXPECT_EQ(&*std::prev(M->globals().end()), NewGV);
315 // Check globals()
316 auto Range = M->globals();
317 EXPECT_EQ(&*Range.begin(), GV);
318 EXPECT_EQ(&*std::next(Range.begin()), NewGV);
319 EXPECT_EQ(std::next(Range.begin(), 2), Range.end());
320 // Check remove
321 M->removeGlobalVariable(NewGV);
322 EXPECT_EQ(M->global_size(), 1u);
323 // Check erase
324 M->insertGlobalVariable(NewGV);
325 M->eraseGlobalVariable(NewGV);
326 EXPECT_EQ(M->global_size(), 1u);
329 } // end namespace