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