Fix test failures introduced by PR #113697 (#116941)
[llvm-project.git] / llvm / unittests / IR / FunctionTest.cpp
blobf6735fb55a6d522b4203abd13f9ce892b6b3f39e
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-c/Core.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/IR/Module.h"
13 #include "llvm/Support/SourceMgr.h"
14 #include "gtest/gtest.h"
15 using namespace llvm;
17 namespace {
19 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
20 SMDiagnostic Err;
21 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
22 if (!Mod)
23 Err.print("InstructionsTests", errs());
24 return Mod;
27 static BasicBlock *getBBWithName(Function *F, StringRef Name) {
28 auto It = find_if(
29 *F, [&Name](const BasicBlock &BB) { return BB.getName() == Name; });
30 assert(It != F->end() && "Not found!");
31 return &*It;
34 TEST(FunctionTest, hasLazyArguments) {
35 LLVMContext C;
37 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
38 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
40 // Functions start out with lazy arguments.
41 std::unique_ptr<Function> F(
42 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
43 EXPECT_TRUE(F->hasLazyArguments());
45 // Checking for empty or size shouldn't force arguments to be instantiated.
46 EXPECT_FALSE(F->arg_empty());
47 EXPECT_TRUE(F->hasLazyArguments());
48 EXPECT_EQ(2u, F->arg_size());
49 EXPECT_TRUE(F->hasLazyArguments());
51 // The argument list should be populated at first access.
52 (void)F->arg_begin();
53 EXPECT_FALSE(F->hasLazyArguments());
55 // Checking that getArg gets the arguments from F1 in the correct order.
56 unsigned i = 0;
57 for (Argument &A : F->args()) {
58 EXPECT_EQ(&A, F->getArg(i));
59 ++i;
61 EXPECT_FALSE(F->hasLazyArguments());
64 TEST(FunctionTest, stealArgumentListFrom) {
65 LLVMContext C;
67 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
68 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
69 std::unique_ptr<Function> F1(
70 Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
71 std::unique_ptr<Function> F2(
72 Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
73 EXPECT_TRUE(F1->hasLazyArguments());
74 EXPECT_TRUE(F2->hasLazyArguments());
76 // Steal arguments before they've been accessed. Nothing should change; both
77 // functions should still have lazy arguments.
79 // steal(empty); drop (empty)
80 F1->stealArgumentListFrom(*F2);
81 EXPECT_TRUE(F1->hasLazyArguments());
82 EXPECT_TRUE(F2->hasLazyArguments());
84 // Save arguments from F1 for later assertions. F1 won't have lazy arguments
85 // anymore.
86 SmallVector<Argument *, 4> Args;
87 for (Argument &A : F1->args())
88 Args.push_back(&A);
89 EXPECT_EQ(2u, Args.size());
90 EXPECT_FALSE(F1->hasLazyArguments());
92 // Steal arguments from F1 to F2. F1's arguments should be lazy again.
94 // steal(real); drop (empty)
95 F2->stealArgumentListFrom(*F1);
96 EXPECT_TRUE(F1->hasLazyArguments());
97 EXPECT_FALSE(F2->hasLazyArguments());
98 unsigned I = 0;
99 for (Argument &A : F2->args()) {
100 EXPECT_EQ(Args[I], &A);
101 I++;
103 EXPECT_EQ(2u, I);
105 // Check that arguments in F1 don't have pointer equality with the saved ones.
106 // This also instantiates F1's arguments.
107 I = 0;
108 for (Argument &A : F1->args()) {
109 EXPECT_NE(Args[I], &A);
110 I++;
112 EXPECT_EQ(2u, I);
113 EXPECT_FALSE(F1->hasLazyArguments());
114 EXPECT_FALSE(F2->hasLazyArguments());
116 // Steal back from F2. F2's arguments should be lazy again.
118 // steal(real); drop (real)
119 F1->stealArgumentListFrom(*F2);
120 EXPECT_FALSE(F1->hasLazyArguments());
121 EXPECT_TRUE(F2->hasLazyArguments());
122 I = 0;
123 for (Argument &A : F1->args()) {
124 EXPECT_EQ(Args[I], &A);
125 I++;
127 EXPECT_EQ(2u, I);
129 // Steal from F2 a second time. Now both functions should have lazy
130 // arguments.
132 // steal(empty); drop (real)
133 F1->stealArgumentListFrom(*F2);
134 EXPECT_TRUE(F1->hasLazyArguments());
135 EXPECT_TRUE(F2->hasLazyArguments());
138 // Test setting and removing section information
139 TEST(FunctionTest, setSection) {
140 LLVMContext C;
141 Module M("test", C);
143 llvm::Function *F =
144 Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C), false),
145 llvm::GlobalValue::ExternalLinkage, "F", &M);
147 F->setSection(".text.test");
148 EXPECT_TRUE(F->getSection() == ".text.test");
149 EXPECT_TRUE(F->hasSection());
150 F->setSection("");
151 EXPECT_FALSE(F->hasSection());
152 F->setSection(".text.test");
153 F->setSection(".text.test2");
154 EXPECT_TRUE(F->getSection() == ".text.test2");
155 EXPECT_TRUE(F->hasSection());
158 TEST(FunctionTest, GetPointerAlignment) {
159 LLVMContext Context;
160 Type *VoidType(Type::getVoidTy(Context));
161 FunctionType *FuncType(FunctionType::get(VoidType, false));
162 std::unique_ptr<Function> Func(Function::Create(
163 FuncType, GlobalValue::ExternalLinkage));
164 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("")));
165 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fi8")));
166 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fn8")));
167 EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fi16")));
168 EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fn16")));
169 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fi32")));
170 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn32")));
172 Func->setAlignment(Align(4));
174 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("")));
175 EXPECT_EQ(Align(1), Func->getPointerAlignment(DataLayout("Fi8")));
176 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn8")));
177 EXPECT_EQ(Align(2), Func->getPointerAlignment(DataLayout("Fi16")));
178 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn16")));
179 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fi32")));
180 EXPECT_EQ(Align(4), Func->getPointerAlignment(DataLayout("Fn32")));
183 TEST(FunctionTest, InsertBasicBlockAt) {
184 LLVMContext C;
185 std::unique_ptr<Module> M = parseIR(C, R"(
186 define void @foo(i32 %a, i32 %b) {
187 foo_bb0:
188 ret void
191 define void @bar() {
192 bar_bb0:
193 br label %bar_bb1
194 bar_bb1:
195 br label %bar_bb2
196 bar_bb2:
197 ret void
199 )");
200 Function *FooF = M->getFunction("foo");
201 BasicBlock *FooBB0 = getBBWithName(FooF, "foo_bb0");
203 Function *BarF = M->getFunction("bar");
204 BasicBlock *BarBB0 = getBBWithName(BarF, "bar_bb0");
205 BasicBlock *BarBB1 = getBBWithName(BarF, "bar_bb1");
206 BasicBlock *BarBB2 = getBBWithName(BarF, "bar_bb2");
208 // Insert foo_bb0 into bar() at the very top.
209 FooBB0->removeFromParent();
210 auto It = BarF->insert(BarF->begin(), FooBB0);
211 EXPECT_EQ(BarBB0->getPrevNode(), FooBB0);
212 EXPECT_EQ(It, FooBB0->getIterator());
214 // Insert foo_bb0 into bar() at the very end.
215 FooBB0->removeFromParent();
216 It = BarF->insert(BarF->end(), FooBB0);
217 EXPECT_EQ(FooBB0->getPrevNode(), BarBB2);
218 EXPECT_EQ(FooBB0->getNextNode(), nullptr);
219 EXPECT_EQ(It, FooBB0->getIterator());
221 // Insert foo_bb0 into bar() just before bar_bb0.
222 FooBB0->removeFromParent();
223 It = BarF->insert(BarBB0->getIterator(), FooBB0);
224 EXPECT_EQ(FooBB0->getPrevNode(), nullptr);
225 EXPECT_EQ(FooBB0->getNextNode(), BarBB0);
226 EXPECT_EQ(It, FooBB0->getIterator());
228 // Insert foo_bb0 into bar() just before bar_bb1.
229 FooBB0->removeFromParent();
230 It = BarF->insert(BarBB1->getIterator(), FooBB0);
231 EXPECT_EQ(FooBB0->getPrevNode(), BarBB0);
232 EXPECT_EQ(FooBB0->getNextNode(), BarBB1);
233 EXPECT_EQ(It, FooBB0->getIterator());
235 // Insert foo_bb0 into bar() just before bar_bb2.
236 FooBB0->removeFromParent();
237 It = BarF->insert(BarBB2->getIterator(), FooBB0);
238 EXPECT_EQ(FooBB0->getPrevNode(), BarBB1);
239 EXPECT_EQ(FooBB0->getNextNode(), BarBB2);
240 EXPECT_EQ(It, FooBB0->getIterator());
243 TEST(FunctionTest, SpliceOneBB) {
244 LLVMContext Ctx;
245 std::unique_ptr<Module> M = parseIR(Ctx, R"(
246 define void @from() {
247 from_bb1:
248 br label %from_bb2
249 from_bb2:
250 br label %from_bb3
251 from_bb3:
252 ret void
254 define void @to() {
255 to_bb1:
256 br label %to_bb2
257 to_bb2:
258 br label %to_bb3
259 to_bb3:
260 ret void
262 )");
263 Function *FromF = M->getFunction("from");
264 BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
265 BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
266 BasicBlock *FromBB3 = getBBWithName(FromF, "from_bb3");
268 Function *ToF = M->getFunction("to");
269 BasicBlock *ToBB1 = getBBWithName(ToF, "to_bb1");
270 BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
271 BasicBlock *ToBB3 = getBBWithName(ToF, "to_bb3");
273 // Move from_bb2 before to_bb1.
274 ToF->splice(ToBB1->getIterator(), FromF, FromBB2->getIterator());
275 EXPECT_EQ(FromF->size(), 2u);
276 EXPECT_EQ(ToF->size(), 4u);
278 auto It = FromF->begin();
279 EXPECT_EQ(&*It++, FromBB1);
280 EXPECT_EQ(&*It++, FromBB3);
282 It = ToF->begin();
283 EXPECT_EQ(&*It++, FromBB2);
284 EXPECT_EQ(&*It++, ToBB1);
285 EXPECT_EQ(&*It++, ToBB2);
286 EXPECT_EQ(&*It++, ToBB3);
288 // Cleanup to avoid "Uses remain when a value is destroyed!".
289 FromF->splice(FromBB3->getIterator(), ToF, FromBB2->getIterator());
292 TEST(FunctionTest, SpliceOneBBWhenFromIsSameAsTo) {
293 LLVMContext Ctx;
294 std::unique_ptr<Module> M = parseIR(Ctx, R"(
295 define void @fromto() {
296 bb1:
297 br label %bb2
298 bb2:
299 ret void
301 )");
302 Function *F = M->getFunction("fromto");
303 BasicBlock *BB1 = getBBWithName(F, "bb1");
304 BasicBlock *BB2 = getBBWithName(F, "bb2");
306 // According to ilist's splice() a single-element splice where dst == src
307 // should be a noop.
308 F->splice(BB1->getIterator(), F, BB1->getIterator());
310 auto It = F->begin();
311 EXPECT_EQ(&*It++, BB1);
312 EXPECT_EQ(&*It++, BB2);
313 EXPECT_EQ(F->size(), 2u);
316 TEST(FunctionTest, SpliceLastBB) {
317 LLVMContext Ctx;
318 std::unique_ptr<Module> M = parseIR(Ctx, R"(
319 define void @from() {
320 from_bb1:
321 br label %from_bb2
322 from_bb2:
323 br label %from_bb3
324 from_bb3:
325 ret void
327 define void @to() {
328 to_bb1:
329 br label %to_bb2
330 to_bb2:
331 br label %to_bb3
332 to_bb3:
333 ret void
335 )");
337 Function *FromF = M->getFunction("from");
338 BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
339 BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
340 BasicBlock *FromBB3 = getBBWithName(FromF, "from_bb3");
342 Function *ToF = M->getFunction("to");
343 BasicBlock *ToBB1 = getBBWithName(ToF, "to_bb1");
344 BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
345 BasicBlock *ToBB3 = getBBWithName(ToF, "to_bb3");
347 // Move from_bb2 before to_bb1.
348 auto ToMove = FromBB2->getIterator();
349 ToF->splice(ToBB1->getIterator(), FromF, ToMove, std::next(ToMove));
351 EXPECT_EQ(FromF->size(), 2u);
352 auto It = FromF->begin();
353 EXPECT_EQ(&*It++, FromBB1);
354 EXPECT_EQ(&*It++, FromBB3);
356 EXPECT_EQ(ToF->size(), 4u);
357 It = ToF->begin();
358 EXPECT_EQ(&*It++, FromBB2);
359 EXPECT_EQ(&*It++, ToBB1);
360 EXPECT_EQ(&*It++, ToBB2);
361 EXPECT_EQ(&*It++, ToBB3);
363 // Cleanup to avoid "Uses remain when a value is destroyed!".
364 FromF->splice(FromBB3->getIterator(), ToF, ToMove);
367 TEST(FunctionTest, SpliceBBRange) {
368 LLVMContext Ctx;
369 std::unique_ptr<Module> M = parseIR(Ctx, R"(
370 define void @from() {
371 from_bb1:
372 br label %from_bb2
373 from_bb2:
374 br label %from_bb3
375 from_bb3:
376 ret void
378 define void @to() {
379 to_bb1:
380 br label %to_bb2
381 to_bb2:
382 br label %to_bb3
383 to_bb3:
384 ret void
386 )");
388 Function *FromF = M->getFunction("from");
389 BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
390 BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
391 BasicBlock *FromBB3 = getBBWithName(FromF, "from_bb3");
393 Function *ToF = M->getFunction("to");
394 BasicBlock *ToBB1 = getBBWithName(ToF, "to_bb1");
395 BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
396 BasicBlock *ToBB3 = getBBWithName(ToF, "to_bb3");
398 // Move all BBs from @from to @to.
399 ToF->splice(ToBB2->getIterator(), FromF, FromF->begin(), FromF->end());
401 EXPECT_EQ(FromF->size(), 0u);
403 EXPECT_EQ(ToF->size(), 6u);
404 auto It = ToF->begin();
405 EXPECT_EQ(&*It++, ToBB1);
406 EXPECT_EQ(&*It++, FromBB1);
407 EXPECT_EQ(&*It++, FromBB2);
408 EXPECT_EQ(&*It++, FromBB3);
409 EXPECT_EQ(&*It++, ToBB2);
410 EXPECT_EQ(&*It++, ToBB3);
413 #ifdef EXPENSIVE_CHECKS
414 TEST(FunctionTest, SpliceEndBeforeBegin) {
415 LLVMContext Ctx;
416 std::unique_ptr<Module> M = parseIR(Ctx, R"(
417 define void @from() {
418 from_bb1:
419 br label %from_bb2
420 from_bb2:
421 br label %from_bb3
422 from_bb3:
423 ret void
425 define void @to() {
426 to_bb1:
427 br label %to_bb2
428 to_bb2:
429 br label %to_bb3
430 to_bb3:
431 ret void
433 )");
435 Function *FromF = M->getFunction("from");
436 BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
437 BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
439 Function *ToF = M->getFunction("to");
440 BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
442 EXPECT_DEATH(ToF->splice(ToBB2->getIterator(), FromF, FromBB2->getIterator(),
443 FromBB1->getIterator()),
444 "FromBeginIt not before FromEndIt!");
446 #endif //EXPENSIVE_CHECKS
448 TEST(FunctionTest, EraseBBs) {
449 LLVMContext Ctx;
450 std::unique_ptr<Module> M = parseIR(Ctx, R"(
451 define void @foo() {
452 bb1:
453 br label %bb2
454 bb2:
455 br label %bb3
456 bb3:
457 br label %bb4
458 bb4:
459 br label %bb5
460 bb5:
461 ret void
463 )");
465 Function *F = M->getFunction("foo");
466 BasicBlock *BB1 = getBBWithName(F, "bb1");
467 BasicBlock *BB2 = getBBWithName(F, "bb2");
468 BasicBlock *BB3 = getBBWithName(F, "bb3");
469 BasicBlock *BB4 = getBBWithName(F, "bb4");
470 BasicBlock *BB5 = getBBWithName(F, "bb5");
471 EXPECT_EQ(F->size(), 5u);
473 // Erase BB2.
474 BB1->getTerminator()->eraseFromParent();
475 auto It = F->erase(BB2->getIterator(), std::next(BB2->getIterator()));
476 EXPECT_EQ(F->size(), 4u);
477 // Check that the iterator returned matches the node after the erased one.
478 EXPECT_EQ(It, BB3->getIterator());
480 It = F->begin();
481 EXPECT_EQ(&*It++, BB1);
482 EXPECT_EQ(&*It++, BB3);
483 EXPECT_EQ(&*It++, BB4);
484 EXPECT_EQ(&*It++, BB5);
486 // Erase all BBs.
487 It = F->erase(F->begin(), F->end());
488 EXPECT_EQ(F->size(), 0u);
491 TEST(FunctionTest, BasicBlockNumbers) {
492 LLVMContext Context;
493 Type *VoidType = Type::getVoidTy(Context);
494 FunctionType *FuncType = FunctionType::get(VoidType, false);
495 std::unique_ptr<Function> Func(
496 Function::Create(FuncType, GlobalValue::ExternalLinkage));
498 EXPECT_EQ(Func->getBlockNumberEpoch(), 0u);
499 EXPECT_EQ(Func->getMaxBlockNumber(), 0u);
501 BasicBlock *BB1 = BasicBlock::Create(Context, "bb1", Func.get());
502 EXPECT_EQ(BB1->getNumber(), 0u);
503 EXPECT_EQ(Func->getMaxBlockNumber(), 1u);
504 BasicBlock *BB2 = BasicBlock::Create(Context, "bb2", Func.get());
505 EXPECT_EQ(BB2->getNumber(), 1u);
506 EXPECT_EQ(Func->getMaxBlockNumber(), 2u);
507 BasicBlock *BB3 = BasicBlock::Create(Context, "bb3", Func.get());
508 EXPECT_EQ(BB3->getNumber(), 2u);
509 EXPECT_EQ(Func->getMaxBlockNumber(), 3u);
511 BB2->eraseFromParent();
512 // Erasing doesn't trigger renumbering
513 EXPECT_EQ(BB1->getNumber(), 0u);
514 EXPECT_EQ(BB3->getNumber(), 2u);
515 EXPECT_EQ(Func->getMaxBlockNumber(), 3u);
516 // ... and number are assigned monotonically increasing
517 BasicBlock *BB4 = BasicBlock::Create(Context, "bb4", Func.get());
518 EXPECT_EQ(BB4->getNumber(), 3u);
519 EXPECT_EQ(Func->getMaxBlockNumber(), 4u);
520 // ... even if inserted not at the end
521 BasicBlock *BB5 = BasicBlock::Create(Context, "bb5", Func.get(), BB1);
522 EXPECT_EQ(BB5->getNumber(), 4u);
523 EXPECT_EQ(Func->getMaxBlockNumber(), 5u);
525 // Func is now: bb5, bb1, bb3, bb4
526 // Renumbering assigns numbers in their order in the function
527 EXPECT_EQ(Func->getBlockNumberEpoch(), 0u);
528 Func->renumberBlocks();
529 EXPECT_EQ(Func->getBlockNumberEpoch(), 1u);
530 EXPECT_EQ(BB5->getNumber(), 0u);
531 EXPECT_EQ(BB1->getNumber(), 1u);
532 EXPECT_EQ(BB3->getNumber(), 2u);
533 EXPECT_EQ(BB4->getNumber(), 3u);
534 EXPECT_EQ(Func->getMaxBlockNumber(), 4u);
536 // Moving a block inside the function doesn't change numbers
537 BB1->moveBefore(BB5);
538 EXPECT_EQ(BB5->getNumber(), 0u);
539 EXPECT_EQ(BB1->getNumber(), 1u);
540 EXPECT_EQ(BB3->getNumber(), 2u);
541 EXPECT_EQ(BB4->getNumber(), 3u);
542 EXPECT_EQ(Func->getMaxBlockNumber(), 4u);
544 // Removing a block and adding it back assigns a new number, because the
545 // block was temporarily without a parent.
546 BB4->removeFromParent();
547 BB4->insertInto(Func.get());
548 EXPECT_EQ(BB5->getNumber(), 0u);
549 EXPECT_EQ(BB1->getNumber(), 1u);
550 EXPECT_EQ(BB3->getNumber(), 2u);
551 EXPECT_EQ(BB4->getNumber(), 4u);
552 EXPECT_EQ(Func->getMaxBlockNumber(), 5u);
554 std::unique_ptr<Function> Func2(
555 Function::Create(FuncType, GlobalValue::ExternalLinkage));
556 BasicBlock *BB6 = BasicBlock::Create(Context, "bb6", Func2.get());
557 EXPECT_EQ(BB6->getNumber(), 0u);
558 EXPECT_EQ(Func2->getMaxBlockNumber(), 1u);
559 // Moving a block to a different function assigns a new number
560 BB3->removeFromParent();
561 BB3->insertInto(Func2.get(), BB6);
562 EXPECT_EQ(BB3->getParent(), Func2.get());
563 EXPECT_EQ(BB3->getNumber(), 1u);
564 EXPECT_EQ(Func2->getMaxBlockNumber(), 2u);
566 EXPECT_EQ(Func2->getBlockNumberEpoch(), 0u);
567 Func2->renumberBlocks();
568 EXPECT_EQ(Func2->getBlockNumberEpoch(), 1u);
569 EXPECT_EQ(BB3->getNumber(), 0u);
570 EXPECT_EQ(BB6->getNumber(), 1u);
571 EXPECT_EQ(Func2->getMaxBlockNumber(), 2u);
573 // splice works as expected and assigns new numbers
574 Func->splice(Func->end(), Func2.get());
575 EXPECT_EQ(BB5->getNumber(), 0u);
576 EXPECT_EQ(BB1->getNumber(), 1u);
577 EXPECT_EQ(BB4->getNumber(), 4u);
578 EXPECT_EQ(BB3->getNumber(), 5u);
579 EXPECT_EQ(BB6->getNumber(), 6u);
580 EXPECT_EQ(Func->getMaxBlockNumber(), 7u);
583 TEST(FunctionTest, UWTable) {
584 LLVMContext Ctx;
585 std::unique_ptr<Module> M = parseIR(Ctx, R"(
586 define void @foo() {
587 bb1:
588 ret void
590 )");
592 Function &F = *M->getFunction("foo");
594 EXPECT_FALSE(F.hasUWTable());
595 EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
597 F.setUWTableKind(UWTableKind::Async);
598 EXPECT_TRUE(F.hasUWTable());
599 EXPECT_TRUE(F.getUWTableKind() == UWTableKind::Async);
601 F.setUWTableKind(UWTableKind::None);
602 EXPECT_FALSE(F.hasUWTable());
603 EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
606 TEST(FunctionTest, Personality) {
607 LLVMContext Ctx;
608 Module M("test", Ctx);
609 Type *Int8Ty = Type::getInt8Ty(Ctx);
610 FunctionType *FTy = FunctionType::get(Int8Ty, false);
611 Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, "F", &M);
612 Function *PersonalityFn =
613 Function::Create(FTy, GlobalValue::ExternalLinkage, "PersonalityFn", &M);
615 EXPECT_FALSE(F->hasPersonalityFn());
616 F->setPersonalityFn(PersonalityFn);
617 EXPECT_TRUE(F->hasPersonalityFn());
618 EXPECT_EQ(F->getPersonalityFn(), PersonalityFn);
619 F->setPersonalityFn(nullptr);
620 EXPECT_FALSE(F->hasPersonalityFn());
622 EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F)));
623 LLVMSetPersonalityFn(wrap(F), wrap(PersonalityFn));
624 EXPECT_TRUE(LLVMHasPersonalityFn(wrap(F)));
625 EXPECT_EQ(LLVMGetPersonalityFn(wrap(F)), wrap(PersonalityFn));
626 LLVMSetPersonalityFn(wrap(F), nullptr);
627 EXPECT_FALSE(LLVMHasPersonalityFn(wrap(F)));
630 } // end namespace