1 ; RUN: opt -S -objc-arc-contract < %s | FileCheck %s 2 3 ; The optimizer should be able to move the autorelease past a control triangle 4 ; and various scary looking things and fold it into an objc_retainAutorelease. 5 6 ; CHECK: bb57: 7 ; CHECK: tail call i8* @objc_retainAutorelease(i8* %tmp71x) [[NUW:#[0-9]+]] 8 ; CHECK: bb99: 9 10 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" 11 target triple = "x86_64-apple-darwin11.0.0" 12 13 %0 = type { i8* (i8*, %1*, ...)*, i8* } 14 %1 = type { i8*, i8* } 15 %2 = type { %2*, %2*, %3*, i8* (i8*, i8*)**, %4* } 16 %3 = type opaque 17 %4 = type { i32, i32, i32, i8*, i8*, %5*, %7*, %10*, i8*, %9* } 18 %5 = type { i32, i32, [0 x %6] } 19 %6 = type { i8*, i8*, i8* } 20 %7 = type { i64, [0 x %8*] } 21 %8 = type { i8*, i8*, %7*, %5*, %5*, %5*, %5*, %9*, i32, i32 } 22 %9 = type { i32, i32, [0 x %1] } 23 %10 = type { i32, i32, [0 x %11] } 24 %11 = type { i64*, i8*, i8*, i32, i32 } 25 %12 = type { i32*, i32, i8*, i64 } 26 %13 = type opaque 27 %14 = type opaque 28 %15 = type opaque 29 %16 = type opaque 30 %17 = type opaque 31 %18 = type opaque 32 %19 = type opaque 33 %20 = type opaque 34 %21 = type opaque 35 %22 = type opaque 36 %23 = type opaque 37 %24 = type opaque 38 %25 = type opaque 39 40 @"\01l_objc_msgSend_fixup_alloc" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16 41 @"\01L_OBJC_SELECTOR_REFERENCES_8" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 42 @"\01L_OBJC_SELECTOR_REFERENCES_3725" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 43 @"\01L_OBJC_CLASSLIST_REFERENCES_$_40" = external hidden global %2*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 44 @"\01L_OBJC_SELECTOR_REFERENCES_4227" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 45 @"\01L_OBJC_SELECTOR_REFERENCES_4631" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 46 @"\01L_OBJC_CLASSLIST_REFERENCES_$_70" = external hidden global %2*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 47 @"\01L_OBJC_SELECTOR_REFERENCES_148" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 48 @"\01L_OBJC_SELECTOR_REFERENCES_159" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 49 @"\01L_OBJC_SELECTOR_REFERENCES_188" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 50 @"\01L_OBJC_SELECTOR_REFERENCES_328" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 51 @"\01l_objc_msgSend_fixup_objectAtIndex_" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16 52 @_unnamed_cfstring_386 = external hidden constant %12, section "__DATA,__cfstring" 53 @"\01l_objc_msgSend_fixup_count" = external hidden global %0, section "__DATA, __objc_msgrefs, coalesced", align 16 54 @"\01L_OBJC_SELECTOR_REFERENCES_389" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 55 @"\01L_OBJC_SELECTOR_REFERENCES_391" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 56 @"\01L_OBJC_SELECTOR_REFERENCES_393" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 57 @NSPrintHeaderAndFooter = external constant %13* 58 @"\01L_OBJC_SELECTOR_REFERENCES_395" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 59 @"\01L_OBJC_CLASSLIST_REFERENCES_$_396" = external hidden global %2*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 60 @"\01L_OBJC_SELECTOR_REFERENCES_398" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 61 @"\01L_OBJC_SELECTOR_REFERENCES_400" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 62 @"\01L_OBJC_SELECTOR_REFERENCES_402" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 63 @"\01L_OBJC_SELECTOR_REFERENCES_404" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 64 @"\01L_OBJC_SELECTOR_REFERENCES_406" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 65 @"\01L_OBJC_SELECTOR_REFERENCES_408" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 66 @"\01L_OBJC_CLASSLIST_REFERENCES_$_409" = external hidden global %2*, section "__DATA, __objc_classrefs, regular, no_dead_strip", align 8 67 @"\01L_OBJC_SELECTOR_REFERENCES_411" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 68 @"\01L_OBJC_SELECTOR_REFERENCES_413" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 69 @"\01L_OBJC_SELECTOR_REFERENCES_415" = external hidden global i8*, section "__DATA, __objc_selrefs, literal_pointers, no_dead_strip" 70 71 declare i8* @objc_msgSend(i8*, i8*, ...) 72 73 declare i8* @objc_retain(i8*) 74 75 declare void @objc_release(i8*) 76 77 declare i8* @objc_autorelease(i8*) 78 79 declare i8* @objc_explicit_autorelease(i8*) 80 81 define hidden %14* @foo(%15* %arg, %16* %arg2) { 82 bb: 83 %tmp = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_3725", align 8 84 %tmp4 = bitcast %15* %arg to i8* 85 %tmp5 = tail call %18* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %18* (i8*, i8*)*)(i8* %tmp4, i8* %tmp) 86 %tmp6 = bitcast %18* %tmp5 to i8* 87 %tmp7 = tail call i8* @objc_retain(i8* %tmp6) nounwind 88 %tmp8 = load %2** @"\01L_OBJC_CLASSLIST_REFERENCES_$_40", align 8 89 %tmp9 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_4227", align 8 90 %tmp10 = bitcast %2* %tmp8 to i8* 91 %tmp11 = tail call %19* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %19* (i8*, i8*)*)(i8* %tmp10, i8* %tmp9) 92 %tmp12 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_4631", align 8 93 %tmp13 = bitcast %19* %tmp11 to i8* 94 %tmp14 = tail call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*, %13*)*)(i8* %tmp13, i8* %tmp12, %13* bitcast (%12* @_unnamed_cfstring_386 to %13*)) 95 %tmp15 = bitcast %16* %arg2 to i8* 96 %tmp16 = load i8** bitcast (%0* @"\01l_objc_msgSend_fixup_count" to i8**), align 16 97 %tmp17 = bitcast i8* %tmp16 to i64 (i8*, %1*)* 98 %tmp18 = tail call i64 %tmp17(i8* %tmp15, %1* bitcast (%0* @"\01l_objc_msgSend_fixup_count" to %1*)) 99 %tmp19 = icmp eq i64 %tmp18, 0 100 br i1 %tmp19, label %bb22, label %bb20 101 102 bb20: ; preds = %bb 103 %tmp21 = icmp eq i8 %tmp14, 0 104 br label %bb25 105 106 bb22: ; preds = %bb 107 %tmp23 = bitcast i8* %tmp7 to %18* 108 %tmp24 = icmp eq i8 %tmp14, 0 109 br i1 %tmp24, label %bb46, label %bb25 110 111 bb25: ; preds = %bb22, %bb20 112 %tmp26 = phi i1 [ %tmp21, %bb20 ], [ false, %bb22 ] 113 %tmp27 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_188", align 8 114 %tmp28 = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %tmp7, i8* %tmp27) 115 %tmp29 = tail call i8* @objc_explicit_autorelease(i8* %tmp28) nounwind 116 %tmp30 = bitcast i8* %tmp29 to %18* 117 tail call void @objc_release(i8* %tmp7) nounwind 118 %tmp31 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_389", align 8 119 %tmp32 = tail call %20* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %20* (i8*, i8*)*)(i8* %tmp29, i8* %tmp31) 120 %tmp33 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_391", align 8 121 %tmp34 = bitcast %20* %tmp32 to i8* 122 tail call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %16*)*)(i8* %tmp34, i8* %tmp33, %16* %arg2) 123 br i1 %tmp26, label %bb46, label %bb35 124 125 bb35: ; preds = %bb25 126 %tmp36 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_389", align 8 127 %tmp37 = tail call %20* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %20* (i8*, i8*)*)(i8* %tmp29, i8* %tmp36) 128 %tmp38 = load %2** @"\01L_OBJC_CLASSLIST_REFERENCES_$_70", align 8 129 %tmp39 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_393", align 8 130 %tmp40 = bitcast %2* %tmp38 to i8* 131 %tmp41 = tail call %21* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %21* (i8*, i8*, i8)*)(i8* %tmp40, i8* %tmp39, i8 signext 1) 132 %tmp42 = bitcast %21* %tmp41 to i8* 133 %tmp43 = load %13** @NSPrintHeaderAndFooter, align 8 134 %tmp44 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_159", align 8 135 %tmp45 = bitcast %20* %tmp37 to i8* 136 tail call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8*, %13*)*)(i8* %tmp45, i8* %tmp44, i8* %tmp42, %13* %tmp43) 137 br label %bb46 138 139 bb46: ; preds = %bb35, %bb25, %bb22 140 %tmp47 = phi %18* [ %tmp30, %bb35 ], [ %tmp30, %bb25 ], [ %tmp23, %bb22 ] 141 %tmp48 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_328", align 8 142 %tmp49 = tail call %22* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %22* (i8*, i8*)*)(i8* %tmp4, i8* %tmp48) 143 %tmp50 = bitcast %22* %tmp49 to i8* 144 %tmp51 = load i8** bitcast (%0* @"\01l_objc_msgSend_fixup_count" to i8**), align 16 145 %tmp52 = bitcast i8* %tmp51 to i64 (i8*, %1*)* 146 %tmp53 = tail call i64 %tmp52(i8* %tmp50, %1* bitcast (%0* @"\01l_objc_msgSend_fixup_count" to %1*)) 147 %tmp54 = icmp eq i64 %tmp53, 0 148 br i1 %tmp54, label %bb55, label %bb57 149 150 bb55: ; preds = %bb46 151 %tmp56 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_395", align 8 152 tail call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*)*)(i8* %tmp4, i8* %tmp56) 153 br label %bb57 154 155 bb57: ; preds = %bb55, %bb46 156 %tmp58 = load %2** @"\01L_OBJC_CLASSLIST_REFERENCES_$_396", align 8 157 %tmp59 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_328", align 8 158 %tmp60 = tail call %22* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %22* (i8*, i8*)*)(i8* %tmp4, i8* %tmp59) 159 %tmp61 = bitcast %22* %tmp60 to i8* 160 %tmp62 = load i8** bitcast (%0* @"\01l_objc_msgSend_fixup_objectAtIndex_" to i8**), align 16 161 %tmp63 = bitcast i8* %tmp62 to i8* (i8*, %1*, i64)* 162 %tmp64 = tail call i8* %tmp63(i8* %tmp61, %1* bitcast (%0* @"\01l_objc_msgSend_fixup_objectAtIndex_" to %1*), i64 0) 163 %tmp65 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_398", align 8 164 %tmp66 = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %tmp64, i8* %tmp65) 165 %tmp67 = bitcast i8* %tmp66 to %23* 166 %tmp68 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_400", align 8 167 %tmp69 = bitcast %2* %tmp58 to i8* 168 %tmp70 = tail call %14* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %14* (i8*, i8*, %23*, %18*)*)(i8* %tmp69, i8* %tmp68, %23* %tmp67, %18* %tmp47) 169 %tmp71 = bitcast %14* %tmp70 to i8* 170 ; hack to prevent the optimize from using objc_retainAutoreleasedReturnValue. 171 %tmp71x = getelementptr i8* %tmp71, i64 1 172 %tmp72 = tail call i8* @objc_retain(i8* %tmp71x) nounwind 173 %tmp73 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_402", align 8 174 tail call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8)*)(i8* %tmp72, i8* %tmp73, i8 signext 1) 175 %tmp74 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_404", align 8 176 tail call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8)*)(i8* %tmp72, i8* %tmp74, i8 signext 1) 177 %tmp75 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_328", align 8 178 %tmp76 = tail call %22* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %22* (i8*, i8*)*)(i8* %tmp4, i8* %tmp75) 179 %tmp77 = bitcast %22* %tmp76 to i8* 180 %tmp78 = load i8** bitcast (%0* @"\01l_objc_msgSend_fixup_objectAtIndex_" to i8**), align 16 181 %tmp79 = bitcast i8* %tmp78 to i8* (i8*, %1*, i64)* 182 %tmp80 = tail call i8* %tmp79(i8* %tmp77, %1* bitcast (%0* @"\01l_objc_msgSend_fixup_objectAtIndex_" to %1*), i64 0) 183 %tmp81 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_406", align 8 184 tail call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i64)*)(i8* %tmp80, i8* %tmp81, i64 9223372036854775807) 185 %tmp82 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_408", align 8 186 %tmp83 = tail call %24* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to %24* (i8*, i8*)*)(i8* %tmp72, i8* %tmp82) 187 %tmp84 = bitcast %24* %tmp83 to i8* 188 %tmp85 = tail call i8* @objc_retain(i8* %tmp84) nounwind 189 %tmp86 = load %2** @"\01L_OBJC_CLASSLIST_REFERENCES_$_409", align 8 190 %tmp87 = bitcast %2* %tmp86 to i8* 191 %tmp88 = load i8** bitcast (%0* @"\01l_objc_msgSend_fixup_alloc" to i8**), align 16 192 %tmp89 = bitcast i8* %tmp88 to i8* (i8*, %1*)* 193 %tmp90 = tail call i8* %tmp89(i8* %tmp87, %1* bitcast (%0* @"\01l_objc_msgSend_fixup_alloc" to %1*)) 194 %tmp91 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_8", align 8 195 %tmp92 = tail call i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*, i8*)*)(i8* %tmp90, i8* %tmp91) 196 %tmp93 = tail call i8* @objc_explicit_autorelease(i8* %tmp92) nounwind 197 %tmp94 = bitcast i8* %tmp93 to %25* 198 %tmp95 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_411", align 8 199 tail call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %25*)*)(i8* %tmp85, i8* %tmp95, %25* %tmp94) 200 tail call void @objc_release(i8* %tmp93) nounwind 201 %tmp96 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_148", align 8 202 %tmp97 = tail call signext i8 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8 (i8*, i8*)*)(i8* %tmp4, i8* %tmp96) 203 %tmp98 = icmp eq i8 %tmp97, 0 204 br i1 %tmp98, label %bb99, label %bb104 205 206 bb99: ; preds = %bb57 207 %tmp100 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_413", align 8 208 %tmp101 = tail call i64 bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i64 (i8*, i8*)*)(i8* %tmp85, i8* %tmp100) 209 %tmp102 = or i64 %tmp101, 12 210 %tmp103 = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_415", align 8 211 tail call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i64)*)(i8* %tmp85, i8* %tmp103, i64 %tmp102) 212 br label %bb104 213 214 bb104: ; preds = %bb99, %bb57 215 %tmp105 = call i8* @objc_autorelease(i8* %tmp72) nounwind 216 %tmp106 = bitcast i8* %tmp105 to %14* 217 tail call void @objc_release(i8* %tmp85) nounwind 218 %tmp107 = bitcast %18* %tmp47 to i8* 219 tail call void @objc_release(i8* %tmp107) nounwind 220 ret %14* %tmp106 221 } 222 223 ; CHECK: attributes [[NUW]] = { nounwind } 224