xref: /llvm-project/llvm/unittests/IR/FunctionTest.cpp (revision 0bd513082540b2b00bfad1540812e3ea282e70ed)
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 //===----------------------------------------------------------------------===//
8 
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;
16 
17 namespace {
18 
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;
25 }
26 
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;
32 }
33 
34 TEST(FunctionTest, hasLazyArguments) {
35   LLVMContext C;
36 
37   Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
38   FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
39 
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());
44 
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());
50 
51   // The argument list should be populated at first access.
52   (void)F->arg_begin();
53   EXPECT_FALSE(F->hasLazyArguments());
54 
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;
60   }
61   EXPECT_FALSE(F->hasLazyArguments());
62 }
63 
64 TEST(FunctionTest, stealArgumentListFrom) {
65   LLVMContext C;
66 
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());
75 
76   // Steal arguments before they've been accessed.  Nothing should change; both
77   // functions should still have lazy arguments.
78   //
79   //   steal(empty); drop (empty)
80   F1->stealArgumentListFrom(*F2);
81   EXPECT_TRUE(F1->hasLazyArguments());
82   EXPECT_TRUE(F2->hasLazyArguments());
83 
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());
91 
92   // Steal arguments from F1 to F2.  F1's arguments should be lazy again.
93   //
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++;
102   }
103   EXPECT_EQ(2u, I);
104 
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++;
111   }
112   EXPECT_EQ(2u, I);
113   EXPECT_FALSE(F1->hasLazyArguments());
114   EXPECT_FALSE(F2->hasLazyArguments());
115 
116   // Steal back from F2.  F2's arguments should be lazy again.
117   //
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++;
126   }
127   EXPECT_EQ(2u, I);
128 
129   // Steal from F2 a second time.  Now both functions should have lazy
130   // arguments.
131   //
132   //   steal(empty); drop (real)
133   F1->stealArgumentListFrom(*F2);
134   EXPECT_TRUE(F1->hasLazyArguments());
135   EXPECT_TRUE(F2->hasLazyArguments());
136 }
137 
138 // Test setting and removing section information
139 TEST(FunctionTest, setSection) {
140   LLVMContext C;
141   Module M("test", C);
142 
143   llvm::Function *F =
144       Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C), false),
145                        llvm::GlobalValue::ExternalLinkage, "F", &M);
146 
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());
156 }
157 
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")));
171 
172   Func->setAlignment(Align(4));
173 
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")));
181 }
182 
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
189 }
190 
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
198 }
199 )");
200   Function *FooF = M->getFunction("foo");
201   BasicBlock *FooBB0 = getBBWithName(FooF, "foo_bb0");
202 
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");
207 
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());
213 
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());
220 
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());
227 
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());
234 
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());
241 }
242 
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
253     }
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
261     }
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");
267 
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");
272 
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);
277 
278   auto It = FromF->begin();
279   EXPECT_EQ(&*It++, FromBB1);
280   EXPECT_EQ(&*It++, FromBB3);
281 
282   It = ToF->begin();
283   EXPECT_EQ(&*It++, FromBB2);
284   EXPECT_EQ(&*It++, ToBB1);
285   EXPECT_EQ(&*It++, ToBB2);
286   EXPECT_EQ(&*It++, ToBB3);
287 
288   // Cleanup to avoid "Uses remain when a value is destroyed!".
289   FromF->splice(FromBB3->getIterator(), ToF, FromBB2->getIterator());
290 }
291 
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
300     }
301 )");
302   Function *F = M->getFunction("fromto");
303   BasicBlock *BB1 = getBBWithName(F, "bb1");
304   BasicBlock *BB2 = getBBWithName(F, "bb2");
305 
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());
309 
310   auto It = F->begin();
311   EXPECT_EQ(&*It++, BB1);
312   EXPECT_EQ(&*It++, BB2);
313   EXPECT_EQ(F->size(), 2u);
314 }
315 
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
326     }
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
334     }
335 )");
336 
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");
341 
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");
346 
347   // Move from_bb2 before to_bb1.
348   auto ToMove = FromBB2->getIterator();
349   ToF->splice(ToBB1->getIterator(), FromF, ToMove, std::next(ToMove));
350 
351   EXPECT_EQ(FromF->size(), 2u);
352   auto It = FromF->begin();
353   EXPECT_EQ(&*It++, FromBB1);
354   EXPECT_EQ(&*It++, FromBB3);
355 
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);
362 
363   // Cleanup to avoid "Uses remain when a value is destroyed!".
364   FromF->splice(FromBB3->getIterator(), ToF, ToMove);
365 }
366 
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
377     }
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
385     }
386 )");
387 
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");
392 
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");
397 
398   // Move all BBs from @from to @to.
399   ToF->splice(ToBB2->getIterator(), FromF, FromF->begin(), FromF->end());
400 
401   EXPECT_EQ(FromF->size(), 0u);
402 
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);
411 }
412 
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
424     }
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
432     }
433 )");
434 
435   Function *FromF = M->getFunction("from");
436   BasicBlock *FromBB1 = getBBWithName(FromF, "from_bb1");
437   BasicBlock *FromBB2 = getBBWithName(FromF, "from_bb2");
438 
439   Function *ToF = M->getFunction("to");
440   BasicBlock *ToBB2 = getBBWithName(ToF, "to_bb2");
441 
442   EXPECT_DEATH(ToF->splice(ToBB2->getIterator(), FromF, FromBB2->getIterator(),
443                            FromBB1->getIterator()),
444                "FromBeginIt not before FromEndIt!");
445 }
446 #endif //EXPENSIVE_CHECKS
447 
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
462     }
463 )");
464 
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);
472 
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());
479 
480   It = F->begin();
481   EXPECT_EQ(&*It++, BB1);
482   EXPECT_EQ(&*It++, BB3);
483   EXPECT_EQ(&*It++, BB4);
484   EXPECT_EQ(&*It++, BB5);
485 
486   // Erase all BBs.
487   It = F->erase(F->begin(), F->end());
488   EXPECT_EQ(F->size(), 0u);
489 }
490 
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));
497 
498   EXPECT_EQ(Func->getBlockNumberEpoch(), 0u);
499   EXPECT_EQ(Func->getMaxBlockNumber(), 0u);
500 
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);
510 
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);
524 
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);
535 
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);
543 
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);
553 
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);
565 
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);
572 
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);
581 }
582 
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
589     }
590 )");
591 
592   Function &F = *M->getFunction("foo");
593 
594   EXPECT_FALSE(F.hasUWTable());
595   EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
596 
597   F.setUWTableKind(UWTableKind::Async);
598   EXPECT_TRUE(F.hasUWTable());
599   EXPECT_TRUE(F.getUWTableKind() == UWTableKind::Async);
600 
601   F.setUWTableKind(UWTableKind::None);
602   EXPECT_FALSE(F.hasUWTable());
603   EXPECT_TRUE(F.getUWTableKind() == UWTableKind::None);
604 }
605 
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);
614 
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());
621 
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)));
628 }
629 
630 } // end namespace
631