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