1 ; RUN: opt -objc-arc -S < %s | FileCheck %s 2 3 target datalayout = "e-p:64:64:64" 4 5 declare i8* @objc_retain(i8*) 6 declare void @objc_release(i8*) 7 declare i8* @objc_autorelease(i8*) 8 declare void @objc_autoreleasePoolPop(i8*) 9 declare void @objc_autoreleasePoolPush() 10 declare i8* @objc_retainBlock(i8*) 11 12 declare i8* @objc_retainedObject(i8*) 13 declare i8* @objc_unretainedObject(i8*) 14 declare i8* @objc_unretainedPointer(i8*) 15 16 declare void @use_pointer(i8*) 17 declare void @callee() 18 declare void @callee_fnptr(void ()*) 19 declare void @invokee() 20 declare i8* @returner() 21 22 declare void @llvm.dbg.value(metadata, i64, metadata) 23 24 declare i8* @objc_msgSend(i8*, i8*, ...) 25 26 ; Simple retain+release pair deletion, with some intervening control 27 ; flow and harmless instructions. 28 29 ; CHECK: define void @test0( 30 ; CHECK-NOT: @objc_ 31 ; CHECK: } 32 define void @test0(i32* %x, i1 %p) nounwind { 33 entry: 34 %a = bitcast i32* %x to i8* 35 %0 = call i8* @objc_retain(i8* %a) nounwind 36 br i1 %p, label %t, label %f 37 38 t: 39 store i8 3, i8* %a 40 %b = bitcast i32* %x to float* 41 store float 2.0, float* %b 42 br label %return 43 44 f: 45 store i32 7, i32* %x 46 br label %return 47 48 return: 49 %c = bitcast i32* %x to i8* 50 call void @objc_release(i8* %c) nounwind 51 ret void 52 } 53 54 ; Like test0 but the release isn't always executed when the retain is, 55 ; so the optimization is not safe. 56 57 ; TODO: Make the objc_release's argument be %0. 58 59 ; CHECK: define void @test1( 60 ; CHECK: @objc_retain(i8* %a) 61 ; CHECK: @objc_release 62 ; CHECK: } 63 define void @test1(i32* %x, i1 %p, i1 %q) nounwind { 64 entry: 65 %a = bitcast i32* %x to i8* 66 %0 = call i8* @objc_retain(i8* %a) nounwind 67 br i1 %p, label %t, label %f 68 69 t: 70 store i8 3, i8* %a 71 %b = bitcast i32* %x to float* 72 store float 2.0, float* %b 73 br label %return 74 75 f: 76 store i32 7, i32* %x 77 call void @callee() 78 br i1 %q, label %return, label %alt_return 79 80 return: 81 %c = bitcast i32* %x to i8* 82 call void @objc_release(i8* %c) nounwind 83 ret void 84 85 alt_return: 86 ret void 87 } 88 89 ; Like test0 but the pointer is passed to an intervening call, 90 ; so the optimization is not safe. 91 92 ; CHECK: define void @test2( 93 ; CHECK: @objc_retain(i8* %a) 94 ; CHECK: @objc_release 95 ; CHECK: } 96 define void @test2(i32* %x, i1 %p) nounwind { 97 entry: 98 %a = bitcast i32* %x to i8* 99 %0 = call i8* @objc_retain(i8* %a) nounwind 100 br i1 %p, label %t, label %f 101 102 t: 103 store i8 3, i8* %a 104 %b = bitcast i32* %x to float* 105 store float 2.0, float* %b 106 br label %return 107 108 f: 109 store i32 7, i32* %x 110 call void @use_pointer(i8* %0) 111 %d = bitcast i32* %x to float* 112 store float 3.0, float* %d 113 br label %return 114 115 return: 116 %c = bitcast i32* %x to i8* 117 call void @objc_release(i8* %c) nounwind 118 ret void 119 } 120 121 ; Like test0 but the release is in a loop, 122 ; so the optimization is not safe. 123 124 ; TODO: For now, assume this can't happen. 125 126 ; CHECK: define void @test3( 127 ; TODO: @objc_retain(i8* %a) 128 ; TODO: @objc_release 129 ; CHECK: } 130 define void @test3(i32* %x, i1* %q) nounwind { 131 entry: 132 %a = bitcast i32* %x to i8* 133 %0 = call i8* @objc_retain(i8* %a) nounwind 134 br label %loop 135 136 loop: 137 %c = bitcast i32* %x to i8* 138 call void @objc_release(i8* %c) nounwind 139 %j = volatile load i1* %q 140 br i1 %j, label %loop, label %return 141 142 return: 143 ret void 144 } 145 146 ; TODO: For now, assume this can't happen. 147 148 ; Like test0 but the retain is in a loop, 149 ; so the optimization is not safe. 150 151 ; CHECK: define void @test4( 152 ; TODO: @objc_retain(i8* %a) 153 ; TODO: @objc_release 154 ; CHECK: } 155 define void @test4(i32* %x, i1* %q) nounwind { 156 entry: 157 br label %loop 158 159 loop: 160 %a = bitcast i32* %x to i8* 161 %0 = call i8* @objc_retain(i8* %a) nounwind 162 %j = volatile load i1* %q 163 br i1 %j, label %loop, label %return 164 165 return: 166 %c = bitcast i32* %x to i8* 167 call void @objc_release(i8* %c) nounwind 168 ret void 169 } 170 171 ; Like test0 but the pointer is conditionally passed to an intervening call, 172 ; so the optimization is not safe. 173 174 ; CHECK: define void @test5( 175 ; CHECK: @objc_retain(i8* 176 ; CHECK: @objc_release 177 ; CHECK: } 178 define void @test5(i32* %x, i1 %q, i8* %y) nounwind { 179 entry: 180 %a = bitcast i32* %x to i8* 181 %0 = call i8* @objc_retain(i8* %a) nounwind 182 %s = select i1 %q, i8* %y, i8* %0 183 call void @use_pointer(i8* %s) 184 store i32 7, i32* %x 185 %c = bitcast i32* %x to i8* 186 call void @objc_release(i8* %c) nounwind 187 ret void 188 } 189 190 ; retain+release pair deletion, where the release happens on two different 191 ; flow paths. 192 193 ; CHECK: define void @test6( 194 ; CHECK-NOT: @objc_ 195 ; CHECK: } 196 define void @test6(i32* %x, i1 %p) nounwind { 197 entry: 198 %a = bitcast i32* %x to i8* 199 %0 = call i8* @objc_retain(i8* %a) nounwind 200 br i1 %p, label %t, label %f 201 202 t: 203 store i8 3, i8* %a 204 %b = bitcast i32* %x to float* 205 store float 2.0, float* %b 206 %ct = bitcast i32* %x to i8* 207 call void @objc_release(i8* %ct) nounwind 208 br label %return 209 210 f: 211 store i32 7, i32* %x 212 call void @callee() 213 %cf = bitcast i32* %x to i8* 214 call void @objc_release(i8* %cf) nounwind 215 br label %return 216 217 return: 218 ret void 219 } 220 221 ; retain+release pair deletion, where the retain happens on two different 222 ; flow paths. 223 224 ; CHECK: define void @test7( 225 ; CHECK-NOT: @objc_ 226 ; CHECK: } 227 define void @test7(i32* %x, i1 %p) nounwind { 228 entry: 229 %a = bitcast i32* %x to i8* 230 br i1 %p, label %t, label %f 231 232 t: 233 %0 = call i8* @objc_retain(i8* %a) nounwind 234 store i8 3, i8* %a 235 %b = bitcast i32* %x to float* 236 store float 2.0, float* %b 237 br label %return 238 239 f: 240 %1 = call i8* @objc_retain(i8* %a) nounwind 241 store i32 7, i32* %x 242 call void @callee() 243 br label %return 244 245 return: 246 %c = bitcast i32* %x to i8* 247 call void @objc_release(i8* %c) nounwind 248 ret void 249 } 250 251 ; Like test7, but there's a retain/retainBlock mismatch. Don't delete! 252 253 ; CHECK: define void @test7b 254 ; CHECK: t: 255 ; CHECK: call i8* @objc_retainBlock 256 ; CHECK: f: 257 ; CHECK: call i8* @objc_retain 258 ; CHECK: return: 259 ; CHECK: call void @objc_release 260 ; CHECK: } 261 define void @test7b(i32* %x, i1 %p) nounwind { 262 entry: 263 %a = bitcast i32* %x to i8* 264 br i1 %p, label %t, label %f 265 266 t: 267 %0 = call i8* @objc_retainBlock(i8* %a) nounwind 268 store i8 3, i8* %a 269 %b = bitcast i32* %x to float* 270 store float 2.0, float* %b 271 br label %return 272 273 f: 274 %1 = call i8* @objc_retain(i8* %a) nounwind 275 store i32 7, i32* %x 276 call void @callee() 277 br label %return 278 279 return: 280 %c = bitcast i32* %x to i8* 281 call void @objc_release(i8* %c) nounwind 282 ret void 283 } 284 285 ; retain+release pair deletion, where the retain and release both happen on 286 ; different flow paths. Wild! 287 288 ; CHECK: define void @test8( 289 ; CHECK-NOT: @objc_ 290 ; CHECK: } 291 define void @test8(i32* %x, i1 %p, i1 %q) nounwind { 292 entry: 293 %a = bitcast i32* %x to i8* 294 br i1 %p, label %t, label %f 295 296 t: 297 %0 = call i8* @objc_retain(i8* %a) nounwind 298 store i8 3, i8* %a 299 %b = bitcast i32* %x to float* 300 store float 2.0, float* %b 301 br label %mid 302 303 f: 304 %1 = call i8* @objc_retain(i8* %a) nounwind 305 store i32 7, i32* %x 306 br label %mid 307 308 mid: 309 br i1 %q, label %u, label %g 310 311 u: 312 call void @callee() 313 %cu = bitcast i32* %x to i8* 314 call void @objc_release(i8* %cu) nounwind 315 br label %return 316 317 g: 318 %cg = bitcast i32* %x to i8* 319 call void @objc_release(i8* %cg) nounwind 320 br label %return 321 322 return: 323 ret void 324 } 325 326 ; Trivial retain+release pair deletion. 327 328 ; CHECK: define void @test9( 329 ; CHECK-NOT: @objc_ 330 ; CHECK: } 331 define void @test9(i8* %x) nounwind { 332 entry: 333 %0 = call i8* @objc_retain(i8* %x) nounwind 334 call void @objc_release(i8* %0) nounwind 335 ret void 336 } 337 338 ; Retain+release pair, but on an unknown pointer relationship. Don't delete! 339 340 ; CHECK: define void @test9b 341 ; CHECK: @objc_retain(i8* %x) 342 ; CHECK: @objc_release(i8* %s) 343 ; CHECK: } 344 define void @test9b(i8* %x, i1 %j, i8* %p) nounwind { 345 entry: 346 %0 = call i8* @objc_retain(i8* %x) nounwind 347 %s = select i1 %j, i8* %x, i8* %p 348 call void @objc_release(i8* %s) nounwind 349 ret void 350 } 351 352 ; Trivial retain+release pair with intervening calls - don't delete! 353 354 ; CHECK: define void @test10( 355 ; CHECK: @objc_retain(i8* %x) 356 ; CHECK: @callee 357 ; CHECK: @use_pointer 358 ; CHECK: @objc_release 359 ; CHECK: } 360 define void @test10(i8* %x) nounwind { 361 entry: 362 %0 = call i8* @objc_retain(i8* %x) nounwind 363 call void @callee() 364 call void @use_pointer(i8* %x) 365 call void @objc_release(i8* %0) nounwind 366 ret void 367 } 368 369 ; Trivial retain+autoreleaserelease pair. Don't delete! 370 ; Also, add a tail keyword, since objc_retain can never be passed 371 ; a stack argument. 372 373 ; CHECK: define void @test11( 374 ; CHECK: tail call i8* @objc_retain(i8* %x) nounwind 375 ; CHECK: tail call i8* @objc_autorelease(i8* %0) nounwind 376 ; CHECK: } 377 define void @test11(i8* %x) nounwind { 378 entry: 379 %0 = call i8* @objc_retain(i8* %x) nounwind 380 call i8* @objc_autorelease(i8* %0) nounwind 381 call void @use_pointer(i8* %x) 382 ret void 383 } 384 385 ; Same as test11 but with no use_pointer call. Delete the pair! 386 387 ; CHECK: define void @test11a( 388 ; CHECK: entry: 389 ; CHECK-NEXT: ret void 390 ; CHECK: } 391 define void @test11a(i8* %x) nounwind { 392 entry: 393 %0 = call i8* @objc_retain(i8* %x) nounwind 394 call i8* @objc_autorelease(i8* %0) nounwind 395 ret void 396 } 397 398 ; Same as test11 but the value is returned. Do an RV optimization. 399 400 ; CHECK: define i8* @test11b( 401 ; CHECK: tail call i8* @objc_retain(i8* %x) nounwind 402 ; CHECK: tail call i8* @objc_autoreleaseReturnValue(i8* %0) nounwind 403 ; CHECK: } 404 define i8* @test11b(i8* %x) nounwind { 405 entry: 406 %0 = call i8* @objc_retain(i8* %x) nounwind 407 call i8* @objc_autorelease(i8* %0) nounwind 408 ret i8* %x 409 } 410 411 ; Trivial retain,release pair with intervening call, but it's dominated 412 ; by another retain - delete! 413 414 ; CHECK: define void @test12( 415 ; CHECK-NEXT: entry: 416 ; CHECK-NEXT: @objc_retain(i8* %x) 417 ; CHECK-NOT: @objc_ 418 ; CHECK: } 419 define void @test12(i8* %x, i64 %n) { 420 entry: 421 call i8* @objc_retain(i8* %x) nounwind 422 call i8* @objc_retain(i8* %x) nounwind 423 call void @use_pointer(i8* %x) 424 call void @use_pointer(i8* %x) 425 call void @objc_release(i8* %x) nounwind 426 ret void 427 } 428 429 ; Trivial retain,autorelease pair. Don't delete! 430 431 ; CHECK: define void @test13( 432 ; CHECK: tail call i8* @objc_retain(i8* %x) nounwind 433 ; CHECK: tail call i8* @objc_retain(i8* %x) nounwind 434 ; CHECK: @use_pointer(i8* %x) 435 ; CHECK: tail call i8* @objc_autorelease(i8* %x) nounwind 436 ; CHECK: } 437 define void @test13(i8* %x, i64 %n) { 438 entry: 439 call i8* @objc_retain(i8* %x) nounwind 440 call i8* @objc_retain(i8* %x) nounwind 441 call void @use_pointer(i8* %x) 442 call i8* @objc_autorelease(i8* %x) nounwind 443 ret void 444 } 445 446 ; Delete the retain+release pair. 447 448 ; CHECK: define void @test13b 449 ; CHECK-NEXT: entry: 450 ; CHECK-NEXT: @objc_retain(i8* %x) 451 ; CHECK-NEXT: @use_pointer 452 ; CHECK-NEXT: @use_pointer 453 ; CHECK-NEXT: ret void 454 define void @test13b(i8* %x, i64 %n) { 455 entry: 456 call i8* @objc_retain(i8* %x) nounwind 457 call i8* @objc_retain(i8* %x) nounwind 458 call void @use_pointer(i8* %x) 459 call void @use_pointer(i8* %x) 460 call void @objc_release(i8* %x) nounwind 461 ret void 462 } 463 464 ; Don't delete the retain+release pair because there's an 465 ; autoreleasePoolPop in the way. 466 467 ; CHECK: define void @test13c 468 ; CHECK: @objc_retain(i8* %x) 469 ; CHECK: @objc_autoreleasePoolPop 470 ; CHECK: @objc_retain(i8* %x) 471 ; CHECK: @use_pointer 472 ; CHECK: @objc_release 473 ; CHECK: } 474 define void @test13c(i8* %x, i64 %n) { 475 entry: 476 call i8* @objc_retain(i8* %x) nounwind 477 call void @objc_autoreleasePoolPop(i8* undef) 478 call i8* @objc_retain(i8* %x) nounwind 479 call void @use_pointer(i8* %x) 480 call void @use_pointer(i8* %x) 481 call void @objc_release(i8* %x) nounwind 482 ret void 483 } 484 485 ; Like test13c, but there's an autoreleasePoolPush in the way, but that 486 ; doesn't matter. 487 488 ; CHECK: define void @test13d 489 ; CHECK-NEXT: entry: 490 ; CHECK-NEXT: @objc_retain(i8* %x) 491 ; CHECK-NEXT: @objc_autoreleasePoolPush 492 ; CHECK-NEXT: @use_pointer 493 ; CHECK-NEXT: @use_pointer 494 ; CHECK-NEXT: ret void 495 define void @test13d(i8* %x, i64 %n) { 496 entry: 497 call i8* @objc_retain(i8* %x) nounwind 498 call void @objc_autoreleasePoolPush() 499 call i8* @objc_retain(i8* %x) nounwind 500 call void @use_pointer(i8* %x) 501 call void @use_pointer(i8* %x) 502 call void @objc_release(i8* %x) nounwind 503 ret void 504 } 505 506 ; Trivial retain,release pair with intervening call, but it's post-dominated 507 ; by another release - delete! 508 509 ; CHECK: define void @test14( 510 ; CHECK-NEXT: entry: 511 ; CHECK-NEXT: @use_pointer 512 ; CHECK-NEXT: @use_pointer 513 ; CHECK-NEXT: @objc_release 514 ; CHECK-NEXT: ret void 515 ; CHECK-NEXT: } 516 define void @test14(i8* %x, i64 %n) { 517 entry: 518 call i8* @objc_retain(i8* %x) nounwind 519 call void @use_pointer(i8* %x) 520 call void @use_pointer(i8* %x) 521 call void @objc_release(i8* %x) nounwind 522 call void @objc_release(i8* %x) nounwind 523 ret void 524 } 525 526 ; Trivial retain,autorelease pair with intervening call, but it's post-dominated 527 ; by another release. Don't delete anything. 528 529 ; CHECK: define void @test15( 530 ; CHECK-NEXT: entry: 531 ; CHECK-NEXT: @objc_retain(i8* %x) 532 ; CHECK-NEXT: @use_pointer 533 ; CHECK-NEXT: @objc_autorelease(i8* %x) 534 ; CHECK-NEXT: @objc_release 535 ; CHECK-NEXT: ret void 536 ; CHECK-NEXT: } 537 define void @test15(i8* %x, i64 %n) { 538 entry: 539 call i8* @objc_retain(i8* %x) nounwind 540 call void @use_pointer(i8* %x) 541 call i8* @objc_autorelease(i8* %x) nounwind 542 call void @objc_release(i8* %x) nounwind 543 ret void 544 } 545 546 ; Trivial retain,autorelease pair, post-dominated 547 ; by another release. Delete the retain and release. 548 549 ; CHECK: define void @test15b 550 ; CHECK-NEXT: entry: 551 ; CHECK-NEXT: @objc_autorelease 552 ; CHECK-NEXT: ret void 553 ; CHECK-NEXT: } 554 define void @test15b(i8* %x, i64 %n) { 555 entry: 556 call i8* @objc_retain(i8* %x) nounwind 557 call i8* @objc_autorelease(i8* %x) nounwind 558 call void @objc_release(i8* %x) nounwind 559 ret void 560 } 561 562 ; Retain+release pairs in diamonds, all dominated by a retain. 563 564 ; CHECK: define void @test16( 565 ; CHECK: @objc_retain(i8* %x) 566 ; CHECK-NOT: @objc 567 ; CHECK: } 568 define void @test16(i1 %a, i1 %b, i8* %x) { 569 entry: 570 call i8* @objc_retain(i8* %x) nounwind 571 br i1 %a, label %red, label %orange 572 573 red: 574 call i8* @objc_retain(i8* %x) nounwind 575 br label %yellow 576 577 orange: 578 call i8* @objc_retain(i8* %x) nounwind 579 br label %yellow 580 581 yellow: 582 call void @use_pointer(i8* %x) 583 call void @use_pointer(i8* %x) 584 br i1 %b, label %green, label %blue 585 586 green: 587 call void @objc_release(i8* %x) nounwind 588 br label %purple 589 590 blue: 591 call void @objc_release(i8* %x) nounwind 592 br label %purple 593 594 purple: 595 ret void 596 } 597 598 ; Retain+release pairs in diamonds, all post-dominated by a release. 599 600 ; CHECK: define void @test17( 601 ; CHECK-NOT: @objc_ 602 ; CHECK: purple: 603 ; CHECK: @objc_release 604 ; CHECK: } 605 define void @test17(i1 %a, i1 %b, i8* %x) { 606 entry: 607 br i1 %a, label %red, label %orange 608 609 red: 610 call i8* @objc_retain(i8* %x) nounwind 611 br label %yellow 612 613 orange: 614 call i8* @objc_retain(i8* %x) nounwind 615 br label %yellow 616 617 yellow: 618 call void @use_pointer(i8* %x) 619 call void @use_pointer(i8* %x) 620 br i1 %b, label %green, label %blue 621 622 green: 623 call void @objc_release(i8* %x) nounwind 624 br label %purple 625 626 blue: 627 call void @objc_release(i8* %x) nounwind 628 br label %purple 629 630 purple: 631 call void @objc_release(i8* %x) nounwind 632 ret void 633 } 634 635 ; Delete no-ops. 636 637 ; CHECK: define void @test18( 638 ; CHECK-NOT: @objc_ 639 ; CHECK: } 640 define void @test18() { 641 call i8* @objc_retain(i8* null) 642 call void @objc_release(i8* null) 643 call i8* @objc_autorelease(i8* null) 644 ret void 645 } 646 647 ; Delete no-ops where undef can be assumed to be null. 648 649 ; CHECK: define void @test18b 650 ; CHECK-NOT: @objc_ 651 ; CHECK: } 652 define void @test18b() { 653 call i8* @objc_retain(i8* undef) 654 call void @objc_release(i8* undef) 655 call i8* @objc_autorelease(i8* undef) 656 ret void 657 } 658 659 ; Replace uses of arguments with uses of return values, to reduce 660 ; register pressure. 661 662 ; CHECK: define void @test19(i32* %y) { 663 ; CHECK: %z = bitcast i32* %y to i8* 664 ; CHECK: %0 = bitcast i32* %y to i8* 665 ; CHECK: %1 = tail call i8* @objc_retain(i8* %0) 666 ; CHECK: call void @use_pointer(i8* %z) 667 ; CHECK: call void @use_pointer(i8* %z) 668 ; CHECK: %2 = bitcast i32* %y to i8* 669 ; CHECK: call void @objc_release(i8* %2) 670 ; CHECK: ret void 671 ; CHECK: } 672 define void @test19(i32* %y) { 673 entry: 674 %x = bitcast i32* %y to i8* 675 %0 = call i8* @objc_retain(i8* %x) nounwind 676 %z = bitcast i32* %y to i8* 677 call void @use_pointer(i8* %z) 678 call void @use_pointer(i8* %z) 679 call void @objc_release(i8* %x) 680 ret void 681 } 682 683 ; Bitcast insertion 684 685 ; CHECK: define void @test20( 686 ; CHECK: %tmp1 = tail call i8* @objc_retain(i8* %tmp) nounwind 687 ; CHECK-NEXT: invoke 688 define void @test20(double* %self) { 689 if.then12: 690 %tmp = bitcast double* %self to i8* 691 %tmp1 = call i8* @objc_retain(i8* %tmp) nounwind 692 invoke void @invokee() 693 to label %invoke.cont23 unwind label %lpad20 694 695 invoke.cont23: ; preds = %if.then12 696 invoke void @invokee() 697 to label %if.end unwind label %lpad20 698 699 lpad20: ; preds = %invoke.cont23, %if.then12 700 %tmp502 = phi double* [ undef, %invoke.cont23 ], [ %self, %if.then12 ] 701 %exn = landingpad {i8*, i32} personality i32 (...)* @__gxx_personality_v0 702 cleanup 703 unreachable 704 705 if.end: ; preds = %invoke.cont23 706 ret void 707 } 708 709 ; Delete a redundant retain,autorelease when forwaring a call result 710 ; directly to a return value. 711 712 ; CHECK: define i8* @test21( 713 ; CHECK: call i8* @returner() 714 ; CHECK-NEXT: ret i8* %call 715 define i8* @test21() { 716 entry: 717 %call = call i8* @returner() 718 %0 = call i8* @objc_retain(i8* %call) nounwind 719 %1 = call i8* @objc_autorelease(i8* %0) nounwind 720 ret i8* %1 721 } 722 723 ; Move an objc call up through a phi that has null operands. 724 725 ; CHECK: define void @test22( 726 ; CHECK: B: 727 ; CHECK: %1 = bitcast double* %p to i8* 728 ; CHECK: call void @objc_release(i8* %1) 729 ; CHECK: br label %C 730 ; CHECK: C: ; preds = %B, %A 731 ; CHECK-NOT: @objc_release 732 ; CHECK: } 733 define void @test22(double* %p, i1 %a) { 734 br i1 %a, label %A, label %B 735 A: 736 br label %C 737 B: 738 br label %C 739 C: 740 %h = phi double* [ null, %A ], [ %p, %B ] 741 %c = bitcast double* %h to i8* 742 call void @objc_release(i8* %c) 743 ret void 744 } 745 746 ; Optimize objc_retainBlock. 747 748 ; CHECK: define void @test23( 749 ; CHECK-NOT: @objc_ 750 ; CHECK: } 751 %block0 = type { i64, i64, i8*, i8* } 752 %block1 = type { i8**, i32, i32, i32 (%struct.__block_literal_1*)*, %block0* } 753 %struct.__block_descriptor = type { i64, i64 } 754 %struct.__block_literal_1 = type { i8**, i32, i32, i8**, %struct.__block_descriptor* } 755 @__block_holder_tmp_1 = external constant %block1 756 define void @test23() { 757 entry: 758 %0 = call i8* @objc_retainBlock(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind 759 call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*)) 760 call void @bar(i32 ()* bitcast (%block1* @__block_holder_tmp_1 to i32 ()*)) 761 call void @objc_release(i8* bitcast (%block1* @__block_holder_tmp_1 to i8*)) nounwind 762 ret void 763 } 764 765 ; Don't optimize objc_retainBlock. 766 767 ; CHECK: define void @test23b 768 ; CHECK: @objc_retainBlock 769 ; CHECK: @objc_release 770 ; CHECK: } 771 define void @test23b(i8* %p) { 772 entry: 773 %0 = call i8* @objc_retainBlock(i8* %p) nounwind 774 call void @callee() 775 call void @use_pointer(i8* %p) 776 call void @objc_release(i8* %p) nounwind 777 ret void 778 } 779 780 ; Any call can decrement a retain count. 781 782 ; CHECK: define void @test24( 783 ; CHECK: @objc_retain(i8* %a) 784 ; CHECK: @objc_release 785 ; CHECK: } 786 define void @test24(i8* %r, i8* %a) { 787 call i8* @objc_retain(i8* %a) 788 call void @use_pointer(i8* %r) 789 %q = load i8* %a 790 call void @objc_release(i8* %a) 791 ret void 792 } 793 794 ; Don't move a retain/release pair if the release can be moved 795 ; but the retain can't be moved to balance it. 796 797 ; CHECK: define void @test25( 798 ; CHECK: entry: 799 ; CHECK: call i8* @objc_retain(i8* %p) 800 ; CHECK: true: 801 ; CHECK: done: 802 ; CHECK: call void @objc_release(i8* %p) 803 ; CHECK: } 804 define void @test25(i8* %p, i1 %x) { 805 entry: 806 %f0 = call i8* @objc_retain(i8* %p) 807 call void @callee() 808 br i1 %x, label %true, label %done 809 810 true: 811 store i8 0, i8* %p 812 br label %done 813 814 done: 815 call void @objc_release(i8* %p) 816 ret void 817 } 818 819 ; Don't move a retain/release pair if the retain can be moved 820 ; but the release can't be moved to balance it. 821 822 ; CHECK: define void @test26( 823 ; CHECK: entry: 824 ; CHECK: call i8* @objc_retain(i8* %p) 825 ; CHECK: true: 826 ; CHECK: done: 827 ; CHECK: call void @objc_release(i8* %p) 828 ; CHECK: } 829 define void @test26(i8* %p, i1 %x) { 830 entry: 831 %f0 = call i8* @objc_retain(i8* %p) 832 br i1 %x, label %true, label %done 833 834 true: 835 call void @callee() 836 br label %done 837 838 done: 839 store i8 0, i8* %p 840 call void @objc_release(i8* %p) 841 ret void 842 } 843 844 ; Don't sink the retain,release into the loop. 845 846 ; CHECK: define void @test27( 847 ; CHECK: entry: 848 ; CHECK: call i8* @objc_retain(i8* %p) 849 ; CHECK: loop: 850 ; CHECK-NOT: @objc_ 851 ; CHECK: done: 852 ; CHECK: call void @objc_release 853 ; CHECK: } 854 define void @test27(i8* %p, i1 %x, i1 %y) { 855 entry: 856 %f0 = call i8* @objc_retain(i8* %p) 857 br i1 %x, label %loop, label %done 858 859 loop: 860 call void @callee() 861 store i8 0, i8* %p 862 br i1 %y, label %done, label %loop 863 864 done: 865 call void @objc_release(i8* %p) 866 ret void 867 } 868 869 ; Trivial code motion case: Triangle. 870 871 ; CHECK: define void @test28( 872 ; CHECK-NOT: @objc_ 873 ; CHECK: true: 874 ; CHECK: call i8* @objc_retain( 875 ; CHECK: call void @callee() 876 ; CHECK: store 877 ; CHECK: call void @objc_release 878 ; CHECK: done: 879 ; CHECK-NOT: @objc_ 880 ; CHECK: } 881 define void @test28(i8* %p, i1 %x) { 882 entry: 883 %f0 = call i8* @objc_retain(i8* %p) 884 br i1 %x, label %true, label %done 885 886 true: 887 call void @callee() 888 store i8 0, i8* %p 889 br label %done 890 891 done: 892 call void @objc_release(i8* %p), !clang.imprecise_release !0 893 ret void 894 } 895 896 ; Trivial code motion case: Triangle, but no metadata. Don't move past 897 ; unrelated memory references! 898 899 ; CHECK: define void @test28b 900 ; CHECK: call i8* @objc_retain( 901 ; CHECK: true: 902 ; CHECK-NOT: @objc_ 903 ; CHECK: call void @callee() 904 ; CHECK-NOT: @objc_ 905 ; CHECK: store 906 ; CHECK-NOT: @objc_ 907 ; CHECK: done: 908 ; CHECK: @objc_release 909 ; CHECK: } 910 define void @test28b(i8* %p, i1 %x, i8* noalias %t) { 911 entry: 912 %f0 = call i8* @objc_retain(i8* %p) 913 br i1 %x, label %true, label %done 914 915 true: 916 call void @callee() 917 store i8 0, i8* %p 918 br label %done 919 920 done: 921 store i8 0, i8* %t 922 call void @objc_release(i8* %p) 923 ret void 924 } 925 926 ; Trivial code motion case: Triangle, with metadata. Do move past 927 ; unrelated memory references! And preserve the metadata. 928 929 ; CHECK: define void @test28c 930 ; CHECK-NOT: @objc_ 931 ; CHECK: true: 932 ; CHECK: call i8* @objc_retain( 933 ; CHECK: call void @callee() 934 ; CHECK: store 935 ; CHECK: call void @objc_release(i8* %p) nounwind, !clang.imprecise_release 936 ; CHECK: done: 937 ; CHECK-NOT: @objc_ 938 ; CHECK: } 939 define void @test28c(i8* %p, i1 %x, i8* noalias %t) { 940 entry: 941 %f0 = call i8* @objc_retain(i8* %p) 942 br i1 %x, label %true, label %done 943 944 true: 945 call void @callee() 946 store i8 0, i8* %p 947 br label %done 948 949 done: 950 store i8 0, i8* %t 951 call void @objc_release(i8* %p), !clang.imprecise_release !0 952 ret void 953 } 954 955 ; Like test28. but with two releases. 956 957 ; CHECK: define void @test29( 958 ; CHECK-NOT: @objc_ 959 ; CHECK: true: 960 ; CHECK: call i8* @objc_retain( 961 ; CHECK: call void @callee() 962 ; CHECK: store 963 ; CHECK: call void @objc_release 964 ; CHECK-NOT: @objc_release 965 ; CHECK: done: 966 ; CHECK-NOT: @objc_ 967 ; CHECK: ohno: 968 ; CHECK-NOT: @objc_ 969 ; CHECK: } 970 define void @test29(i8* %p, i1 %x, i1 %y) { 971 entry: 972 %f0 = call i8* @objc_retain(i8* %p) 973 br i1 %x, label %true, label %done 974 975 true: 976 call void @callee() 977 store i8 0, i8* %p 978 br i1 %y, label %done, label %ohno 979 980 done: 981 call void @objc_release(i8* %p) 982 ret void 983 984 ohno: 985 call void @objc_release(i8* %p) 986 ret void 987 } 988 989 ; Basic case with the use and call in a diamond 990 ; with an extra release. 991 992 ; CHECK: define void @test30( 993 ; CHECK-NOT: @objc_ 994 ; CHECK: true: 995 ; CHECK: call i8* @objc_retain( 996 ; CHECK: call void @callee() 997 ; CHECK: store 998 ; CHECK: call void @objc_release 999 ; CHECK-NOT: @objc_release 1000 ; CHECK: false: 1001 ; CHECK-NOT: @objc_ 1002 ; CHECK: done: 1003 ; CHECK-NOT: @objc_ 1004 ; CHECK: ohno: 1005 ; CHECK-NOT: @objc_ 1006 ; CHECK: } 1007 define void @test30(i8* %p, i1 %x, i1 %y, i1 %z) { 1008 entry: 1009 %f0 = call i8* @objc_retain(i8* %p) 1010 br i1 %x, label %true, label %false 1011 1012 true: 1013 call void @callee() 1014 store i8 0, i8* %p 1015 br i1 %y, label %done, label %ohno 1016 1017 false: 1018 br i1 %z, label %done, label %ohno 1019 1020 done: 1021 call void @objc_release(i8* %p) 1022 ret void 1023 1024 ohno: 1025 call void @objc_release(i8* %p) 1026 ret void 1027 } 1028 1029 ; Basic case with a mergeable release. 1030 1031 ; CHECK: define void @test31( 1032 ; CHECK: call i8* @objc_retain(i8* %p) 1033 ; CHECK: call void @callee() 1034 ; CHECK: store 1035 ; CHECK: call void @objc_release 1036 ; CHECK-NOT: @objc_release 1037 ; CHECK: true: 1038 ; CHECK-NOT: @objc_release 1039 ; CHECK: false: 1040 ; CHECK-NOT: @objc_release 1041 ; CHECK: ret void 1042 ; CHECK-NOT: @objc_release 1043 ; CHECK: } 1044 define void @test31(i8* %p, i1 %x) { 1045 entry: 1046 %f0 = call i8* @objc_retain(i8* %p) 1047 call void @callee() 1048 store i8 0, i8* %p 1049 br i1 %x, label %true, label %false 1050 true: 1051 call void @objc_release(i8* %p) 1052 ret void 1053 false: 1054 call void @objc_release(i8* %p) 1055 ret void 1056 } 1057 1058 ; Don't consider bitcasts or getelementptrs direct uses. 1059 1060 ; CHECK: define void @test32( 1061 ; CHECK-NOT: @objc_ 1062 ; CHECK: true: 1063 ; CHECK: call i8* @objc_retain( 1064 ; CHECK: call void @callee() 1065 ; CHECK: store 1066 ; CHECK: call void @objc_release 1067 ; CHECK: done: 1068 ; CHECK-NOT: @objc_ 1069 ; CHECK: } 1070 define void @test32(i8* %p, i1 %x) { 1071 entry: 1072 %f0 = call i8* @objc_retain(i8* %p) 1073 br i1 %x, label %true, label %done 1074 1075 true: 1076 call void @callee() 1077 store i8 0, i8* %p 1078 br label %done 1079 1080 done: 1081 %g = bitcast i8* %p to i8* 1082 %h = getelementptr i8* %g, i64 0 1083 call void @objc_release(i8* %g) 1084 ret void 1085 } 1086 1087 ; Do consider icmps to be direct uses. 1088 1089 ; CHECK: define void @test33( 1090 ; CHECK-NOT: @objc_ 1091 ; CHECK: true: 1092 ; CHECK: call i8* @objc_retain( 1093 ; CHECK: call void @callee() 1094 ; CHECK: icmp 1095 ; CHECK: call void @objc_release 1096 ; CHECK: done: 1097 ; CHECK-NOT: @objc_ 1098 ; CHECK: } 1099 define void @test33(i8* %p, i1 %x, i8* %y) { 1100 entry: 1101 %f0 = call i8* @objc_retain(i8* %p) 1102 br i1 %x, label %true, label %done 1103 1104 true: 1105 call void @callee() 1106 %v = icmp eq i8* %p, %y 1107 br label %done 1108 1109 done: 1110 %g = bitcast i8* %p to i8* 1111 %h = getelementptr i8* %g, i64 0 1112 call void @objc_release(i8* %g) 1113 ret void 1114 } 1115 1116 ; Delete retain,release if there's just a possible dec. 1117 1118 ; CHECK: define void @test34( 1119 ; CHECK-NOT: @objc_ 1120 ; CHECK: } 1121 define void @test34(i8* %p, i1 %x, i8* %y) { 1122 entry: 1123 %f0 = call i8* @objc_retain(i8* %p) 1124 br i1 %x, label %true, label %done 1125 1126 true: 1127 call void @callee() 1128 br label %done 1129 1130 done: 1131 %g = bitcast i8* %p to i8* 1132 %h = getelementptr i8* %g, i64 0 1133 call void @objc_release(i8* %g) 1134 ret void 1135 } 1136 1137 ; Delete retain,release if there's just a use. 1138 1139 ; CHECK: define void @test35( 1140 ; CHECK-NOT: @objc_ 1141 ; CHECK: } 1142 define void @test35(i8* %p, i1 %x, i8* %y) { 1143 entry: 1144 %f0 = call i8* @objc_retain(i8* %p) 1145 br i1 %x, label %true, label %done 1146 1147 true: 1148 %v = icmp eq i8* %p, %y 1149 br label %done 1150 1151 done: 1152 %g = bitcast i8* %p to i8* 1153 %h = getelementptr i8* %g, i64 0 1154 call void @objc_release(i8* %g) 1155 ret void 1156 } 1157 1158 ; Delete a retain,release if there's no actual use. 1159 1160 ; CHECK: define void @test36( 1161 ; CHECK-NOT: @objc_ 1162 ; CHECK: call void @callee() 1163 ; CHECK-NOT: @objc_ 1164 ; CHECK: call void @callee() 1165 ; CHECK-NOT: @objc_ 1166 ; CHECK: } 1167 define void @test36(i8* %p) { 1168 entry: 1169 call i8* @objc_retain(i8* %p) 1170 call void @callee() 1171 call void @callee() 1172 call void @objc_release(i8* %p) 1173 ret void 1174 } 1175 1176 ; Like test36, but with metadata. 1177 1178 ; CHECK: define void @test37( 1179 ; CHECK-NOT: @objc_ 1180 ; CHECK: } 1181 define void @test37(i8* %p) { 1182 entry: 1183 call i8* @objc_retain(i8* %p) 1184 call void @callee() 1185 call void @callee() 1186 call void @objc_release(i8* %p), !clang.imprecise_release !0 1187 ret void 1188 } 1189 1190 ; Be aggressive about analyzing phis to eliminate possible uses. 1191 1192 ; CHECK: define void @test38( 1193 ; CHECK-NOT: @objc_ 1194 ; CHECK: } 1195 define void @test38(i8* %p, i1 %u, i1 %m, i8* %z, i8* %y, i8* %x, i8* %w) { 1196 entry: 1197 call i8* @objc_retain(i8* %p) 1198 br i1 %u, label %true, label %false 1199 true: 1200 br i1 %m, label %a, label %b 1201 false: 1202 br i1 %m, label %c, label %d 1203 a: 1204 br label %e 1205 b: 1206 br label %e 1207 c: 1208 br label %f 1209 d: 1210 br label %f 1211 e: 1212 %j = phi i8* [ %z, %a ], [ %y, %b ] 1213 br label %g 1214 f: 1215 %k = phi i8* [ %w, %c ], [ %x, %d ] 1216 br label %g 1217 g: 1218 %h = phi i8* [ %j, %e ], [ %k, %f ] 1219 call void @use_pointer(i8* %h) 1220 call void @objc_release(i8* %p), !clang.imprecise_release !0 1221 ret void 1222 } 1223 1224 ; Delete retain,release pairs around loops. 1225 1226 ; CHECK: define void @test39( 1227 ; CHECK_NOT: @objc_ 1228 ; CHECK: } 1229 define void @test39(i8* %p) { 1230 entry: 1231 %0 = call i8* @objc_retain(i8* %p) 1232 br label %loop 1233 1234 loop: ; preds = %loop, %entry 1235 br i1 undef, label %loop, label %exit 1236 1237 exit: ; preds = %loop 1238 call void @objc_release(i8* %0), !clang.imprecise_release !0 1239 ret void 1240 } 1241 1242 ; Delete retain,release pairs around loops containing uses. 1243 1244 ; CHECK: define void @test39b( 1245 ; CHECK_NOT: @objc_ 1246 ; CHECK: } 1247 define void @test39b(i8* %p) { 1248 entry: 1249 %0 = call i8* @objc_retain(i8* %p) 1250 br label %loop 1251 1252 loop: ; preds = %loop, %entry 1253 store i8 0, i8* %0 1254 br i1 undef, label %loop, label %exit 1255 1256 exit: ; preds = %loop 1257 call void @objc_release(i8* %0), !clang.imprecise_release !0 1258 ret void 1259 } 1260 1261 ; Delete retain,release pairs around loops containing potential decrements. 1262 1263 ; CHECK: define void @test39c( 1264 ; CHECK_NOT: @objc_ 1265 ; CHECK: } 1266 define void @test39c(i8* %p) { 1267 entry: 1268 %0 = call i8* @objc_retain(i8* %p) 1269 br label %loop 1270 1271 loop: ; preds = %loop, %entry 1272 call void @use_pointer(i8* %0) 1273 br i1 undef, label %loop, label %exit 1274 1275 exit: ; preds = %loop 1276 call void @objc_release(i8* %0), !clang.imprecise_release !0 1277 ret void 1278 } 1279 1280 ; Delete retain,release pairs around loops even if 1281 ; the successors are in a different order. 1282 1283 ; CHECK: define void @test40( 1284 ; CHECK_NOT: @objc_ 1285 ; CHECK: } 1286 define void @test40(i8* %p) { 1287 entry: 1288 %0 = call i8* @objc_retain(i8* %p) 1289 br label %loop 1290 1291 loop: ; preds = %loop, %entry 1292 call void @use_pointer(i8* %0) 1293 br i1 undef, label %exit, label %loop 1294 1295 exit: ; preds = %loop 1296 call void @objc_release(i8* %0), !clang.imprecise_release !0 1297 ret void 1298 } 1299 1300 ; Do the known-incremented retain+release elimination even if the pointer 1301 ; is also autoreleased. 1302 1303 ; CHECK: define void @test42( 1304 ; CHECK-NEXT: entry: 1305 ; CHECK-NEXT: call i8* @objc_retain(i8* %p) 1306 ; CHECK-NEXT: call i8* @objc_autorelease(i8* %p) 1307 ; CHECK-NEXT: call void @use_pointer(i8* %p) 1308 ; CHECK-NEXT: call void @use_pointer(i8* %p) 1309 ; CHECK-NEXT: ret void 1310 ; CHECK-NEXT: } 1311 define void @test42(i8* %p) { 1312 entry: 1313 call i8* @objc_retain(i8* %p) 1314 call i8* @objc_autorelease(i8* %p) 1315 call i8* @objc_retain(i8* %p) 1316 call void @use_pointer(i8* %p) 1317 call void @use_pointer(i8* %p) 1318 call void @objc_release(i8* %p) 1319 ret void 1320 } 1321 1322 ; Don't the known-incremented retain+release elimination if the pointer is 1323 ; autoreleased and there's an autoreleasePoolPop. 1324 1325 ; CHECK: define void @test43( 1326 ; CHECK-NEXT: entry: 1327 ; CHECK-NEXT: call i8* @objc_retain(i8* %p) 1328 ; CHECK-NEXT: call i8* @objc_autorelease(i8* %p) 1329 ; CHECK-NEXT: call i8* @objc_retain 1330 ; CHECK-NEXT: call void @use_pointer(i8* %p) 1331 ; CHECK-NEXT: call void @use_pointer(i8* %p) 1332 ; CHECK-NEXT: call void @objc_autoreleasePoolPop(i8* undef) 1333 ; CHECK-NEXT: call void @objc_release 1334 ; CHECK-NEXT: ret void 1335 ; CHECK-NEXT: } 1336 define void @test43(i8* %p) { 1337 entry: 1338 call i8* @objc_retain(i8* %p) 1339 call i8* @objc_autorelease(i8* %p) 1340 call i8* @objc_retain(i8* %p) 1341 call void @use_pointer(i8* %p) 1342 call void @use_pointer(i8* %p) 1343 call void @objc_autoreleasePoolPop(i8* undef) 1344 call void @objc_release(i8* %p) 1345 ret void 1346 } 1347 1348 ; Do the known-incremented retain+release elimination if the pointer is 1349 ; autoreleased and there's an autoreleasePoolPush. 1350 1351 ; CHECK: define void @test43b 1352 ; CHECK-NEXT: entry: 1353 ; CHECK-NEXT: call i8* @objc_retain(i8* %p) 1354 ; CHECK-NEXT: call i8* @objc_autorelease(i8* %p) 1355 ; CHECK-NEXT: call void @use_pointer(i8* %p) 1356 ; CHECK-NEXT: call void @use_pointer(i8* %p) 1357 ; CHECK-NEXT: call void @objc_autoreleasePoolPush() 1358 ; CHECK-NEXT: ret void 1359 ; CHECK-NEXT: } 1360 define void @test43b(i8* %p) { 1361 entry: 1362 call i8* @objc_retain(i8* %p) 1363 call i8* @objc_autorelease(i8* %p) 1364 call i8* @objc_retain(i8* %p) 1365 call void @use_pointer(i8* %p) 1366 call void @use_pointer(i8* %p) 1367 call void @objc_autoreleasePoolPush() 1368 call void @objc_release(i8* %p) 1369 ret void 1370 } 1371 1372 ; Do retain+release elimination for non-provenance pointers. 1373 1374 ; CHECK: define void @test44( 1375 ; CHECK-NOT: objc_ 1376 ; CHECK: } 1377 define void @test44(i8** %pp) { 1378 %p = load i8** %pp 1379 %q = call i8* @objc_retain(i8* %p) 1380 call void @objc_release(i8* %q) 1381 ret void 1382 } 1383 1384 ; Don't delete retain+release with an unknown-provenance 1385 ; may-alias objc_release between them. 1386 1387 ; CHECK: define void @test45( 1388 ; CHECK: call i8* @objc_retain(i8* %p) 1389 ; CHECK: call void @objc_release(i8* %q) 1390 ; CHECK: call void @use_pointer(i8* %p) 1391 ; CHECK: call void @objc_release(i8* %p) 1392 define void @test45(i8** %pp, i8** %qq) { 1393 %p = load i8** %pp 1394 %q = load i8** %qq 1395 call i8* @objc_retain(i8* %p) 1396 call void @objc_release(i8* %q) 1397 call void @use_pointer(i8* %p) 1398 call void @objc_release(i8* %p) 1399 ret void 1400 } 1401 1402 ; Don't delete retain and autorelease here. 1403 1404 ; CHECK: define void @test46( 1405 ; CHECK: tail call i8* @objc_retain(i8* %p) nounwind 1406 ; CHECK: true: 1407 ; CHECK: tail call i8* @objc_autorelease(i8* %p) nounwind 1408 define void @test46(i8* %p, i1 %a) { 1409 entry: 1410 call i8* @objc_retain(i8* %p) 1411 br i1 %a, label %true, label %false 1412 1413 true: 1414 call i8* @objc_autorelease(i8* %p) 1415 call void @use_pointer(i8* %p) 1416 ret void 1417 1418 false: 1419 ret void 1420 } 1421 1422 ; Delete no-op cast calls. 1423 1424 ; CHECK: define i8* @test47( 1425 ; CHECK-NOT: call 1426 ; CHECK: ret i8* %p 1427 define i8* @test47(i8* %p) nounwind { 1428 %x = call i8* @objc_retainedObject(i8* %p) 1429 ret i8* %x 1430 } 1431 1432 ; Delete no-op cast calls. 1433 1434 ; CHECK: define i8* @test48( 1435 ; CHECK-NOT: call 1436 ; CHECK: ret i8* %p 1437 define i8* @test48(i8* %p) nounwind { 1438 %x = call i8* @objc_unretainedObject(i8* %p) 1439 ret i8* %x 1440 } 1441 1442 ; Delete no-op cast calls. 1443 1444 ; CHECK: define i8* @test49( 1445 ; CHECK-NOT: call 1446 ; CHECK: ret i8* %p 1447 define i8* @test49(i8* %p) nounwind { 1448 %x = call i8* @objc_unretainedPointer(i8* %p) 1449 ret i8* %x 1450 } 1451 1452 ; Do delete retain+release with intervening stores of the 1453 ; address value; 1454 1455 ; CHECK: define void @test50( 1456 ; CHECK-NOT: @objc_ 1457 ; CHECK: } 1458 define void @test50(i8* %p, i8** %pp) { 1459 call i8* @objc_retain(i8* %p) 1460 call void @callee() 1461 store i8* %p, i8** %pp 1462 call void @objc_release(i8* %p) 1463 ret void 1464 } 1465 1466 ; Don't delete retain+release with intervening stores through the 1467 ; address value. 1468 1469 ; CHECK: define void @test51( 1470 ; CHECK: call i8* @objc_retain(i8* %p) 1471 ; CHECK: call void @objc_release(i8* %p) 1472 define void @test51(i8* %p) { 1473 call i8* @objc_retain(i8* %p) 1474 call void @callee() 1475 store i8 0, i8* %p 1476 call void @objc_release(i8* %p) 1477 ret void 1478 } 1479 1480 ; Don't delete retain+release with intervening use of a pointer of 1481 ; unknown provenance. 1482 1483 ; CHECK: define void @test52( 1484 ; CHECK: call i8* @objc_retain 1485 ; CHECK: call void @callee() 1486 ; CHECK: call void @use_pointer(i8* %z) 1487 ; CHECK: call void @objc_release 1488 define void @test52(i8** %zz, i8** %pp) { 1489 %p = load i8** %pp 1490 %1 = call i8* @objc_retain(i8* %p) 1491 call void @callee() 1492 %z = load i8** %zz 1493 call void @use_pointer(i8* %z) 1494 call void @objc_release(i8* %p) 1495 ret void 1496 } 1497 1498 ; Like test52, but the pointer has function type, so it's assumed to 1499 ; be not reference counted. 1500 1501 ; CHECK: define void @test53( 1502 ; CHECK-NOT: @objc_ 1503 ; CHECK: } 1504 define void @test53(void ()** %zz, i8** %pp) { 1505 %p = load i8** %pp 1506 %1 = call i8* @objc_retain(i8* %p) 1507 call void @callee() 1508 %z = load void ()** %zz 1509 call void @callee_fnptr(void ()* %z) 1510 call void @objc_release(i8* %p) 1511 ret void 1512 } 1513 1514 ; Convert autorelease to release if the value is unused. 1515 1516 ; CHECK: define void @test54( 1517 ; CHECK: call i8* @returner() 1518 ; CHECK-NEXT: call void @objc_release(i8* %t) nounwind, !clang.imprecise_release !0 1519 ; CHECK-NEXT: ret void 1520 define void @test54() { 1521 %t = call i8* @returner() 1522 call i8* @objc_autorelease(i8* %t) 1523 ret void 1524 } 1525 1526 ; Nested retain+release pairs. Delete them both. 1527 1528 ; CHECK: define void @test55( 1529 ; CHECK-NOT: @objc 1530 ; CHECK: } 1531 define void @test55(i8* %x) { 1532 entry: 1533 %0 = call i8* @objc_retain(i8* %x) nounwind 1534 %1 = call i8* @objc_retain(i8* %x) nounwind 1535 call void @objc_release(i8* %x) nounwind 1536 call void @objc_release(i8* %x) nounwind 1537 ret void 1538 } 1539 1540 ; Nested retain+release pairs where the inner pair depends 1541 ; on the outer pair to be removed, and then the outer pair 1542 ; can be partially eliminated. Plus an extra outer pair to 1543 ; eliminate, for fun. 1544 1545 ; CHECK: define void @test56( 1546 ; CHECK-NOT: @objc 1547 ; CHECK: if.then: 1548 ; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind 1549 ; CHECK-NEXT: tail call void @use_pointer(i8* %x) 1550 ; CHECK-NEXT: tail call void @use_pointer(i8* %x) 1551 ; CHECK-NEXT: tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 1552 ; CHECK-NEXT: br label %if.end 1553 ; CHECK-NOT: @objc 1554 ; CHECK: } 1555 define void @test56(i8* %x, i32 %n) { 1556 entry: 1557 %0 = tail call i8* @objc_retain(i8* %x) nounwind 1558 %1 = tail call i8* @objc_retain(i8* %0) nounwind 1559 %tobool = icmp eq i32 %n, 0 1560 br i1 %tobool, label %if.end, label %if.then 1561 1562 if.then: ; preds = %entry 1563 %2 = tail call i8* @objc_retain(i8* %1) nounwind 1564 tail call void @use_pointer(i8* %2) 1565 tail call void @use_pointer(i8* %2) 1566 tail call void @objc_release(i8* %2) nounwind, !clang.imprecise_release !0 1567 br label %if.end 1568 1569 if.end: ; preds = %entry, %if.then 1570 tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0 1571 tail call void @objc_release(i8* %0) nounwind, !clang.imprecise_release !0 1572 ret void 1573 } 1574 1575 ; When there are adjacent retain+release pairs, the first one is 1576 ; known unnecessary because the presence of the second one means that 1577 ; the first one won't be deleting the object. 1578 1579 ; CHECK: define void @test57( 1580 ; CHECK-NEXT: entry: 1581 ; CHECK-NEXT: call void @use_pointer(i8* %x) 1582 ; CHECK-NEXT: call void @use_pointer(i8* %x) 1583 ; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind 1584 ; CHECK-NEXT: call void @use_pointer(i8* %x) 1585 ; CHECK-NEXT: call void @use_pointer(i8* %x) 1586 ; CHECK-NEXT: call void @objc_release(i8* %x) nounwind 1587 ; CHECK-NEXT: ret void 1588 ; CHECK-NEXT: } 1589 define void @test57(i8* %x) nounwind { 1590 entry: 1591 call i8* @objc_retain(i8* %x) nounwind 1592 call void @use_pointer(i8* %x) 1593 call void @use_pointer(i8* %x) 1594 call void @objc_release(i8* %x) nounwind 1595 call i8* @objc_retain(i8* %x) nounwind 1596 call void @use_pointer(i8* %x) 1597 call void @use_pointer(i8* %x) 1598 call void @objc_release(i8* %x) nounwind 1599 ret void 1600 } 1601 1602 ; An adjacent retain+release pair is sufficient even if it will be 1603 ; removed itself. 1604 1605 ; CHECK: define void @test58( 1606 ; CHECK-NEXT: entry: 1607 ; CHECK-NEXT: call void @use_pointer(i8* %x) 1608 ; CHECK-NEXT: call void @use_pointer(i8* %x) 1609 ; CHECK-NEXT: ret void 1610 ; CHECK-NEXT: } 1611 define void @test58(i8* %x) nounwind { 1612 entry: 1613 call i8* @objc_retain(i8* %x) nounwind 1614 call void @use_pointer(i8* %x) 1615 call void @use_pointer(i8* %x) 1616 call void @objc_release(i8* %x) nounwind 1617 call i8* @objc_retain(i8* %x) nounwind 1618 call void @objc_release(i8* %x) nounwind 1619 ret void 1620 } 1621 1622 ; Don't delete the second retain+release pair in an adjacent set. 1623 1624 ; CHECK: define void @test59( 1625 ; CHECK-NEXT: entry: 1626 ; CHECK-NEXT: %0 = tail call i8* @objc_retain(i8* %x) nounwind 1627 ; CHECK-NEXT: call void @use_pointer(i8* %x) 1628 ; CHECK-NEXT: call void @use_pointer(i8* %x) 1629 ; CHECK-NEXT: call void @objc_release(i8* %x) nounwind 1630 ; CHECK-NEXT: ret void 1631 ; CHECK-NEXT: } 1632 define void @test59(i8* %x) nounwind { 1633 entry: 1634 %a = call i8* @objc_retain(i8* %x) nounwind 1635 call void @objc_release(i8* %x) nounwind 1636 %b = call i8* @objc_retain(i8* %x) nounwind 1637 call void @use_pointer(i8* %x) 1638 call void @use_pointer(i8* %x) 1639 call void @objc_release(i8* %x) nounwind 1640 ret void 1641 } 1642 1643 ; Constant pointers to objects don't need reference counting. 1644 1645 @constptr = external constant i8* 1646 @something = external global i8* 1647 1648 ; CHECK: define void @test60( 1649 ; CHECK-NOT: @objc_ 1650 ; CHECK: } 1651 define void @test60() { 1652 %t = load i8** @constptr 1653 %s = load i8** @something 1654 call i8* @objc_retain(i8* %s) 1655 call void @callee() 1656 call void @use_pointer(i8* %t) 1657 call void @objc_release(i8* %s) 1658 ret void 1659 } 1660 1661 ; Constant pointers to objects don't need to be considered related to other 1662 ; pointers. 1663 1664 ; CHECK: define void @test61( 1665 ; CHECK-NOT: @objc_ 1666 ; CHECK: } 1667 define void @test61() { 1668 %t = load i8** @constptr 1669 call i8* @objc_retain(i8* %t) 1670 call void @callee() 1671 call void @use_pointer(i8* %t) 1672 call void @objc_release(i8* %t) 1673 ret void 1674 } 1675 1676 declare void @bar(i32 ()*) 1677 1678 ; A few real-world testcases. 1679 1680 @.str4 = private unnamed_addr constant [33 x i8] c"-[A z] = { %f, %f, { %f, %f } }\0A\00" 1681 @"OBJC_IVAR_$_A.myZ" = global i64 20, section "__DATA, __objc_const", align 8 1682 declare i32 @printf(i8* nocapture, ...) nounwind 1683 declare i32 @puts(i8* nocapture) nounwind 1684 @str = internal constant [16 x i8] c"-[ Top0 _getX ]\00" 1685 1686 ; CHECK: @"\01-[A z]" 1687 ; CHECK-NOT: @objc_ 1688 ; CHECK: } 1689 1690 define {<2 x float>, <2 x float>} @"\01-[A z]"({}* %self, i8* nocapture %_cmd) nounwind { 1691 invoke.cont: 1692 %0 = bitcast {}* %self to i8* 1693 %1 = tail call i8* @objc_retain(i8* %0) nounwind 1694 tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0) 1695 tail call void @llvm.dbg.value(metadata !{{}* %self}, i64 0, metadata !0) 1696 %ivar = load i64* @"OBJC_IVAR_$_A.myZ", align 8 1697 %add.ptr = getelementptr i8* %0, i64 %ivar 1698 %tmp1 = bitcast i8* %add.ptr to float* 1699 %tmp2 = load float* %tmp1, align 4 1700 %conv = fpext float %tmp2 to double 1701 %add.ptr.sum = add i64 %ivar, 4 1702 %tmp6 = getelementptr inbounds i8* %0, i64 %add.ptr.sum 1703 %2 = bitcast i8* %tmp6 to float* 1704 %tmp7 = load float* %2, align 4 1705 %conv8 = fpext float %tmp7 to double 1706 %add.ptr.sum36 = add i64 %ivar, 8 1707 %tmp12 = getelementptr inbounds i8* %0, i64 %add.ptr.sum36 1708 %arrayidx = bitcast i8* %tmp12 to float* 1709 %tmp13 = load float* %arrayidx, align 4 1710 %conv14 = fpext float %tmp13 to double 1711 %tmp12.sum = add i64 %ivar, 12 1712 %arrayidx19 = getelementptr inbounds i8* %0, i64 %tmp12.sum 1713 %3 = bitcast i8* %arrayidx19 to float* 1714 %tmp20 = load float* %3, align 4 1715 %conv21 = fpext float %tmp20 to double 1716 %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([33 x i8]* @.str4, i64 0, i64 0), double %conv, double %conv8, double %conv14, double %conv21) 1717 %ivar23 = load i64* @"OBJC_IVAR_$_A.myZ", align 8 1718 %add.ptr24 = getelementptr i8* %0, i64 %ivar23 1719 %4 = bitcast i8* %add.ptr24 to i128* 1720 %srcval = load i128* %4, align 4 1721 tail call void @objc_release(i8* %0) nounwind 1722 %tmp29 = trunc i128 %srcval to i64 1723 %tmp30 = bitcast i64 %tmp29 to <2 x float> 1724 %tmp31 = insertvalue {<2 x float>, <2 x float>} undef, <2 x float> %tmp30, 0 1725 %tmp32 = lshr i128 %srcval, 64 1726 %tmp33 = trunc i128 %tmp32 to i64 1727 %tmp34 = bitcast i64 %tmp33 to <2 x float> 1728 %tmp35 = insertvalue {<2 x float>, <2 x float>} %tmp31, <2 x float> %tmp34, 1 1729 ret {<2 x float>, <2 x float>} %tmp35 1730 } 1731 1732 ; CHECK: @"\01-[Top0 _getX]" 1733 ; CHECK-NOT: @objc_ 1734 ; CHECK: } 1735 1736 define i32 @"\01-[Top0 _getX]"({}* %self, i8* nocapture %_cmd) nounwind { 1737 invoke.cont: 1738 %0 = bitcast {}* %self to i8* 1739 %1 = tail call i8* @objc_retain(i8* %0) nounwind 1740 %puts = tail call i32 @puts(i8* getelementptr inbounds ([16 x i8]* @str, i64 0, i64 0)) 1741 tail call void @objc_release(i8* %0) nounwind 1742 ret i32 0 1743 } 1744 1745 @"\01L_OBJC_METH_VAR_NAME_" = internal global [5 x i8] c"frob\00", section "__TEXT,__cstring,cstring_literals", align 1@"\01L_OBJC_SELECTOR_REFERENCES_" = internal global i8* getelementptr inbounds ([5 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i64 0, i64 0), section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1746 @"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] [i32 0, i32 16], section "__DATA, __objc_imageinfo, regular, no_dead_strip" 1747 @llvm.used = appending global [3 x i8*] [i8* getelementptr inbounds ([5 x i8]* @"\01L_OBJC_METH_VAR_NAME_", i32 0, i32 0), i8* bitcast (i8** @"\01L_OBJC_SELECTOR_REFERENCES_" to i8*), i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*)], section "llvm.metadata" 1748 1749 ; A simple loop. Eliminate the retain and release inside of it! 1750 1751 ; CHECK: define void @loop 1752 ; CHECK: for.body: 1753 ; CHECK-NOT: @objc_ 1754 ; CHECK: @objc_msgSend 1755 ; CHECK-NOT: @objc_ 1756 ; CHECK: for.end: 1757 define void @loop(i8* %x, i64 %n) { 1758 entry: 1759 %0 = tail call i8* @objc_retain(i8* %x) nounwind 1760 %cmp9 = icmp sgt i64 %n, 0 1761 br i1 %cmp9, label %for.body, label %for.end 1762 1763 for.body: ; preds = %entry, %for.body 1764 %i.010 = phi i64 [ %inc, %for.body ], [ 0, %entry ] 1765 %1 = tail call i8* @objc_retain(i8* %x) nounwind 1766 %tmp5 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_", align 8 1767 %call = tail call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %1, i8* %tmp5) 1768 tail call void @objc_release(i8* %1) nounwind, !clang.imprecise_release !0 1769 %inc = add nsw i64 %i.010, 1 1770 %exitcond = icmp eq i64 %inc, %n 1771 br i1 %exitcond, label %for.end, label %for.body 1772 1773 for.end: ; preds = %for.body, %entry 1774 tail call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0 1775 ret void 1776 } 1777 1778 ; ObjCARCOpt can delete the retain,release on self. 1779 1780 ; CHECK: define void @TextEditTest 1781 ; CHECK-NOT: call i8* @objc_retain(i8* %tmp7) 1782 ; CHECK: } 1783 1784 %0 = type { i8* (i8*, %struct._message_ref_t*, ...)*, i8* } 1785 %1 = type opaque 1786 %2 = type opaque 1787 %3 = type opaque 1788 %4 = type opaque 1789 %5 = type opaque 1790 %struct.NSConstantString = type { i32*, i32, i8*, i64 } 1791 %struct._NSRange = type { i64, i64 } 1792 %struct.__CFString = type opaque 1793 %struct.__method_list_t = type { i32, i32, [0 x %struct._objc_method] } 1794 %struct._class_ro_t = type { i32, i32, i32, i8*, i8*, %struct.__method_list_t*, %struct._objc_protocol_list*, %struct._ivar_list_t*, i8*, %struct._prop_list_t* } 1795 %struct._class_t = type { %struct._class_t*, %struct._class_t*, %struct._objc_cache*, i8* (i8*, i8*)**, %struct._class_ro_t* } 1796 %struct._ivar_list_t = type { i32, i32, [0 x %struct._ivar_t] } 1797 %struct._ivar_t = type { i64*, i8*, i8*, i32, i32 } 1798 %struct._message_ref_t = type { i8*, i8* } 1799 %struct._objc_cache = type opaque 1800 %struct._objc_method = type { i8*, i8*, i8* } 1801 %struct._objc_protocol_list = type { i64, [0 x %struct._protocol_t*] } 1802 %struct._prop_list_t = type { i32, i32, [0 x %struct._message_ref_t] } 1803 %struct._protocol_t = type { i8*, i8*, %struct._objc_protocol_list*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct.__method_list_t*, %struct._prop_list_t*, i32, i32 } 1804 1805 @"\01L_OBJC_CLASSLIST_REFERENCES_$_17" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 1806 @kUTTypePlainText = external constant %struct.__CFString* 1807 @"\01L_OBJC_SELECTOR_REFERENCES_19" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1808 @"\01L_OBJC_SELECTOR_REFERENCES_21" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1809 @"\01L_OBJC_SELECTOR_REFERENCES_23" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1810 @"\01L_OBJC_SELECTOR_REFERENCES_25" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1811 @"\01L_OBJC_CLASSLIST_REFERENCES_$_26" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 1812 @"\01L_OBJC_SELECTOR_REFERENCES_28" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1813 @"\01L_OBJC_CLASSLIST_REFERENCES_$_29" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 1814 @"\01L_OBJC_SELECTOR_REFERENCES_31" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1815 @"\01L_OBJC_SELECTOR_REFERENCES_33" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1816 @"\01L_OBJC_SELECTOR_REFERENCES_35" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1817 @"\01L_OBJC_SELECTOR_REFERENCES_37" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1818 @"\01L_OBJC_CLASSLIST_REFERENCES_$_38" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 1819 @"\01L_OBJC_SELECTOR_REFERENCES_40" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1820 @"\01L_OBJC_SELECTOR_REFERENCES_42" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1821 @_unnamed_cfstring_44 = external hidden constant %struct.NSConstantString, section "__DATA,__cfstring" 1822 @"\01L_OBJC_SELECTOR_REFERENCES_46" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1823 @"\01L_OBJC_SELECTOR_REFERENCES_48" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1824 @"\01l_objc_msgSend_fixup_isEqual_" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16 1825 @"\01L_OBJC_CLASSLIST_REFERENCES_$_50" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 1826 @NSCocoaErrorDomain = external constant %1* 1827 @"\01L_OBJC_CLASSLIST_REFERENCES_$_51" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 1828 @NSFilePathErrorKey = external constant %1* 1829 @"\01L_OBJC_SELECTOR_REFERENCES_53" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1830 @"\01L_OBJC_SELECTOR_REFERENCES_55" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1831 @"\01L_OBJC_CLASSLIST_REFERENCES_$_56" = external hidden global %struct._class_t*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 1832 @"\01L_OBJC_SELECTOR_REFERENCES_58" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1833 @"\01L_OBJC_SELECTOR_REFERENCES_60" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 1834 1835 declare %1* @truncatedString(%1*, i64) 1836 define void @TextEditTest(%2* %self, %3* %pboard) { 1837 entry: 1838 %err = alloca %4*, align 8 1839 %tmp7 = bitcast %2* %self to i8* 1840 %tmp8 = call i8* @objc_retain(i8* %tmp7) nounwind 1841 store %4* null, %4** %err, align 8 1842 %tmp1 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_17", align 8 1843 %tmp2 = load %struct.__CFString** @kUTTypePlainText, align 8 1844 %tmp3 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_19", align 8 1845 %tmp4 = bitcast %struct._class_t* %tmp1 to i8* 1846 %call5 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp4, i8* %tmp3, %struct.__CFString* %tmp2) 1847 %tmp5 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_21", align 8 1848 %tmp6 = bitcast %3* %pboard to i8* 1849 %call76 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp6, i8* %tmp5, i8* %call5) 1850 %tmp9 = call i8* @objc_retain(i8* %call76) nounwind 1851 %tobool = icmp eq i8* %tmp9, null 1852 br i1 %tobool, label %end, label %land.lhs.true 1853 1854 land.lhs.true: ; preds = %entry 1855 %tmp11 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_23", align 8 1856 %call137 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp6, i8* %tmp11, i8* %tmp9) 1857 %tmp = bitcast i8* %call137 to %1* 1858 %tmp10 = call i8* @objc_retain(i8* %call137) nounwind 1859 call void @objc_release(i8* null) nounwind 1860 %tmp12 = call i8* @objc_retain(i8* %call137) nounwind 1861 call void @objc_release(i8* null) nounwind 1862 %tobool16 = icmp eq i8* %call137, null 1863 br i1 %tobool16, label %end, label %if.then 1864 1865 if.then: ; preds = %land.lhs.true 1866 %tmp19 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8 1867 %call21 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %call137, i8* %tmp19) 1868 %tobool22 = icmp eq i8 %call21, 0 1869 br i1 %tobool22, label %if.then44, label %land.lhs.true23 1870 1871 land.lhs.true23: ; preds = %if.then 1872 %tmp24 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8 1873 %tmp26 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8 1874 %tmp27 = bitcast %struct._class_t* %tmp24 to i8* 1875 %call2822 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp27, i8* %tmp26, i8* %call137) 1876 %tmp13 = bitcast i8* %call2822 to %5* 1877 %tmp14 = call i8* @objc_retain(i8* %call2822) nounwind 1878 call void @objc_release(i8* null) nounwind 1879 %tobool30 = icmp eq i8* %call2822, null 1880 br i1 %tobool30, label %if.then44, label %if.end 1881 1882 if.end: ; preds = %land.lhs.true23 1883 %tmp32 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8 1884 %tmp33 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8 1885 %tmp34 = bitcast %struct._class_t* %tmp32 to i8* 1886 %call35 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp34, i8* %tmp33) 1887 %tmp37 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8 1888 %call3923 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call35, i8* %tmp37, i8* %call2822, i32 signext 1, %4** %err) 1889 %cmp = icmp eq i8* %call3923, null 1890 br i1 %cmp, label %if.then44, label %end 1891 1892 if.then44: ; preds = %if.end, %land.lhs.true23, %if.then 1893 %url.025 = phi %5* [ %tmp13, %if.end ], [ %tmp13, %land.lhs.true23 ], [ null, %if.then ] 1894 %tmp49 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_35", align 8 1895 %call51 = call %struct._NSRange bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %struct._NSRange (i8*, i8*, i64, i64)*)(i8* %call137, i8* %tmp49, i64 0, i64 0) 1896 %call513 = extractvalue %struct._NSRange %call51, 0 1897 %call514 = extractvalue %struct._NSRange %call51, 1 1898 %tmp52 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_37", align 8 1899 %call548 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call137, i8* %tmp52, i64 %call513, i64 %call514) 1900 %tmp55 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_38", align 8 1901 %tmp56 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_40", align 8 1902 %tmp57 = bitcast %struct._class_t* %tmp55 to i8* 1903 %call58 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp57, i8* %tmp56) 1904 %tmp59 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_42", align 8 1905 %call6110 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call548, i8* %tmp59, i8* %call58) 1906 %tmp15 = call i8* @objc_retain(i8* %call6110) nounwind 1907 call void @objc_release(i8* %call137) nounwind 1908 %tmp64 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_46", align 8 1909 %call66 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*, %1*)*)(i8* %call6110, i8* %tmp64, %1* bitcast (%struct.NSConstantString* @_unnamed_cfstring_44 to %1*)) 1910 %tobool67 = icmp eq i8 %call66, 0 1911 br i1 %tobool67, label %if.end74, label %if.then68 1912 1913 if.then68: ; preds = %if.then44 1914 %tmp70 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_48", align 8 1915 %call7220 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call6110, i8* %tmp70) 1916 %tmp16 = call i8* @objc_retain(i8* %call7220) nounwind 1917 call void @objc_release(i8* %call6110) nounwind 1918 br label %if.end74 1919 1920 if.end74: ; preds = %if.then68, %if.then44 1921 %filename.0.in = phi i8* [ %call7220, %if.then68 ], [ %call6110, %if.then44 ] 1922 %filename.0 = bitcast i8* %filename.0.in to %1* 1923 %tmp17 = load i8** bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to i8**), align 16 1924 %tmp18 = bitcast i8* %tmp17 to i8 (i8*, %struct._message_ref_t*, i8*, ...)* 1925 %call78 = call signext i8 (i8*, %struct._message_ref_t*, i8*, ...)* %tmp18(i8* %call137, %struct._message_ref_t* bitcast (%0* @"\01l_objc_msgSend_fixup_isEqual_" to %struct._message_ref_t*), i8* %filename.0.in) 1926 %tobool79 = icmp eq i8 %call78, 0 1927 br i1 %tobool79, label %land.lhs.true80, label %if.then109 1928 1929 land.lhs.true80: ; preds = %if.end74 1930 %tmp82 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_25", align 8 1931 %call84 = call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %filename.0.in, i8* %tmp82) 1932 %tobool86 = icmp eq i8 %call84, 0 1933 br i1 %tobool86, label %if.then109, label %if.end106 1934 1935 if.end106: ; preds = %land.lhs.true80 1936 %tmp88 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_26", align 8 1937 %tmp90 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_28", align 8 1938 %tmp91 = bitcast %struct._class_t* %tmp88 to i8* 1939 %call9218 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp91, i8* %tmp90, i8* %filename.0.in) 1940 %tmp20 = bitcast i8* %call9218 to %5* 1941 %tmp21 = call i8* @objc_retain(i8* %call9218) nounwind 1942 %tmp22 = bitcast %5* %url.025 to i8* 1943 call void @objc_release(i8* %tmp22) nounwind 1944 %tmp94 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_29", align 8 1945 %tmp95 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_31", align 8 1946 %tmp96 = bitcast %struct._class_t* %tmp94 to i8* 1947 %call97 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp96, i8* %tmp95) 1948 %tmp99 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_33", align 8 1949 %call10119 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call97, i8* %tmp99, i8* %call9218, i32 signext 1, %4** %err) 1950 %phitmp = icmp eq i8* %call10119, null 1951 br i1 %phitmp, label %if.then109, label %end 1952 1953 if.then109: ; preds = %if.end106, %land.lhs.true80, %if.end74 1954 %url.129 = phi %5* [ %tmp20, %if.end106 ], [ %url.025, %if.end74 ], [ %url.025, %land.lhs.true80 ] 1955 %tmp110 = load %4** %err, align 8 1956 %tobool111 = icmp eq %4* %tmp110, null 1957 br i1 %tobool111, label %if.then112, label %if.end125 1958 1959 if.then112: ; preds = %if.then109 1960 %tmp113 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_50", align 8 1961 %tmp114 = load %1** @NSCocoaErrorDomain, align 8 1962 %tmp115 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_51", align 8 1963 %call117 = call %1* @truncatedString(%1* %filename.0, i64 1034) 1964 %tmp118 = load %1** @NSFilePathErrorKey, align 8 1965 %tmp119 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_53", align 8 1966 %tmp120 = bitcast %struct._class_t* %tmp115 to i8* 1967 %call12113 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp120, i8* %tmp119, %1* %call117, %1* %tmp118, i8* null) 1968 %tmp122 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_55", align 8 1969 %tmp123 = bitcast %struct._class_t* %tmp113 to i8* 1970 %call12414 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp123, i8* %tmp122, %1* %tmp114, i64 258, i8* %call12113) 1971 %tmp23 = call i8* @objc_retain(i8* %call12414) nounwind 1972 %tmp25 = call i8* @objc_autorelease(i8* %tmp23) nounwind 1973 %tmp28 = bitcast i8* %tmp25 to %4* 1974 store %4* %tmp28, %4** %err, align 8 1975 br label %if.end125 1976 1977 if.end125: ; preds = %if.then112, %if.then109 1978 %tmp127 = phi %4* [ %tmp110, %if.then109 ], [ %tmp28, %if.then112 ] 1979 %tmp126 = load %struct._class_t** @"\01L_OBJC_CLASSLIST_REFERENCES_$_56", align 8 1980 %tmp128 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_58", align 8 1981 %tmp129 = bitcast %struct._class_t* %tmp126 to i8* 1982 %call13015 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %tmp129, i8* %tmp128, %4* %tmp127) 1983 %tmp131 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_60", align 8 1984 %call13317 = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %call13015, i8* %tmp131) 1985 br label %end 1986 1987 end: ; preds = %if.end125, %if.end106, %if.end, %land.lhs.true, %entry 1988 %filename.2 = phi %1* [ %filename.0, %if.end106 ], [ %filename.0, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ] 1989 %origFilename.0 = phi %1* [ %tmp, %if.end106 ], [ %tmp, %if.end125 ], [ %tmp, %land.lhs.true ], [ null, %entry ], [ %tmp, %if.end ] 1990 %url.2 = phi %5* [ %tmp20, %if.end106 ], [ %url.129, %if.end125 ], [ null, %land.lhs.true ], [ null, %entry ], [ %tmp13, %if.end ] 1991 call void @objc_release(i8* %tmp9) nounwind, !clang.imprecise_release !0 1992 %tmp29 = bitcast %5* %url.2 to i8* 1993 call void @objc_release(i8* %tmp29) nounwind, !clang.imprecise_release !0 1994 %tmp30 = bitcast %1* %origFilename.0 to i8* 1995 call void @objc_release(i8* %tmp30) nounwind, !clang.imprecise_release !0 1996 %tmp31 = bitcast %1* %filename.2 to i8* 1997 call void @objc_release(i8* %tmp31) nounwind, !clang.imprecise_release !0 1998 call void @objc_release(i8* %tmp7) nounwind, !clang.imprecise_release !0 1999 ret void 2000 } 2001 2002 !0 = metadata !{} 2003 2004 declare i32 @__gxx_personality_v0(...) 2005