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
10target 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"
11target 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
71declare i8* @objc_msgSend(i8*, i8*, ...)
72
73declare i8* @objc_retain(i8*)
74
75declare void @objc_release(i8*)
76
77declare i8* @objc_autorelease(i8*)
78
79declare i8* @objc_explicit_autorelease(i8*)
80
81define hidden %14* @foo(%15* %arg, %16* %arg2) {
82bb:
83  %tmp = load i8*, 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*, %2** @"\01L_OBJC_CLASSLIST_REFERENCES_$_40", align 8
89  %tmp9 = load i8*, 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*, 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*, 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
102bb20:                                             ; preds = %bb
103  %tmp21 = icmp eq i8 %tmp14, 0
104  br label %bb25
105
106bb22:                                             ; 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
111bb25:                                             ; preds = %bb22, %bb20
112  %tmp26 = phi i1 [ %tmp21, %bb20 ], [ false, %bb22 ]
113  %tmp27 = load i8*, 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*, 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*, 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
125bb35:                                             ; preds = %bb25
126  %tmp36 = load i8*, 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*, %2** @"\01L_OBJC_CLASSLIST_REFERENCES_$_70", align 8
129  %tmp39 = load i8*, 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*, %13** @NSPrintHeaderAndFooter, align 8
134  %tmp44 = load i8*, 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
139bb46:                                             ; preds = %bb35, %bb25, %bb22
140  %tmp47 = phi %18* [ %tmp30, %bb35 ], [ %tmp30, %bb25 ], [ %tmp23, %bb22 ]
141  %tmp48 = load i8*, 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*, 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
150bb55:                                             ; preds = %bb46
151  %tmp56 = load i8*, 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
155bb57:                                             ; preds = %bb55, %bb46
156  %tmp58 = load %2*, %2** @"\01L_OBJC_CLASSLIST_REFERENCES_$_396", align 8
157  %tmp59 = load i8*, 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*, 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*, 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*, 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, i8* %tmp71, i64 1
172  %tmp72 = tail call i8* @objc_retain(i8* %tmp71x) nounwind
173  %tmp73 = load i8*, 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*, 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*, 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*, 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*, 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*, 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*, %2** @"\01L_OBJC_CLASSLIST_REFERENCES_$_409", align 8
190  %tmp87 = bitcast %2* %tmp86 to i8*
191  %tmp88 = load i8*, 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*, 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*, 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*, 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
206bb99:                                             ; preds = %bb57
207  %tmp100 = load i8*, 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*, 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
214bb104:                                            ; 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