Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / unittests / IR / FunctionTest.cpp
blob9aaff3ea33830e8288bd436575eb957275109cb2
1 //===- FunctionTest.cpp - Function 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/Function.h"
10 #include "llvm/AsmParser/Parser.h"
11 #include "llvm/IR/Module.h"
12 #include "llvm/Support/SourceMgr.h"
13 #include "gtest/gtest.h"
14 using namespace llvm;
16 namespace {
18 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
19 SMDiagnostic Err;
20 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
21 if (!Mod)
22 Err.print("InstructionsTests", errs());
23 return Mod;
26 static BasicBlock *getBBWithName(Function *F, StringRef Name) {
27 auto It = find_if(
28 *F, [&Name](const BasicBlock &BB) { return BB.getName() == Name; });
29 assert(It != F->end() && "Not found!");
30 return &*It;
33 TEST(FunctionTest, hasLazyArguments) {
34 LLVMContext C;
36 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
37 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
39 // Functions start out with lazy arguments.
40 std::unique_ptr<Function> F(
41 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
42 EXPECT_TRUE(F->hasLazyArguments());
44 // Checking for empty or size shouldn't force arguments to be instantiated.
45 EXPECT_FALSE(F->arg_empty());
46 EXPECT_TRUE(F->hasLazyArguments());
47 EXPECT_EQ(2u, F->arg_size());
48 EXPECT_TRUE(F->hasLazyArguments());
50 // The argument list should be populated at first access.
51 (void)F->arg_begin();
52 EXPECT_FALSE(F->hasLazyArguments());
54 // Checking that getArg gets the arguments from F1 in the correct order.
55 unsigned i = 0;
56 for (Argument &A : F->args()) {
57 EXPECT_EQ(&A, F->getArg(i));
58 ++i;
60 EXPECT_FALSE(F->hasLazyArguments());
63 TEST(FunctionTest, stealArgumentListFrom) {
64 LLVMContext C;
66 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
67 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
68 std::unique_ptr<Function> F1(
69 Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
70 std::unique_ptr<Function> F2(
71 Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
72 EXPECT_TRUE(F1->hasLazyArguments());
73 EXPECT_TRUE(F2->hasLazyArguments());
75 // Steal arguments before they've been accessed. Nothing should change; both
76 // functions should still have lazy arguments.
78 // steal(empty); drop (empty)
79 F1->stealArgumentListFrom(*F2);
80 EXPECT_TRUE(F1->hasLazyArguments());
81 EXPECT_TRUE(F2->hasLazyArguments());
83 // Save arguments from F1 for later assertions. F1 won't have lazy arguments
84 // anymore.
85 SmallVector<Argument *, 4> Args;
86 for (Argument &A : F1->args())
87 Args.push_back(&A);
88 EXPECT_EQ(2u, Args.size());
89 EXPECT_FALSE(F1->hasLazyArguments());
91 // Steal arguments from F1 to F2. F1's arguments should be lazy again.
93 // steal(real); drop (empty)
94 F2->stealArgumentListFrom(*F1);
95 EXPECT_TRUE(F1->hasLazyArguments());
96 EXPECT_FALSE(F2->hasLazyArguments());
97 unsigned I = 0;
98 for (Argument &A : F2->args()) {
99 EXPECT_EQ(Args[I], &A);
100 I++;
102 EXPECT_EQ(2u, I);
104 // Check that arguments in F1 don't have pointer equality with the saved ones.
105 // This also instantiates F1's arguments.
106 I = 0;
107 for (Argument &A : F1->args()) {
108 EXPECT_NE(Args[I], &A);
109 I++;
111 EXPECT_EQ(2u, I);
112 EXPECT_FALSE(F1->hasLazyArguments());
113 EXPECT_FALSE(F2->hasLazyArguments());
115 // Steal back from F2. F2's arguments should be lazy again.
117 // steal(real); drop (real)
118 F1->stealArgumentListFrom(*F2);
119 EXPECT_FALSE(F1->hasLazyArguments());
120 EXPECT_TRUE(F2->hasLazyArguments());
121 I = 0;
122 for (Argument &A : F1->args()) {
123 EXPECT_EQ(Args[I], &A);
124 I++;
126 EXPECT_EQ(2u, I);
128 // Steal from F2 a second time. Now both functions should have lazy
129 // arguments.
131 // steal(empty); drop (real)
132 F1->stealArgumentListFrom(*F2);
133 EXPECT_TRUE(F1->hasLazyArguments());
134 EXPECT_TRUE(F2->hasLazyArguments());
137 // Test setting and removing section information
138 TEST(FunctionTest, setSection) {
139 LLVMContext C;
140 Module M("test", C);
142 llvm::Function *F =
143 Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C), false),
144 llvm::GlobalValue::ExternalLinkage, "F", &M);
146 F->setSection(".text.test");
147 EXPECT_TRUE(F->getSection() == ".text.test");
148 EXPECT_TRUE(F->hasSection());
149 F->setSection("");
150 EXPECT_FALSE(F->hasSection());
151 F->setSection(".text.test");
152 F->setSection(".text.test2");
153 EXPECT_TRUE(F->getSection() == ".text.test2");
154 EXPECT_TRUE(F->hasSection());
157 TEST(FunctionTest, GetPointerAlignment) {
158 LLVMContext Context;
159 Type *VoidType(Type::getVoidTy(Context));
160 FunctionType *FuncType(FunctionType::get(VoidType, false));
161 std::unique_ptr<Function> Func(Function::Create(
162 FuncType, GlobalValue::ExternalLinkage));
163 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("")));
164 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fi8")));
165 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fn8")));
166 EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fi16")));
167 EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fn16")));
168 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fi32")));
169 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn32")));
171 Func->setAlignment(Align(4));
173 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("")));
174 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fi8")));
175 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn8")));
176 EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fi16")));
177 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn16")));
178 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fi32")));
179 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn32")));
182 TEST(FunctionTest, InsertBasicBlockAt) {
183 LLVMContext C;
184 std::unique_ptr<Module> M = parseIR(C, R"(
185 define void @foo(i32 %a, i32 %b) {
186 foo_bb0:
187 ret void
190 define void @bar() {
191 bar_bb0:
192 br label %bar_bb1
193 bar_bb1:
194 br label %bar_bb2
195 bar_bb2:
196 ret void
198 )");
199 Function *FooF = M->getFunction("foo");
200 BasicBlock *FooBB0 = getBBWithName(FooF, "foo_bb0");
202 Function *BarF = M->getFunction("bar");
203 BasicBlock *BarBB0 = getBBWithName(BarF, "bar_bb0");
204 BasicBlock *BarBB1 = getBBWithName(BarF, "bar_bb1");
205 BasicBlock *BarBB2 = getBBWithName(BarF, "bar_bb2");
207 // Insert foo_bb0 into bar() at the very top.
208 FooBB0->removeFromParent();
209 auto It = BarF->insert(BarF->begin(), FooBB0);
210 EXPECT_EQ(BarBB0->getPrevNode(), FooBB0);
211 EXPECT_EQ(It, FooBB0->getIterator());
213 // Insert foo_bb0 into bar() at the very end.
214 FooBB0->removeFromParent();
215 It = BarF->insert(BarF->end(), FooBB0);
216 EXPECT_EQ(FooBB0->getPrevNode(), BarBB2);
217 EXPECT_EQ(FooBB0->getNextNode(), nullptr);
218 EXPECT_EQ(It, FooBB0->getIterator());
220 // Insert foo_bb0 into bar() just before bar_bb0.
221 FooBB0->removeFromParent();
222 It = BarF->insert(BarBB0->getIterator(), FooBB0);
223 EXPECT_EQ(FooBB0->getPrevNode(), nullptr);
224 EXPECT_EQ(FooBB0->getNextNode(), BarBB0);
225 EXPECT_EQ(It, FooBB0->getIterator());
227 // Insert foo_bb0 into bar() just before bar_bb1.
228 FooBB0->removeFromParent();
229 It = BarF->insert(BarBB1->getIterator(), FooBB0);
230 EXPECT_EQ(FooBB0->getPrevNode(), BarBB0);
231 EXPECT_EQ(FooBB0->getNextNode(), BarBB1);
232 EXPECT_EQ(It, FooBB0->getIterator());
234 // Insert foo_bb0 into bar() just before bar_bb2.
235 FooBB0->removeFromParent();
236 It = BarF->insert(BarBB2->getIterator(), FooBB0);
237 EXPECT_EQ(FooBB0->getPrevNode(), BarBB1);
238 EXPECT_EQ(FooBB0->getNextNode(), BarBB2);
239 EXPECT_EQ(It, FooBB0->getIterator());
242 TEST(FunctionTest, SpliceOneBB) {
243 LLVMContext Ctx;
244 std::unique_ptr<Module> M = parseIR(Ctx, R"(
245 define void @from() {
246 from_bb1:
247 br label %from_bb2
248 from_bb2:
249 br label %from_bb3
250 from_bb3:
251 ret void
253 define void @to() {
254 to_bb1:
255 br label %to_bb2
256 to_bb2:
257 br label %to_bb3
258 to_bb3:
259 ret void
261 )");
262 Function *FromF = M->getFunction("from");
263 BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
264 BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
265 BasicBlock *FromBB3 = getBBWithName(FromF, "from_bb3");
267 Function *ToF = M->getFunction("to");
268 BasicBlock *ToBB1 = getBBWithName(ToF, "to_bb1");
269 BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
270 BasicBlock *ToBB3 = getBBWithName(ToF, "to_bb3");
272 // Move from_bb2 before to_bb1.
273 ToF->splice(ToBB1->getIterator(), FromF, FromBB2->getIterator());
274 EXPECT_EQ(FromF->size(), 2u);
275 EXPECT_EQ(ToF->size(), 4u);
277 auto It = FromF->begin();
278 EXPECT_EQ(&*It++, FromBB1);
279 EXPECT_EQ(&*It++, FromBB3);
281 It = ToF->begin();
282 EXPECT_EQ(&*It++, FromBB2);
283 EXPECT_EQ(&*It++, ToBB1);
284 EXPECT_EQ(&*It++, ToBB2);
285 EXPECT_EQ(&*It++, ToBB3);
287 // Cleanup to avoid "Uses remain when a value is destroyed!".
288 FromF->splice(FromBB3->getIterator(), ToF, FromBB2->getIterator());
291 TEST(FunctionTest, SpliceOneBBWhenFromIsSameAsTo) {
292 LLVMContext Ctx;
293 std::unique_ptr<Module> M = parseIR(Ctx, R"(
294 define void @fromto() {
295 bb1:
296 br label %bb2
297 bb2:
298 ret void
300 )");
301 Function *F = M->getFunction("fromto");
302 BasicBlock *BB1 = getBBWithName(F, "bb1");
303 BasicBlock *BB2 = getBBWithName(F, "bb2");
305 // According to ilist's splice() a single-element splice where dst == src
306 // should be a noop.
307 F->splice(BB1->getIterator(), F, BB1->getIterator());
309 auto It = F->begin();
310 EXPECT_EQ(&*It++, BB1);
311 EXPECT_EQ(&*It++, BB2);
312 EXPECT_EQ(F->size(), 2u);
315 TEST(FunctionTest, SpliceLastBB) {
316 LLVMContext Ctx;
317 std::unique_ptr<Module> M = parseIR(Ctx, R"(
318 define void @from() {
319 from_bb1:
320 br label %from_bb2
321 from_bb2:
322 br label %from_bb3
323 from_bb3:
324 ret void
326 define void @to() {
327 to_bb1:
328 br label %to_bb2
329 to_bb2:
330 br label %to_bb3
331 to_bb3:
332 ret void
334 )");
336 Function *FromF = M->getFunction("from");
337 BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
338 BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
339 BasicBlock *FromBB3 = getBBWithName(FromF, "from_bb3");
341 Function *ToF = M->getFunction("to");
342 BasicBlock *ToBB1 = getBBWithName(ToF, "to_bb1");
343 BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
344 BasicBlock *ToBB3 = getBBWithName(ToF, "to_bb3");
346 // Move from_bb2 before to_bb1.
347 auto ToMove = FromBB2->getIterator();
348 ToF->splice(ToBB1->getIterator(), FromF, ToMove, std::next(ToMove));
350 EXPECT_EQ(FromF->size(), 2u);
351 auto It = FromF->begin();
352 EXPECT_EQ(&*It++, FromBB1);
353 EXPECT_EQ(&*It++, FromBB3);
355 EXPECT_EQ(ToF->size(), 4u);
356 It = ToF->begin();
357 EXPECT_EQ(&*It++, FromBB2);
358 EXPECT_EQ(&*It++, ToBB1);
359 EXPECT_EQ(&*It++, ToBB2);
360 EXPECT_EQ(&*It++, ToBB3);
362 // Cleanup to avoid "Uses remain when a value is destroyed!".
363 FromF->splice(FromBB3->getIterator(), ToF, ToMove);
366 TEST(FunctionTest, SpliceBBRange) {
367 LLVMContext Ctx;
368 std::unique_ptr<Module> M = parseIR(Ctx, R"(
369 define void @from() {
370 from_bb1:
371 br label %from_bb2
372 from_bb2:
373 br label %from_bb3
374 from_bb3:
375 ret void
377 define void @to() {
378 to_bb1:
379 br label %to_bb2
380 to_bb2:
381 br label %to_bb3
382 to_bb3:
383 ret void
385 )");
387 Function *FromF = M->getFunction("from");
388 BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
389 BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
390 BasicBlock *FromBB3 = getBBWithName(FromF, "from_bb3");
392 Function *ToF = M->getFunction("to");
393 BasicBlock *ToBB1 = getBBWithName(ToF, "to_bb1");
394 BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
395 BasicBlock *ToBB3 = getBBWithName(ToF, "to_bb3");
397 // Move all BBs from @from to @to.
398 ToF->splice(ToBB2->getIterator(), FromF, FromF->begin(), FromF->end());
400 EXPECT_EQ(FromF->size(), 0u);
402 EXPECT_EQ(ToF->size(), 6u);
403 auto It = ToF->begin();
404 EXPECT_EQ(&*It++, ToBB1);
405 EXPECT_EQ(&*It++, FromBB1);
406 EXPECT_EQ(&*It++, FromBB2);
407 EXPECT_EQ(&*It++, FromBB3);
408 EXPECT_EQ(&*It++, ToBB2);
409 EXPECT_EQ(&*It++, ToBB3);
412 #ifdef EXPENSIVE_CHECKS
413 TEST(FunctionTest, SpliceEndBeforeBegin) {
414 LLVMContext Ctx;
415 std::unique_ptr<Module> M = parseIR(Ctx, R"(
416 define void @from() {
417 from_bb1:
418 br label %from_bb2
419 from_bb2:
420 br label %from_bb3
421 from_bb3:
422 ret void
424 define void @to() {
425 to_bb1:
426 br label %to_bb2
427 to_bb2:
428 br label %to_bb3
429 to_bb3:
430 ret void
432 )");
434 Function *FromF = M->getFunction("from");
435 BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
436 BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
438 Function *ToF = M->getFunction("to");
439 BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
441 EXPECT_DEATH(ToF->splice(ToBB2->getIterator(), FromF, FromBB2->getIterator(),
442 FromBB1->getIterator()),
443 "FromBeginIt not before FromEndIt!");
445 #endif //EXPENSIVE_CHECKS
447 TEST(FunctionTest, EraseBBs) {
448 LLVMContext Ctx;
449 std::unique_ptr<Module> M = parseIR(Ctx, R"(
450 define void @foo() {
451 bb1:
452 br label %bb2
453 bb2:
454 br label %bb3
455 bb3:
456 br label %bb4
457 bb4:
458 br label %bb5
459 bb5:
460 ret void
462 )");
464 Function *F = M->getFunction("foo");
465 BasicBlock *BB1 = getBBWithName(F, "bb1");
466 BasicBlock *BB2 = getBBWithName(F, "bb2");
467 BasicBlock *BB3 = getBBWithName(F, "bb3");
468 BasicBlock *BB4 = getBBWithName(F, "bb4");
469 BasicBlock *BB5 = getBBWithName(F, "bb5");
470 EXPECT_EQ(F->size(), 5u);
472 // Erase BB2.
473 BB1->getTerminator()->eraseFromParent();
474 auto It = F->erase(BB2->getIterator(), std::next(BB2->getIterator()));
475 EXPECT_EQ(F->size(), 4u);
476 // Check that the iterator returned matches the node after the erased one.
477 EXPECT_EQ(It, BB3->getIterator());
479 It = F->begin();
480 EXPECT_EQ(&*It++, BB1);
481 EXPECT_EQ(&*It++, BB3);
482 EXPECT_EQ(&*It++, BB4);
483 EXPECT_EQ(&*It++, BB5);
485 // Erase all BBs.
486 It = F->erase(F->begin(), F->end());
487 EXPECT_EQ(F->size(), 0u);
490 TEST(FunctionTest, UWTable) {
491 LLVMContext Ctx;
492 std::unique_ptr<Module> M = parseIR(Ctx, R"(
493 define void @foo() {
494 bb1:
495 ret void
497 )");
499 Function &F = *M->getFunction("foo");
501 EXPECT_FALSE(F.hasUWTable());
502 EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
504 F.setUWTableKind(UWTableKind::Async);
505 EXPECT_TRUE(F.hasUWTable());
506 EXPECT_TRUE(F.getUWTableKind() == UWTableKind::Async);
508 F.setUWTableKind(UWTableKind::None);
509 EXPECT_FALSE(F.hasUWTable());
510 EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
512 } // end namespace