Home | History | Annotate | Download | only in ObjCARC
      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_retainAutorelease(i8*)
      7 declare void @objc_release(i8*)
      8 declare i8* @objc_autorelease(i8*)
      9 
     10 declare void @clang.arc.use(...)
     11 
     12 declare void @test0_helper(i8*, i8**)
     13 
     14 ; Ensure that we honor clang.arc.use as a use and don't miscompile
     15 ; the reduced test case from <rdar://13195034>.
     16 ;
     17 ; CHECK-LABEL:      define void @test0(
     18 ; CHECK:        @objc_retain(i8* %x)
     19 ; CHECK-NEXT:   store i8* %y, i8** %temp0
     20 ; CHECK-NEXT:   @objc_retain(i8* %y)
     21 ; CHECK-NEXT:   call void @test0_helper
     22 ; CHECK-NEXT:   [[VAL1:%.*]] = load i8*, i8** %temp0
     23 ; CHECK-NEXT:   @objc_retain(i8* [[VAL1]])
     24 ; CHECK-NEXT:   call void (...) @clang.arc.use(i8* %y)
     25 ; CHECK-NEXT:   @objc_release(i8* %y)
     26 ; CHECK-NEXT:   store i8* [[VAL1]], i8** %temp1
     27 ; CHECK-NEXT:   call void @test0_helper
     28 ; CHECK-NEXT:   [[VAL2:%.*]] = load i8*, i8** %temp1
     29 ; CHECK-NEXT:   @objc_retain(i8* [[VAL2]])
     30 ; CHECK-NEXT:   call void (...) @clang.arc.use(i8* [[VAL1]])
     31 ; CHECK-NEXT:   @objc_release(i8* [[VAL1]])
     32 ; CHECK-NEXT:   @objc_autorelease(i8* %x)
     33 ; CHECK-NEXT:   store i8* %x, i8** %out
     34 ; CHECK-NEXT:   @objc_retain(i8* %x)
     35 ; CHECK-NEXT:   @objc_release(i8* [[VAL2]])
     36 ; CHECK-NEXT:   @objc_release(i8* %x)
     37 ; CHECK-NEXT:   ret void
     38 ; CHECK-NEXT: }
     39 define void @test0(i8** %out, i8* %x, i8* %y) {
     40 entry:
     41   %temp0 = alloca i8*, align 8
     42   %temp1 = alloca i8*, align 8
     43   %0 = call i8* @objc_retain(i8* %x) nounwind
     44   %1 = call i8* @objc_retain(i8* %y) nounwind
     45   store i8* %y, i8** %temp0
     46   call void @test0_helper(i8* %x, i8** %temp0)
     47   %val1 = load i8*, i8** %temp0
     48   %2 = call i8* @objc_retain(i8* %val1) nounwind
     49   call void (...) @clang.arc.use(i8* %y) nounwind
     50   call void @objc_release(i8* %y) nounwind
     51   store i8* %val1, i8** %temp1
     52   call void @test0_helper(i8* %x, i8** %temp1)
     53   %val2 = load i8*, i8** %temp1
     54   %3 = call i8* @objc_retain(i8* %val2) nounwind
     55   call void (...) @clang.arc.use(i8* %val1) nounwind
     56   call void @objc_release(i8* %val1) nounwind
     57   %4 = call i8* @objc_retain(i8* %x) nounwind
     58   %5 = call i8* @objc_autorelease(i8* %x) nounwind
     59   store i8* %x, i8** %out
     60   call void @objc_release(i8* %val2) nounwind
     61   call void @objc_release(i8* %x) nounwind
     62   ret void
     63 }
     64 
     65 ; CHECK-LABEL:      define void @test0a(
     66 ; CHECK:        @objc_retain(i8* %x)
     67 ; CHECK-NEXT:   store i8* %y, i8** %temp0
     68 ; CHECK-NEXT:   @objc_retain(i8* %y)
     69 ; CHECK-NEXT:   call void @test0_helper
     70 ; CHECK-NEXT:   [[VAL1:%.*]] = load i8*, i8** %temp0
     71 ; CHECK-NEXT:   @objc_retain(i8* [[VAL1]])
     72 ; CHECK-NEXT:   call void (...) @clang.arc.use(i8* %y)
     73 ; CHECK-NEXT:   @objc_release(i8* %y)
     74 ; CHECK-NEXT:   store i8* [[VAL1]], i8** %temp1
     75 ; CHECK-NEXT:   call void @test0_helper
     76 ; CHECK-NEXT:   [[VAL2:%.*]] = load i8*, i8** %temp1
     77 ; CHECK-NEXT:   @objc_retain(i8* [[VAL2]])
     78 ; CHECK-NEXT:   call void (...) @clang.arc.use(i8* [[VAL1]])
     79 ; CHECK-NEXT:   @objc_release(i8* [[VAL1]])
     80 ; CHECK-NEXT:   @objc_autorelease(i8* %x)
     81 ; CHECK-NEXT:   @objc_release(i8* [[VAL2]])
     82 ; CHECK-NEXT:   store i8* %x, i8** %out
     83 ; CHECK-NEXT:   ret void
     84 ; CHECK-NEXT: }
     85 define void @test0a(i8** %out, i8* %x, i8* %y) {
     86 entry:
     87   %temp0 = alloca i8*, align 8
     88   %temp1 = alloca i8*, align 8
     89   %0 = call i8* @objc_retain(i8* %x) nounwind
     90   %1 = call i8* @objc_retain(i8* %y) nounwind
     91   store i8* %y, i8** %temp0
     92   call void @test0_helper(i8* %x, i8** %temp0)
     93   %val1 = load i8*, i8** %temp0
     94   %2 = call i8* @objc_retain(i8* %val1) nounwind
     95   call void (...) @clang.arc.use(i8* %y) nounwind
     96   call void @objc_release(i8* %y) nounwind, !clang.imprecise_release !0
     97   store i8* %val1, i8** %temp1
     98   call void @test0_helper(i8* %x, i8** %temp1)
     99   %val2 = load i8*, i8** %temp1
    100   %3 = call i8* @objc_retain(i8* %val2) nounwind
    101   call void (...) @clang.arc.use(i8* %val1) nounwind
    102   call void @objc_release(i8* %val1) nounwind, !clang.imprecise_release !0
    103   %4 = call i8* @objc_retain(i8* %x) nounwind
    104   %5 = call i8* @objc_autorelease(i8* %x) nounwind
    105   store i8* %x, i8** %out
    106   call void @objc_release(i8* %val2) nounwind, !clang.imprecise_release !0
    107   call void @objc_release(i8* %x) nounwind, !clang.imprecise_release !0
    108   ret void
    109 }
    110 
    111 
    112 !0 = !{}
    113 
    114