1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 %struct.S = type { i32, i32, i32, float, float, float }
7 @globalBytes = global [1024 x i8] zeroinitializer, align 16
8 @Gint1 = global i32 zeroinitializer, align 4
9 @Gint2 = global i32 zeroinitializer, align 4
10 @Gstatic_int1 = internal global i32 zeroinitializer, align 4
11 @Gstatic_int2 = internal global i32 zeroinitializer, align 4
12 @Gstatic_int3 = internal global i32 zeroinitializer, align 4
13 @Gstatic_undef_int1 = internal global i32 undef, align 4
14 @Gstatic_undef_int2 = internal global i32 undef, align 4
15 @GI1 = internal global i32 undef, align 4
16 @GI2 = internal global i32 undef, align 4
17 @Gs1 = internal global %struct.S undef, align 4
18 @Gs2 = internal global %struct.S zeroinitializer, align 4
19 @Vs1 = internal global %struct.S undef, align 4
20 @Vs2 = internal global %struct.S undef, align 4
21 @GBytes = internal global [1024 x i8] zeroinitializer, align 16
22 @Flag0 = global i32 0, align 4
23 @Flag1 = internal global i32 undef, align 4
24 @Flag2 = internal global i32 undef, align 4
25 @Flag4 = internal global i32 undef, align 4
26 @Flag3 = internal global i32 zeroinitializer, align 4
27 @a1 = internal global i32 zeroinitializer
28 @a2 = internal global i32 zeroinitializer
29 @a3 = internal global i32 undef
30 @bytes1 = internal global i32 undef
31 @bytes2 = internal global i32 undef
32 @rec_storage = internal global i32 undef
35 ; CHECK: @globalBytes = global [1024 x i8] zeroinitializer, align 16
36 ; CHECK: @Gint1 = global i32 0, align 4
37 ; CHECK: @Gint2 = global i32 0, align 4
38 ; CHECK: @Gstatic_int1 = internal global i32 0, align 4
39 ; CHECK: @Gstatic_int2 = internal global i32 0, align 4
40 ; CHECK: @Gstatic_int3 = internal global i32 0, align 4
41 ; CHECK: @Gstatic_undef_int1 = internal global i32 undef, align 4
42 ; CHECK: @Gstatic_undef_int2 = internal global i32 undef, align 4
43 ; CHECK: @GI1 = internal global i32 undef, align 4
44 ; CHECK: @GI2 = internal global i32 undef, align 4
45 ; CHECK: @Gs1 = internal global %struct.S undef, align 4
46 ; CHECK: @Gs2 = internal global %struct.S zeroinitializer, align 4
47 ; CHECK: @Vs1 = internal global %struct.S undef, align 4
48 ; CHECK: @Vs2 = internal global %struct.S undef, align 4
49 ; CHECK: @GBytes = internal global [1024 x i8] zeroinitializer, align 16
50 ; CHECK: @Flag0 = global i32 0, align 4
51 ; CHECK: @Flag1 = internal global i32 undef, align 4
52 ; CHECK: @Flag2 = internal global i32 undef, align 4
53 ; CHECK: @Flag4 = internal global i32 undef, align 4
54 ; CHECK: @Flag3 = internal global i32 0, align 4
55 ; CHECK: @a1 = internal global i32 0
56 ; CHECK: @a2 = internal global i32 0
57 ; CHECK: @a3 = internal global i32 undef
58 ; CHECK: @bytes1 = internal global i32 undef
59 ; CHECK: @bytes2 = internal global i32 undef
60 ; CHECK: @rec_storage = internal global i32 undef
61 ; CHECK: @global = internal global %struct.STy zeroinitializer, align 8
62 ; CHECK: @G = internal global i32 0, align 4
63 ; CHECK: @GC = internal global i32 undef, align 4
64 ; CHECK: @GRS = internal thread_local global i32 undef
65 ; CHECK: @GRS2 = global i32 undef
67 define void @write_arg(ptr %p, i32 %v) {
68 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
69 ; CHECK-LABEL: define {{[^@]+}}@write_arg
70 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR0:[0-9]+]] {
72 ; CHECK-NEXT: store i32 [[V]], ptr [[P]], align 4, !tbaa [[TBAA3:![0-9]+]]
73 ; CHECK-NEXT: ret void
76 store i32 %v, ptr %p, align 4, !tbaa !3
80 define void @write_random(ptr %p) {
81 ; CHECK-LABEL: define {{[^@]+}}@write_random
82 ; CHECK-SAME: (ptr nocapture nofree writeonly [[P:%.*]]) {
84 ; CHECK-NEXT: [[CALL:%.*]] = call i32 (...) @random()
85 ; CHECK-NEXT: store i32 [[CALL]], ptr [[P]], align 4, !tbaa [[TBAA3]]
86 ; CHECK-NEXT: ret void
89 %call = call i32 (...) @random()
90 store i32 %call, ptr %p, align 4, !tbaa !3
94 declare i32 @random(...)
96 ; struct S local_alloca_simplifiable_1(void) {
101 ; write_arg(&s.i1, 1);
102 ; write_arg(&s.i2, 2);
103 ; write_arg(&s.i3, 3);
107 ; r.f3 = s.f3 + s.f1;
110 ; r.i3 = s.i3 + s.i1;
113 define void @local_alloca_simplifiable_1(ptr noalias sret(%struct.S) align 4 %agg.result) {
114 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
115 ; TUNIT-LABEL: define {{[^@]+}}@local_alloca_simplifiable_1
116 ; TUNIT-SAME: (ptr noalias nocapture nofree writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable_or_null(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] {
118 ; TUNIT-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4
119 ; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 24, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(24) [[S]]) #[[ATTR17:[0-9]+]]
120 ; TUNIT-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
121 ; TUNIT-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4
122 ; TUNIT-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5
123 ; TUNIT-NEXT: call void @write_arg(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[S]], i32 noundef 1) #[[ATTR18:[0-9]+]]
124 ; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1
125 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR18]]
126 ; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
127 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR18]]
128 ; TUNIT-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3
129 ; TUNIT-NEXT: store float 0x3FF19999A0000000, ptr [[F12]], align 4, !tbaa [[TBAA7:![0-9]+]]
130 ; TUNIT-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4
131 ; TUNIT-NEXT: store float 0x40119999A0000000, ptr [[F24]], align 4, !tbaa [[TBAA10:![0-9]+]]
132 ; TUNIT-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5
133 ; TUNIT-NEXT: store float 0x40119999A0000000, ptr [[F37]], align 4, !tbaa [[TBAA11:![0-9]+]]
134 ; TUNIT-NEXT: store i32 1, ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12:![0-9]+]]
135 ; TUNIT-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1
136 ; TUNIT-NEXT: store i32 4, ptr [[I212]], align 4, !tbaa [[TBAA13:![0-9]+]]
137 ; TUNIT-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2
138 ; TUNIT-NEXT: store i32 4, ptr [[I316]], align 4, !tbaa [[TBAA14:![0-9]+]]
139 ; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 24, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(24) [[S]]) #[[ATTR17]]
140 ; TUNIT-NEXT: ret void
142 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
143 ; CGSCC-LABEL: define {{[^@]+}}@local_alloca_simplifiable_1
144 ; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] {
146 ; CGSCC-NEXT: [[S:%.*]] = alloca [[STRUCT_S]], align 4
147 ; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 24, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(24) [[S]]) #[[ATTR20:[0-9]+]]
148 ; CGSCC-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
149 ; CGSCC-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7:![0-9]+]]
150 ; CGSCC-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4
151 ; CGSCC-NEXT: store float 0x40019999A0000000, ptr [[F2]], align 4, !tbaa [[TBAA10:![0-9]+]]
152 ; CGSCC-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5
153 ; CGSCC-NEXT: store float 0x400A666660000000, ptr [[F3]], align 4, !tbaa [[TBAA11:![0-9]+]]
154 ; CGSCC-NEXT: call void @write_arg(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) [[S]], i32 noundef 1) #[[ATTR21:[0-9]+]]
155 ; CGSCC-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1
156 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]]
157 ; CGSCC-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
158 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]]
159 ; CGSCC-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
160 ; CGSCC-NEXT: [[I4:%.*]] = load float, ptr [[F11]], align 4, !tbaa [[TBAA7]]
161 ; CGSCC-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3
162 ; CGSCC-NEXT: store float [[I4]], ptr [[F12]], align 4, !tbaa [[TBAA7]]
163 ; CGSCC-NEXT: [[F23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4
164 ; CGSCC-NEXT: [[I5:%.*]] = load float, ptr [[F23]], align 4, !tbaa [[TBAA10]]
165 ; CGSCC-NEXT: [[MUL:%.*]] = fmul float [[I5]], 2.000000e+00
166 ; CGSCC-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4
167 ; CGSCC-NEXT: store float [[MUL]], ptr [[F24]], align 4, !tbaa [[TBAA10]]
168 ; CGSCC-NEXT: [[F35:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5
169 ; CGSCC-NEXT: [[I6:%.*]] = load float, ptr [[F35]], align 4, !tbaa [[TBAA11]]
170 ; CGSCC-NEXT: [[F16:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
171 ; CGSCC-NEXT: [[I7:%.*]] = load float, ptr [[F16]], align 4, !tbaa [[TBAA7]]
172 ; CGSCC-NEXT: [[ADD:%.*]] = fadd float [[I6]], [[I7]]
173 ; CGSCC-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5
174 ; CGSCC-NEXT: store float [[ADD]], ptr [[F37]], align 4, !tbaa [[TBAA11]]
175 ; CGSCC-NEXT: [[I8:%.*]] = load i32, ptr [[S]], align 4, !tbaa [[TBAA12:![0-9]+]]
176 ; CGSCC-NEXT: store i32 [[I8]], ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]]
177 ; CGSCC-NEXT: [[I210:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1
178 ; CGSCC-NEXT: [[I9:%.*]] = load i32, ptr [[I210]], align 4, !tbaa [[TBAA13:![0-9]+]]
179 ; CGSCC-NEXT: [[MUL11:%.*]] = shl nsw i32 [[I9]], 1
180 ; CGSCC-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1
181 ; CGSCC-NEXT: store i32 [[MUL11]], ptr [[I212]], align 4, !tbaa [[TBAA13]]
182 ; CGSCC-NEXT: [[I313:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
183 ; CGSCC-NEXT: [[I10:%.*]] = load i32, ptr [[I313]], align 4, !tbaa [[TBAA14:![0-9]+]]
184 ; CGSCC-NEXT: [[I11:%.*]] = load i32, ptr [[S]], align 4, !tbaa [[TBAA12]]
185 ; CGSCC-NEXT: [[ADD15:%.*]] = add nsw i32 [[I10]], [[I11]]
186 ; CGSCC-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2
187 ; CGSCC-NEXT: store i32 [[ADD15]], ptr [[I316]], align 4, !tbaa [[TBAA14]]
188 ; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 24, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(24) [[S]]) #[[ATTR20]]
189 ; CGSCC-NEXT: ret void
192 %s = alloca %struct.S, align 4
193 call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %s)
194 %f1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3
195 store float 0x3FF19999A0000000, ptr %f1, align 4, !tbaa !7
196 %f2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 4
197 store float 0x40019999A0000000, ptr %f2, align 4, !tbaa !10
198 %f3 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 5
199 store float 0x400A666660000000, ptr %f3, align 4, !tbaa !11
200 call void @write_arg(ptr nonnull %s, i32 1)
201 %i2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1
202 call void @write_arg(ptr nonnull %i2, i32 2)
203 %i3 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
204 call void @write_arg(ptr nonnull %i3, i32 3)
205 %f11 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3
206 %i4 = load float, ptr %f11, align 4, !tbaa !7
207 %f12 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 3
208 store float %i4, ptr %f12, align 4, !tbaa !7
209 %f23 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 4
210 %i5 = load float, ptr %f23, align 4, !tbaa !10
211 %mul = fmul float %i5, 2.000000e+00
212 %f24 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 4
213 store float %mul, ptr %f24, align 4, !tbaa !10
214 %f35 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 5
215 %i6 = load float, ptr %f35, align 4, !tbaa !11
216 %f16 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3
217 %i7 = load float, ptr %f16, align 4, !tbaa !7
218 %add = fadd float %i6, %i7
219 %f37 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 5
220 store float %add, ptr %f37, align 4, !tbaa !11
221 %i8 = load i32, ptr %s, align 4, !tbaa !12
222 store i32 %i8, ptr %agg.result, align 4, !tbaa !12
223 %i210 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1
224 %i9 = load i32, ptr %i210, align 4, !tbaa !13
225 %mul11 = shl nsw i32 %i9, 1
226 %i212 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 1
227 store i32 %mul11, ptr %i212, align 4, !tbaa !13
228 %i313 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
229 %i10 = load i32, ptr %i313, align 4, !tbaa !14
230 %i11 = load i32, ptr %s, align 4, !tbaa !12
231 %add15 = add nsw i32 %i10, %i11
232 %i316 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 2
233 store i32 %add15, ptr %i316, align 4, !tbaa !14
234 call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %s)
238 declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
240 declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
242 ; void local_alloca_simplifiable_2(void) {
244 ; for (int i = 0; i < 100; ++i)
246 ; for (int i = 0; i < 10; ++i)
247 ; ((float *)Bytes)[i * 10 + 1] = 0;
248 ; for (int i = 0; i < 20; ++i)
249 ; ((long long int *)Bytes)[i * 10 + 2] = 0;
251 ; write_arg((int *)&Bytes[500], 0);
253 ; for (int i = 0; i < 1024; ++i)
254 ; globalBytes[i] = Bytes[i];
257 define void @local_alloca_simplifiable_2() {
258 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
259 ; TUNIT-LABEL: define {{[^@]+}}@local_alloca_simplifiable_2
260 ; TUNIT-SAME: () #[[ATTR3:[0-9]+]] {
262 ; TUNIT-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
263 ; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 1024, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[BYTES]]) #[[ATTR17]]
264 ; TUNIT-NEXT: br label [[FOR_COND:%.*]]
266 ; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
267 ; TUNIT-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100
268 ; TUNIT-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
269 ; TUNIT: for.cond.cleanup:
270 ; TUNIT-NEXT: br label [[FOR_END:%.*]]
272 ; TUNIT-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10
273 ; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[I15]]
274 ; TUNIT-NEXT: br label [[FOR_INC]]
276 ; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
277 ; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP15:![0-9]+]]
279 ; TUNIT-NEXT: br label [[FOR_COND2:%.*]]
281 ; TUNIT-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ]
282 ; TUNIT-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10
283 ; TUNIT-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]]
284 ; TUNIT: for.cond.cleanup4:
285 ; TUNIT-NEXT: br label [[FOR_END11:%.*]]
287 ; TUNIT-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
288 ; TUNIT-NEXT: [[I18:%.*]] = or i64 [[I17]], 1
289 ; TUNIT-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I18]]
290 ; TUNIT-NEXT: br label [[FOR_INC9]]
292 ; TUNIT-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
293 ; TUNIT-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP17:![0-9]+]]
295 ; TUNIT-NEXT: br label [[FOR_COND13:%.*]]
297 ; TUNIT-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC22:%.*]] ], [ 0, [[FOR_END11]] ]
298 ; TUNIT-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20
299 ; TUNIT-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]]
300 ; TUNIT: for.cond.cleanup15:
301 ; TUNIT-NEXT: br label [[FOR_END24:%.*]]
303 ; TUNIT-NEXT: [[I20:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10
304 ; TUNIT-NEXT: [[I21:%.*]] = add nuw nsw i64 [[I20]], 2
305 ; TUNIT-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I21]]
306 ; TUNIT-NEXT: br label [[FOR_INC22]]
308 ; TUNIT-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
309 ; TUNIT-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP18:![0-9]+]]
311 ; TUNIT-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 1023
312 ; TUNIT-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 500
313 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(524) [[ARRAYIDX26]], i32 noundef 0) #[[ATTR18]]
314 ; TUNIT-NEXT: br label [[FOR_COND28:%.*]]
316 ; TUNIT-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ]
317 ; TUNIT-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024
318 ; TUNIT-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY31:%.*]], label [[FOR_COND_CLEANUP30:%.*]]
319 ; TUNIT: for.cond.cleanup30:
320 ; TUNIT-NEXT: br label [[FOR_END38:%.*]]
322 ; TUNIT-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]]
323 ; TUNIT-NEXT: store i8 0, ptr [[ARRAYIDX35]], align 1, !tbaa [[TBAA19:![0-9]+]]
324 ; TUNIT-NEXT: br label [[FOR_INC36]]
326 ; TUNIT-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1
327 ; TUNIT-NEXT: br label [[FOR_COND28]], !llvm.loop [[LOOP20:![0-9]+]]
329 ; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 1024, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[BYTES]]) #[[ATTR17]]
330 ; TUNIT-NEXT: ret void
332 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
333 ; CGSCC-LABEL: define {{[^@]+}}@local_alloca_simplifiable_2
334 ; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
336 ; CGSCC-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
337 ; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 1024, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[BYTES]]) #[[ATTR20]]
338 ; CGSCC-NEXT: br label [[FOR_COND:%.*]]
340 ; CGSCC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
341 ; CGSCC-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100
342 ; CGSCC-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
343 ; CGSCC: for.cond.cleanup:
344 ; CGSCC-NEXT: br label [[FOR_END:%.*]]
346 ; CGSCC-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10
347 ; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[I15]]
348 ; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX]], align 2, !tbaa [[TBAA15:![0-9]+]]
349 ; CGSCC-NEXT: br label [[FOR_INC]]
351 ; CGSCC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
352 ; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP16:![0-9]+]]
354 ; CGSCC-NEXT: br label [[FOR_COND2:%.*]]
356 ; CGSCC-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ]
357 ; CGSCC-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10
358 ; CGSCC-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]]
359 ; CGSCC: for.cond.cleanup4:
360 ; CGSCC-NEXT: br label [[FOR_END11:%.*]]
362 ; CGSCC-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
363 ; CGSCC-NEXT: [[I18:%.*]] = or i64 [[I17]], 1
364 ; CGSCC-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I18]]
365 ; CGSCC-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA18:![0-9]+]]
366 ; CGSCC-NEXT: br label [[FOR_INC9]]
368 ; CGSCC-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
369 ; CGSCC-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP19:![0-9]+]]
371 ; CGSCC-NEXT: br label [[FOR_COND13:%.*]]
373 ; CGSCC-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC22:%.*]] ], [ 0, [[FOR_END11]] ]
374 ; CGSCC-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20
375 ; CGSCC-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]]
376 ; CGSCC: for.cond.cleanup15:
377 ; CGSCC-NEXT: br label [[FOR_END24:%.*]]
379 ; CGSCC-NEXT: [[I20:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10
380 ; CGSCC-NEXT: [[I21:%.*]] = add nuw nsw i64 [[I20]], 2
381 ; CGSCC-NEXT: [[ARRAYIDX21:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I21]]
382 ; CGSCC-NEXT: store i64 0, ptr [[ARRAYIDX21]], align 16, !tbaa [[TBAA20:![0-9]+]]
383 ; CGSCC-NEXT: br label [[FOR_INC22]]
385 ; CGSCC-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
386 ; CGSCC-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP22:![0-9]+]]
388 ; CGSCC-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 1023
389 ; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX25]], align 1, !tbaa [[TBAA15]]
390 ; CGSCC-NEXT: [[ARRAYIDX26:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 500
391 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(524) [[ARRAYIDX26]], i32 noundef 0) #[[ATTR21]]
392 ; CGSCC-NEXT: br label [[FOR_COND28:%.*]]
394 ; CGSCC-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC36:%.*]] ], [ 0, [[FOR_END24]] ]
395 ; CGSCC-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024
396 ; CGSCC-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY31:%.*]], label [[FOR_COND_CLEANUP30:%.*]]
397 ; CGSCC: for.cond.cleanup30:
398 ; CGSCC-NEXT: br label [[FOR_END38:%.*]]
400 ; CGSCC-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDVARS_IV12]]
401 ; CGSCC-NEXT: [[I23:%.*]] = load i8, ptr [[ARRAYIDX33]], align 1, !tbaa [[TBAA15]]
402 ; CGSCC-NEXT: [[ARRAYIDX35:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]]
403 ; CGSCC-NEXT: store i8 [[I23]], ptr [[ARRAYIDX35]], align 1, !tbaa [[TBAA15]]
404 ; CGSCC-NEXT: br label [[FOR_INC36]]
406 ; CGSCC-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1
407 ; CGSCC-NEXT: br label [[FOR_COND28]], !llvm.loop [[LOOP23:![0-9]+]]
409 ; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 1024, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(1024) [[BYTES]]) #[[ATTR20]]
410 ; CGSCC-NEXT: ret void
413 %Bytes = alloca [1024 x i8], align 16
414 call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %Bytes)
417 for.cond: ; preds = %for.inc, %entry
418 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
419 %exitcond = icmp ne i64 %indvars.iv, 100
420 br i1 %exitcond, label %for.body, label %for.cond.cleanup
422 for.cond.cleanup: ; preds = %for.cond
425 for.body: ; preds = %for.cond
426 %i15 = mul nuw nsw i64 %indvars.iv, 10
427 %arrayidx = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %i15
428 store i8 0, ptr %arrayidx, align 2, !tbaa !15
431 for.inc: ; preds = %for.body
432 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
433 br label %for.cond, !llvm.loop !16
435 for.end: ; preds = %for.cond.cleanup
438 for.cond2: ; preds = %for.inc9, %for.end
439 %indvars.iv2 = phi i64 [ %indvars.iv.next3, %for.inc9 ], [ 0, %for.end ]
440 %exitcond6 = icmp ne i64 %indvars.iv2, 10
441 br i1 %exitcond6, label %for.body5, label %for.cond.cleanup4
443 for.cond.cleanup4: ; preds = %for.cond2
446 for.body5: ; preds = %for.cond2
447 %i17 = mul nuw nsw i64 %indvars.iv2, 10
448 %i18 = or i64 %i17, 1
449 %arrayidx8 = getelementptr inbounds float, ptr %Bytes, i64 %i18
450 store float 0.000000e+00, ptr %arrayidx8, align 4, !tbaa !18
453 for.inc9: ; preds = %for.body5
454 %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1
455 br label %for.cond2, !llvm.loop !19
457 for.end11: ; preds = %for.cond.cleanup4
460 for.cond13: ; preds = %for.inc22, %for.end11
461 %indvars.iv7 = phi i64 [ %indvars.iv.next8, %for.inc22 ], [ 0, %for.end11 ]
462 %exitcond11 = icmp ne i64 %indvars.iv7, 20
463 br i1 %exitcond11, label %for.body16, label %for.cond.cleanup15
465 for.cond.cleanup15: ; preds = %for.cond13
468 for.body16: ; preds = %for.cond13
469 %i20 = mul nuw nsw i64 %indvars.iv7, 10
470 %i21 = add nuw nsw i64 %i20, 2
471 %arrayidx21 = getelementptr inbounds i64, ptr %Bytes, i64 %i21
472 store i64 0, ptr %arrayidx21, align 16, !tbaa !20
475 for.inc22: ; preds = %for.body16
476 %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1
477 br label %for.cond13, !llvm.loop !22
479 for.end24: ; preds = %for.cond.cleanup15
480 %arrayidx25 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 1023
481 store i8 0, ptr %arrayidx25, align 1, !tbaa !15
482 %arrayidx26 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 500
483 call void @write_arg(ptr nonnull %arrayidx26, i32 0)
486 for.cond28: ; preds = %for.inc36, %for.end24
487 %indvars.iv12 = phi i64 [ %indvars.iv.next13, %for.inc36 ], [ 0, %for.end24 ]
488 %exitcond14 = icmp ne i64 %indvars.iv12, 1024
489 br i1 %exitcond14, label %for.body31, label %for.cond.cleanup30
491 for.cond.cleanup30: ; preds = %for.cond28
494 for.body31: ; preds = %for.cond28
495 %arrayidx33 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %indvars.iv12
496 %i23 = load i8, ptr %arrayidx33, align 1, !tbaa !15
497 %arrayidx35 = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 %indvars.iv12
498 store i8 %i23, ptr %arrayidx35, align 1, !tbaa !15
501 for.inc36: ; preds = %for.body31
502 %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1
503 br label %for.cond28, !llvm.loop !23
505 for.end38: ; preds = %for.cond.cleanup30
506 call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %Bytes)
510 ; int local_alloca_simplifiable_3() {
517 define i32 @local_alloca_simplifiable_3() {
518 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
519 ; CHECK-LABEL: define {{[^@]+}}@local_alloca_simplifiable_3
520 ; CHECK-SAME: () #[[ATTR4:[0-9]+]] {
521 ; CHECK-NEXT: br label [[SPLIT:%.*]]
523 ; CHECK-NEXT: ret i32 2
525 %A = alloca i32, align 4
530 %l = load i32, ptr %A, align 4
533 ; int local_alloca_simplifiable_4() {
538 define i32 @local_alloca_simplifiable_4() {
539 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
540 ; CHECK-LABEL: define {{[^@]+}}@local_alloca_simplifiable_4
541 ; CHECK-SAME: () #[[ATTR4]] {
542 ; CHECK-NEXT: ret i32 undef
544 %A = alloca i32, align 4
545 %l = load i32, ptr %A, align 4
549 ; static int GI1 __attribute__((loader_uninitialized));
550 ; int multi_obj_simplifiable_1(int cnd) {
552 ; int *p = cnd ? &GI1 : &L;
555 define i32 @multi_obj_simplifiable_1(i32 %cnd) {
556 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
557 ; TUNIT-LABEL: define {{[^@]+}}@multi_obj_simplifiable_1
558 ; TUNIT-SAME: (i32 [[CND:%.*]]) #[[ATTR3]] {
560 ; TUNIT-NEXT: [[L:%.*]] = alloca i32, align 4
561 ; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[L]]) #[[ATTR17]]
562 ; TUNIT-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0
563 ; TUNIT-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]]
565 ; TUNIT-NEXT: br label [[COND_END:%.*]]
567 ; TUNIT-NEXT: br label [[COND_END]]
569 ; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[L]]) #[[ATTR17]]
570 ; TUNIT-NEXT: ret i32 5
572 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
573 ; CGSCC-LABEL: define {{[^@]+}}@multi_obj_simplifiable_1
574 ; CGSCC-SAME: (i32 [[CND:%.*]]) #[[ATTR5:[0-9]+]] {
576 ; CGSCC-NEXT: [[L:%.*]] = alloca i32, align 4
577 ; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[L]]) #[[ATTR20]]
578 ; CGSCC-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0
579 ; CGSCC-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]]
581 ; CGSCC-NEXT: br label [[COND_END:%.*]]
583 ; CGSCC-NEXT: br label [[COND_END]]
585 ; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[L]]) #[[ATTR20]]
586 ; CGSCC-NEXT: ret i32 5
589 %L = alloca i32, align 4
590 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %L)
591 store i32 5, ptr @GI1, align 4, !tbaa !3
592 store i32 5, ptr %L, align 4, !tbaa !3
593 %tobool.not = icmp eq i32 %cnd, 0
594 br i1 %tobool.not, label %cond.false, label %cond.true
596 cond.true: ; preds = %entry
599 cond.false: ; preds = %entry
602 cond.end: ; preds = %cond.false, %cond.true
603 %cond = phi ptr [ @GI1, %cond.true ], [ %L, %cond.false ]
604 %i1 = load i32, ptr %cond, align 4, !tbaa !3
605 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %L)
609 ; static int GI2 __attribute__((loader_uninitialized));
610 ; int multi_obj_simplifiable_2(int cnd) {
612 ; int *p = cnd ? &GI2 : &L;
617 define i32 @multi_obj_simplifiable_2(i32 %cnd) {
618 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
619 ; TUNIT-LABEL: define {{[^@]+}}@multi_obj_simplifiable_2
620 ; TUNIT-SAME: (i32 [[CND:%.*]]) #[[ATTR3]] {
622 ; TUNIT-NEXT: [[L:%.*]] = alloca i32, align 4
623 ; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[L]]) #[[ATTR17]]
624 ; TUNIT-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0
625 ; TUNIT-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]]
627 ; TUNIT-NEXT: br label [[COND_END:%.*]]
629 ; TUNIT-NEXT: br label [[COND_END]]
631 ; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[L]]) #[[ATTR17]]
632 ; TUNIT-NEXT: ret i32 5
634 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
635 ; CGSCC-LABEL: define {{[^@]+}}@multi_obj_simplifiable_2
636 ; CGSCC-SAME: (i32 [[CND:%.*]]) #[[ATTR5]] {
638 ; CGSCC-NEXT: [[L:%.*]] = alloca i32, align 4
639 ; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[L]]) #[[ATTR20]]
640 ; CGSCC-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0
641 ; CGSCC-NEXT: br i1 [[TOBOOL_NOT]], label [[COND_FALSE:%.*]], label [[COND_TRUE:%.*]]
643 ; CGSCC-NEXT: br label [[COND_END:%.*]]
645 ; CGSCC-NEXT: br label [[COND_END]]
647 ; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[L]]) #[[ATTR20]]
648 ; CGSCC-NEXT: ret i32 5
651 %L = alloca i32, align 4
652 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %L)
653 %tobool.not = icmp eq i32 %cnd, 0
654 br i1 %tobool.not, label %cond.false, label %cond.true
656 cond.true: ; preds = %entry
659 cond.false: ; preds = %entry
662 cond.end: ; preds = %cond.false, %cond.true
663 %cond = phi ptr [ @GI2, %cond.true ], [ %L, %cond.false ]
664 store i32 5, ptr %cond, align 4, !tbaa !3
665 %l = load i32, ptr %cond, align 4, !tbaa !3
666 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %L)
670 ; static struct S Gs __attribute__((loader_uninitialized));
671 ; struct S static_global_simplifiable_1(void) {
675 ; write_arg(&Gs.i1, 1);
676 ; write_arg(&Gs.i2, 2);
677 ; write_arg(&Gs.i3, 3);
681 ; r.f3 = Gs.f3 + Gs.f1;
684 ; r.i3 = Gs.i3 + Gs.i1;
688 define void @static_global_simplifiable_1(ptr noalias sret(%struct.S) align 4 %agg.result) {
689 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
690 ; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_1
691 ; TUNIT-SAME: (ptr noalias nocapture nofree writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable_or_null(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] {
693 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) @Gs1, i32 noundef 1) #[[ATTR18]]
694 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR18]]
695 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR18]]
696 ; TUNIT-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3
697 ; TUNIT-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7]]
698 ; TUNIT-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4
699 ; TUNIT-NEXT: store float 0x40119999A0000000, ptr [[F2]], align 4, !tbaa [[TBAA10]]
700 ; TUNIT-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5
701 ; TUNIT-NEXT: store float 0x40119999A0000000, ptr [[F3]], align 4, !tbaa [[TBAA11]]
702 ; TUNIT-NEXT: store i32 1, ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]]
703 ; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1
704 ; TUNIT-NEXT: store i32 4, ptr [[I2]], align 4, !tbaa [[TBAA13]]
705 ; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2
706 ; TUNIT-NEXT: store i32 4, ptr [[I3]], align 4, !tbaa [[TBAA14]]
707 ; TUNIT-NEXT: ret void
709 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
710 ; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_1
711 ; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR3]] {
713 ; CGSCC-NEXT: store float 0x3FF19999A0000000, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]]
714 ; CGSCC-NEXT: store float 0x40019999A0000000, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]]
715 ; CGSCC-NEXT: store float 0x400A666660000000, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]]
716 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(24) @Gs1, i32 noundef 1) #[[ATTR21]]
717 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR21]]
718 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(16) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 2), i32 noundef 3) #[[ATTR21]]
719 ; CGSCC-NEXT: [[I:%.*]] = load float, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]]
720 ; CGSCC-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3
721 ; CGSCC-NEXT: store float [[I]], ptr [[F1]], align 4, !tbaa [[TBAA7]]
722 ; CGSCC-NEXT: [[I4:%.*]] = load float, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 4), align 4, !tbaa [[TBAA10]]
723 ; CGSCC-NEXT: [[MUL:%.*]] = fmul float [[I4]], 2.000000e+00
724 ; CGSCC-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4
725 ; CGSCC-NEXT: store float [[MUL]], ptr [[F2]], align 4, !tbaa [[TBAA10]]
726 ; CGSCC-NEXT: [[I5:%.*]] = load float, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 5), align 4, !tbaa [[TBAA11]]
727 ; CGSCC-NEXT: [[I6:%.*]] = load float, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 3), align 4, !tbaa [[TBAA7]]
728 ; CGSCC-NEXT: [[ADD:%.*]] = fadd float [[I5]], [[I6]]
729 ; CGSCC-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5
730 ; CGSCC-NEXT: store float [[ADD]], ptr [[F3]], align 4, !tbaa [[TBAA11]]
731 ; CGSCC-NEXT: [[I7:%.*]] = load i32, ptr @Gs1, align 4, !tbaa [[TBAA12]]
732 ; CGSCC-NEXT: store i32 [[I7]], ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]]
733 ; CGSCC-NEXT: [[I8:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 1), align 4, !tbaa [[TBAA13]]
734 ; CGSCC-NEXT: [[MUL1:%.*]] = shl nsw i32 [[I8]], 1
735 ; CGSCC-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1
736 ; CGSCC-NEXT: store i32 [[MUL1]], ptr [[I2]], align 4, !tbaa [[TBAA13]]
737 ; CGSCC-NEXT: [[I9:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 2), align 4, !tbaa [[TBAA14]]
738 ; CGSCC-NEXT: [[I10:%.*]] = load i32, ptr @Gs1, align 4, !tbaa [[TBAA12]]
739 ; CGSCC-NEXT: [[ADD2:%.*]] = add nsw i32 [[I9]], [[I10]]
740 ; CGSCC-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2
741 ; CGSCC-NEXT: store i32 [[ADD2]], ptr [[I3]], align 4, !tbaa [[TBAA14]]
742 ; CGSCC-NEXT: ret void
745 store float 0x3FF19999A0000000, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 3), align 4, !tbaa !7
746 store float 0x40019999A0000000, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 4), align 4, !tbaa !10
747 store float 0x400A666660000000, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 5), align 4, !tbaa !11
748 call void @write_arg(ptr @Gs1, i32 1)
749 call void @write_arg(ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 1), i32 2)
750 call void @write_arg(ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 2), i32 3)
751 %i = load float, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 3), align 4, !tbaa !7
752 %f1 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 3
753 store float %i, ptr %f1, align 4, !tbaa !7
754 %i4 = load float, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 4), align 4, !tbaa !10
755 %mul = fmul float %i4, 2.000000e+00
756 %f2 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 4
757 store float %mul, ptr %f2, align 4, !tbaa !10
758 %i5 = load float, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 5), align 4, !tbaa !11
759 %i6 = load float, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 3), align 4, !tbaa !7
760 %add = fadd float %i5, %i6
761 %f3 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 5
762 store float %add, ptr %f3, align 4, !tbaa !11
763 %i7 = load i32, ptr @Gs1, align 4, !tbaa !12
764 store i32 %i7, ptr %agg.result, align 4, !tbaa !12
765 %i8 = load i32, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 1), align 4, !tbaa !13
766 %mul1 = shl nsw i32 %i8, 1
767 %i2 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 1
768 store i32 %mul1, ptr %i2, align 4, !tbaa !13
769 %i9 = load i32, ptr getelementptr inbounds (%struct.S, ptr @Gs1, i64 0, i32 2), align 4, !tbaa !14
770 %i10 = load i32, ptr @Gs1, align 4, !tbaa !12
771 %add2 = add nsw i32 %i9, %i10
772 %i3 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 2
773 store i32 %add2, ptr %i3, align 4, !tbaa !14
777 define i32 @test_range_merge1() {
778 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
779 ; TUNIT-LABEL: define {{[^@]+}}@test_range_merge1
780 ; TUNIT-SAME: () #[[ATTR5]] {
781 ; TUNIT-NEXT: ret i32 2
783 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
784 ; CGSCC-LABEL: define {{[^@]+}}@test_range_merge1
785 ; CGSCC-SAME: () #[[ATTR6:[0-9]+]] {
786 ; CGSCC-NEXT: ret i32 2
788 store <2 x i32> <i32 1, i32 1>, ptr @Vs1
789 store float 2.000000e+00, ptr getelementptr inbounds (%struct.S, ptr @Vs1, i64 0, i32 4)
790 %l0 = load i32, ptr @Vs1
791 %l1 = load i32, ptr getelementptr inbounds (%struct.S, ptr @Vs1, i64 0, i32 1)
792 %add = add i32 %l0, %l1
796 define i32 @test_range_merge2() {
797 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
798 ; TUNIT-LABEL: define {{[^@]+}}@test_range_merge2
799 ; TUNIT-SAME: () #[[ATTR3]] {
800 ; TUNIT-NEXT: store <2 x i32> <i32 3, i32 4>, ptr @Vs2, align 8
801 ; TUNIT-NEXT: [[L0:%.*]] = load i32, ptr @Vs2, align 4
802 ; TUNIT-NEXT: [[L1:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_S:%.*]], ptr @Vs2, i64 0, i32 1), align 4
803 ; TUNIT-NEXT: [[ADD:%.*]] = add i32 [[L0]], [[L1]]
804 ; TUNIT-NEXT: ret i32 [[ADD]]
806 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
807 ; CGSCC-LABEL: define {{[^@]+}}@test_range_merge2
808 ; CGSCC-SAME: () #[[ATTR5]] {
809 ; CGSCC-NEXT: store <2 x i32> <i32 3, i32 4>, ptr @Vs2, align 8
810 ; CGSCC-NEXT: [[L0:%.*]] = load i32, ptr @Vs2, align 4
811 ; CGSCC-NEXT: [[L1:%.*]] = load i32, ptr getelementptr inbounds ([[STRUCT_S:%.*]], ptr @Vs2, i64 0, i32 1), align 4
812 ; CGSCC-NEXT: [[ADD:%.*]] = add i32 [[L0]], [[L1]]
813 ; CGSCC-NEXT: ret i32 [[ADD]]
815 store <2 x i32> <i32 3, i32 4>, ptr @Vs2
816 store float 2.000000e+00, ptr getelementptr inbounds (%struct.S, ptr @Vs2, i64 0, i32 4)
817 %l0 = load i32, ptr @Vs2
818 %l1 = load i32, ptr getelementptr inbounds (%struct.S, ptr @Vs2, i64 0, i32 1)
819 %add = add i32 %l0, %l1
823 ; static char GBytes[1024];
824 ; void static_global_simplifiable_2(void) {
825 ; for (int i = 0; i < 100; ++i)
826 ; GBytes[i * 10] = 0;
827 ; for (int i = 0; i < 10; ++i)
828 ; ((float *)GBytes)[i * 10 + 1] = 0;
829 ; for (int i = 0; i < 20; ++i)
830 ; ((long long int *)GBytes)[i * 10 + 2] = 0;
832 ; write_arg((int *)&GBytes[500], 0);
834 ; for (int i = 0; i < 1024; ++i)
835 ; globalBytes[i] = GBytes[i];
838 define void @static_global_simplifiable_2() {
839 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
840 ; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_2
841 ; TUNIT-SAME: () #[[ATTR5]] {
843 ; TUNIT-NEXT: br label [[FOR_COND:%.*]]
845 ; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
846 ; TUNIT-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100
847 ; TUNIT-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
848 ; TUNIT: for.cond.cleanup:
849 ; TUNIT-NEXT: br label [[FOR_END:%.*]]
851 ; TUNIT-NEXT: [[I:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10
852 ; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 [[I]]
853 ; TUNIT-NEXT: br label [[FOR_INC]]
855 ; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
856 ; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP21:![0-9]+]]
858 ; TUNIT-NEXT: br label [[FOR_COND2:%.*]]
860 ; TUNIT-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ]
861 ; TUNIT-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10
862 ; TUNIT-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]]
863 ; TUNIT: for.cond.cleanup4:
864 ; TUNIT-NEXT: br label [[FOR_END11:%.*]]
866 ; TUNIT-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
867 ; TUNIT-NEXT: [[I16:%.*]] = or i64 [[I15]], 1
868 ; TUNIT-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr @GBytes, i64 [[I16]]
869 ; TUNIT-NEXT: br label [[FOR_INC9]]
871 ; TUNIT-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
872 ; TUNIT-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP22:![0-9]+]]
874 ; TUNIT-NEXT: br label [[FOR_COND13:%.*]]
876 ; TUNIT-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC21:%.*]] ], [ 0, [[FOR_END11]] ]
877 ; TUNIT-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20
878 ; TUNIT-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]]
879 ; TUNIT: for.cond.cleanup15:
880 ; TUNIT-NEXT: br label [[FOR_END23:%.*]]
882 ; TUNIT-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10
883 ; TUNIT-NEXT: [[I18:%.*]] = add nuw nsw i64 [[I17]], 2
884 ; TUNIT-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds i64, ptr @GBytes, i64 [[I18]]
885 ; TUNIT-NEXT: br label [[FOR_INC21]]
887 ; TUNIT-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
888 ; TUNIT-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP23:![0-9]+]]
890 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(524) getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 500), i32 noundef 0) #[[ATTR18]]
891 ; TUNIT-NEXT: br label [[FOR_COND25:%.*]]
893 ; TUNIT-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ]
894 ; TUNIT-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024
895 ; TUNIT-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY28:%.*]], label [[FOR_COND_CLEANUP27:%.*]]
896 ; TUNIT: for.cond.cleanup27:
897 ; TUNIT-NEXT: br label [[FOR_END35:%.*]]
899 ; TUNIT-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]]
900 ; TUNIT-NEXT: store i8 0, ptr [[ARRAYIDX32]], align 1, !tbaa [[TBAA19]]
901 ; TUNIT-NEXT: br label [[FOR_INC33]]
903 ; TUNIT-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1
904 ; TUNIT-NEXT: br label [[FOR_COND25]], !llvm.loop [[LOOP24:![0-9]+]]
906 ; TUNIT-NEXT: ret void
908 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
909 ; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_2
910 ; CGSCC-SAME: () #[[ATTR3]] {
912 ; CGSCC-NEXT: br label [[FOR_COND:%.*]]
914 ; CGSCC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
915 ; CGSCC-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100
916 ; CGSCC-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
917 ; CGSCC: for.cond.cleanup:
918 ; CGSCC-NEXT: br label [[FOR_END:%.*]]
920 ; CGSCC-NEXT: [[I:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10
921 ; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 [[I]]
922 ; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX]], align 2, !tbaa [[TBAA15]]
923 ; CGSCC-NEXT: br label [[FOR_INC]]
925 ; CGSCC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
926 ; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP24:![0-9]+]]
928 ; CGSCC-NEXT: br label [[FOR_COND2:%.*]]
930 ; CGSCC-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ]
931 ; CGSCC-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10
932 ; CGSCC-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]]
933 ; CGSCC: for.cond.cleanup4:
934 ; CGSCC-NEXT: br label [[FOR_END11:%.*]]
936 ; CGSCC-NEXT: [[I15:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
937 ; CGSCC-NEXT: [[I16:%.*]] = or i64 [[I15]], 1
938 ; CGSCC-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr @GBytes, i64 [[I16]]
939 ; CGSCC-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA18]]
940 ; CGSCC-NEXT: br label [[FOR_INC9]]
942 ; CGSCC-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
943 ; CGSCC-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP25:![0-9]+]]
945 ; CGSCC-NEXT: br label [[FOR_COND13:%.*]]
947 ; CGSCC-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC21:%.*]] ], [ 0, [[FOR_END11]] ]
948 ; CGSCC-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20
949 ; CGSCC-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]]
950 ; CGSCC: for.cond.cleanup15:
951 ; CGSCC-NEXT: br label [[FOR_END23:%.*]]
953 ; CGSCC-NEXT: [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10
954 ; CGSCC-NEXT: [[I18:%.*]] = add nuw nsw i64 [[I17]], 2
955 ; CGSCC-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds i64, ptr @GBytes, i64 [[I18]]
956 ; CGSCC-NEXT: store i64 0, ptr [[ARRAYIDX20]], align 16, !tbaa [[TBAA20]]
957 ; CGSCC-NEXT: br label [[FOR_INC21]]
959 ; CGSCC-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
960 ; CGSCC-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP26:![0-9]+]]
962 ; CGSCC-NEXT: store i8 0, ptr getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 1023), align 1, !tbaa [[TBAA15]]
963 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(524) getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 500), i32 noundef 0) #[[ATTR21]]
964 ; CGSCC-NEXT: br label [[FOR_COND25:%.*]]
966 ; CGSCC-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC33:%.*]] ], [ 0, [[FOR_END23]] ]
967 ; CGSCC-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024
968 ; CGSCC-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY28:%.*]], label [[FOR_COND_CLEANUP27:%.*]]
969 ; CGSCC: for.cond.cleanup27:
970 ; CGSCC-NEXT: br label [[FOR_END35:%.*]]
972 ; CGSCC-NEXT: [[ARRAYIDX30:%.*]] = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 [[INDVARS_IV12]]
973 ; CGSCC-NEXT: [[I19:%.*]] = load i8, ptr [[ARRAYIDX30]], align 1, !tbaa [[TBAA15]]
974 ; CGSCC-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]]
975 ; CGSCC-NEXT: store i8 [[I19]], ptr [[ARRAYIDX32]], align 1, !tbaa [[TBAA15]]
976 ; CGSCC-NEXT: br label [[FOR_INC33]]
978 ; CGSCC-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1
979 ; CGSCC-NEXT: br label [[FOR_COND25]], !llvm.loop [[LOOP27:![0-9]+]]
981 ; CGSCC-NEXT: ret void
986 for.cond: ; preds = %for.inc, %entry
987 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
988 %exitcond = icmp ne i64 %indvars.iv, 100
989 br i1 %exitcond, label %for.body, label %for.cond.cleanup
991 for.cond.cleanup: ; preds = %for.cond
994 for.body: ; preds = %for.cond
995 %i = mul nuw nsw i64 %indvars.iv, 10
996 %arrayidx = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 %i
997 store i8 0, ptr %arrayidx, align 2, !tbaa !15
1000 for.inc: ; preds = %for.body
1001 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
1002 br label %for.cond, !llvm.loop !24
1004 for.end: ; preds = %for.cond.cleanup
1007 for.cond2: ; preds = %for.inc9, %for.end
1008 %indvars.iv2 = phi i64 [ %indvars.iv.next3, %for.inc9 ], [ 0, %for.end ]
1009 %exitcond6 = icmp ne i64 %indvars.iv2, 10
1010 br i1 %exitcond6, label %for.body5, label %for.cond.cleanup4
1012 for.cond.cleanup4: ; preds = %for.cond2
1015 for.body5: ; preds = %for.cond2
1016 %i15 = mul nuw nsw i64 %indvars.iv2, 10
1017 %i16 = or i64 %i15, 1
1018 %arrayidx8 = getelementptr inbounds float, ptr @GBytes, i64 %i16
1019 store float 0.000000e+00, ptr %arrayidx8, align 4, !tbaa !18
1022 for.inc9: ; preds = %for.body5
1023 %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1
1024 br label %for.cond2, !llvm.loop !25
1026 for.end11: ; preds = %for.cond.cleanup4
1027 br label %for.cond13
1029 for.cond13: ; preds = %for.inc21, %for.end11
1030 %indvars.iv7 = phi i64 [ %indvars.iv.next8, %for.inc21 ], [ 0, %for.end11 ]
1031 %exitcond11 = icmp ne i64 %indvars.iv7, 20
1032 br i1 %exitcond11, label %for.body16, label %for.cond.cleanup15
1034 for.cond.cleanup15: ; preds = %for.cond13
1037 for.body16: ; preds = %for.cond13
1038 %i17 = mul nuw nsw i64 %indvars.iv7, 10
1039 %i18 = add nuw nsw i64 %i17, 2
1040 %arrayidx20 = getelementptr inbounds i64, ptr @GBytes, i64 %i18
1041 store i64 0, ptr %arrayidx20, align 16, !tbaa !20
1044 for.inc21: ; preds = %for.body16
1045 %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1
1046 br label %for.cond13, !llvm.loop !26
1048 for.end23: ; preds = %for.cond.cleanup15
1049 store i8 0, ptr getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 1023), align 1, !tbaa !15
1050 call void @write_arg(ptr getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 500), i32 0)
1051 br label %for.cond25
1053 for.cond25: ; preds = %for.inc33, %for.end23
1054 %indvars.iv12 = phi i64 [ %indvars.iv.next13, %for.inc33 ], [ 0, %for.end23 ]
1055 %exitcond14 = icmp ne i64 %indvars.iv12, 1024
1056 br i1 %exitcond14, label %for.body28, label %for.cond.cleanup27
1058 for.cond.cleanup27: ; preds = %for.cond25
1061 for.body28: ; preds = %for.cond25
1062 %arrayidx30 = getelementptr inbounds [1024 x i8], ptr @GBytes, i64 0, i64 %indvars.iv12
1063 %i19 = load i8, ptr %arrayidx30, align 1, !tbaa !15
1064 %arrayidx32 = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 %indvars.iv12
1065 store i8 %i19, ptr %arrayidx32, align 1, !tbaa !15
1068 for.inc33: ; preds = %for.body28
1069 %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1
1070 br label %for.cond25, !llvm.loop !27
1072 for.end35: ; preds = %for.cond.cleanup27
1077 ; int static_global_simplifiable_3() {
1081 define i32 @static_global_simplifiable_3() {
1082 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1083 ; TUNIT-LABEL: define {{[^@]+}}@static_global_simplifiable_3
1084 ; TUNIT-SAME: () #[[ATTR5]] {
1085 ; TUNIT-NEXT: store i32 1, ptr @Flag3, align 4, !tbaa [[TBAA3]]
1086 ; TUNIT-NEXT: ret i32 1
1088 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1089 ; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_3
1090 ; CGSCC-SAME: () #[[ATTR6]] {
1091 ; CGSCC-NEXT: store i32 1, ptr @Flag3, align 4, !tbaa [[TBAA3]]
1092 ; CGSCC-NEXT: ret i32 1
1094 store i32 1, ptr @Flag3, align 4, !tbaa !3
1095 %i = load i32, ptr @Flag3, align 4, !tbaa !3
1099 ; struct S noalias_arg_simplifiable_1(struct S s) {
1103 ; write_arg(&s.i1, 1);
1104 ; write_arg(&s.i2, 2);
1105 ; write_arg(&s.i3, 3);
1109 ; r.f3 = s.f3 + s.f1;
1112 ; r.i3 = s.i3 + s.i1;
1116 define void @noalias_arg_simplifiable_1(ptr noalias sret(%struct.S) align 4 %agg.result, ptr byval(%struct.S) align 8 %s) {
1117 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
1118 ; TUNIT-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1
1119 ; TUNIT-SAME: (ptr noalias nocapture nofree writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable_or_null(24) [[AGG_RESULT:%.*]], ptr noalias nocapture nofree nonnull byval([[STRUCT_S]]) align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR1]] {
1120 ; TUNIT-NEXT: entry:
1121 ; TUNIT-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
1122 ; TUNIT-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7]]
1123 ; TUNIT-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4
1124 ; TUNIT-NEXT: store float 0x40019999A0000000, ptr [[F2]], align 8, !tbaa [[TBAA10]]
1125 ; TUNIT-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5
1126 ; TUNIT-NEXT: store float 0x400A666660000000, ptr [[F3]], align 4, !tbaa [[TBAA11]]
1127 ; TUNIT-NEXT: call void @write_arg(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[S]], i32 noundef 1) #[[ATTR18]]
1128 ; TUNIT-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1
1129 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR18]]
1130 ; TUNIT-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
1131 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR18]]
1132 ; TUNIT-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
1133 ; TUNIT-NEXT: [[I:%.*]] = load float, ptr [[F11]], align 4, !tbaa [[TBAA7]]
1134 ; TUNIT-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3
1135 ; TUNIT-NEXT: store float [[I]], ptr [[F12]], align 4, !tbaa [[TBAA7]]
1136 ; TUNIT-NEXT: [[F23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4
1137 ; TUNIT-NEXT: [[I4:%.*]] = load float, ptr [[F23]], align 8, !tbaa [[TBAA10]]
1138 ; TUNIT-NEXT: [[MUL:%.*]] = fmul float [[I4]], 2.000000e+00
1139 ; TUNIT-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4
1140 ; TUNIT-NEXT: store float [[MUL]], ptr [[F24]], align 4, !tbaa [[TBAA10]]
1141 ; TUNIT-NEXT: [[F35:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5
1142 ; TUNIT-NEXT: [[I5:%.*]] = load float, ptr [[F35]], align 4, !tbaa [[TBAA11]]
1143 ; TUNIT-NEXT: [[F16:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
1144 ; TUNIT-NEXT: [[I6:%.*]] = load float, ptr [[F16]], align 4, !tbaa [[TBAA7]]
1145 ; TUNIT-NEXT: [[ADD:%.*]] = fadd float [[I5]], [[I6]]
1146 ; TUNIT-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5
1147 ; TUNIT-NEXT: store float [[ADD]], ptr [[F37]], align 4, !tbaa [[TBAA11]]
1148 ; TUNIT-NEXT: [[I7:%.*]] = load i32, ptr [[S]], align 8, !tbaa [[TBAA12]]
1149 ; TUNIT-NEXT: store i32 [[I7]], ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]]
1150 ; TUNIT-NEXT: [[I210:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1
1151 ; TUNIT-NEXT: [[I8:%.*]] = load i32, ptr [[I210]], align 4, !tbaa [[TBAA13]]
1152 ; TUNIT-NEXT: [[MUL11:%.*]] = shl nsw i32 [[I8]], 1
1153 ; TUNIT-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1
1154 ; TUNIT-NEXT: store i32 [[MUL11]], ptr [[I212]], align 4, !tbaa [[TBAA13]]
1155 ; TUNIT-NEXT: [[I313:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
1156 ; TUNIT-NEXT: [[I9:%.*]] = load i32, ptr [[I313]], align 8, !tbaa [[TBAA14]]
1157 ; TUNIT-NEXT: [[I10:%.*]] = load i32, ptr [[S]], align 8, !tbaa [[TBAA12]]
1158 ; TUNIT-NEXT: [[ADD15:%.*]] = add nsw i32 [[I9]], [[I10]]
1159 ; TUNIT-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2
1160 ; TUNIT-NEXT: store i32 [[ADD15]], ptr [[I316]], align 4, !tbaa [[TBAA14]]
1161 ; TUNIT-NEXT: ret void
1163 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
1164 ; CGSCC-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_1
1165 ; CGSCC-SAME: (ptr noalias nocapture nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 dereferenceable(24) [[AGG_RESULT:%.*]], ptr noalias nocapture nofree noundef nonnull byval([[STRUCT_S]]) align 8 dereferenceable(24) [[S:%.*]]) #[[ATTR1]] {
1166 ; CGSCC-NEXT: entry:
1167 ; CGSCC-NEXT: [[F1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
1168 ; CGSCC-NEXT: store float 0x3FF19999A0000000, ptr [[F1]], align 4, !tbaa [[TBAA7]]
1169 ; CGSCC-NEXT: [[F2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4
1170 ; CGSCC-NEXT: store float 0x40019999A0000000, ptr [[F2]], align 8, !tbaa [[TBAA10]]
1171 ; CGSCC-NEXT: [[F3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5
1172 ; CGSCC-NEXT: store float 0x400A666660000000, ptr [[F3]], align 4, !tbaa [[TBAA11]]
1173 ; CGSCC-NEXT: call void @write_arg(ptr noalias nocapture nofree noundef nonnull writeonly align 8 dereferenceable(24) [[S]], i32 noundef 1) #[[ATTR21]]
1174 ; CGSCC-NEXT: [[I2:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1
1175 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(20) [[I2]], i32 noundef 2) #[[ATTR21]]
1176 ; CGSCC-NEXT: [[I3:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
1177 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 8 dereferenceable(16) [[I3]], i32 noundef 3) #[[ATTR21]]
1178 ; CGSCC-NEXT: [[F11:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
1179 ; CGSCC-NEXT: [[I:%.*]] = load float, ptr [[F11]], align 4, !tbaa [[TBAA7]]
1180 ; CGSCC-NEXT: [[F12:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 3
1181 ; CGSCC-NEXT: store float [[I]], ptr [[F12]], align 4, !tbaa [[TBAA7]]
1182 ; CGSCC-NEXT: [[F23:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 4
1183 ; CGSCC-NEXT: [[I4:%.*]] = load float, ptr [[F23]], align 8, !tbaa [[TBAA10]]
1184 ; CGSCC-NEXT: [[MUL:%.*]] = fmul float [[I4]], 2.000000e+00
1185 ; CGSCC-NEXT: [[F24:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 4
1186 ; CGSCC-NEXT: store float [[MUL]], ptr [[F24]], align 4, !tbaa [[TBAA10]]
1187 ; CGSCC-NEXT: [[F35:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 5
1188 ; CGSCC-NEXT: [[I5:%.*]] = load float, ptr [[F35]], align 4, !tbaa [[TBAA11]]
1189 ; CGSCC-NEXT: [[F16:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 3
1190 ; CGSCC-NEXT: [[I6:%.*]] = load float, ptr [[F16]], align 4, !tbaa [[TBAA7]]
1191 ; CGSCC-NEXT: [[ADD:%.*]] = fadd float [[I5]], [[I6]]
1192 ; CGSCC-NEXT: [[F37:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 5
1193 ; CGSCC-NEXT: store float [[ADD]], ptr [[F37]], align 4, !tbaa [[TBAA11]]
1194 ; CGSCC-NEXT: [[I7:%.*]] = load i32, ptr [[S]], align 8, !tbaa [[TBAA12]]
1195 ; CGSCC-NEXT: store i32 [[I7]], ptr [[AGG_RESULT]], align 4, !tbaa [[TBAA12]]
1196 ; CGSCC-NEXT: [[I210:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 1
1197 ; CGSCC-NEXT: [[I8:%.*]] = load i32, ptr [[I210]], align 4, !tbaa [[TBAA13]]
1198 ; CGSCC-NEXT: [[MUL11:%.*]] = shl nsw i32 [[I8]], 1
1199 ; CGSCC-NEXT: [[I212:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 1
1200 ; CGSCC-NEXT: store i32 [[MUL11]], ptr [[I212]], align 4, !tbaa [[TBAA13]]
1201 ; CGSCC-NEXT: [[I313:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
1202 ; CGSCC-NEXT: [[I9:%.*]] = load i32, ptr [[I313]], align 8, !tbaa [[TBAA14]]
1203 ; CGSCC-NEXT: [[I10:%.*]] = load i32, ptr [[S]], align 8, !tbaa [[TBAA12]]
1204 ; CGSCC-NEXT: [[ADD15:%.*]] = add nsw i32 [[I9]], [[I10]]
1205 ; CGSCC-NEXT: [[I316:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[AGG_RESULT]], i64 0, i32 2
1206 ; CGSCC-NEXT: store i32 [[ADD15]], ptr [[I316]], align 4, !tbaa [[TBAA14]]
1207 ; CGSCC-NEXT: ret void
1210 %f1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3
1211 store float 0x3FF19999A0000000, ptr %f1, align 4, !tbaa !7
1212 %f2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 4
1213 store float 0x40019999A0000000, ptr %f2, align 8, !tbaa !10
1214 %f3 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 5
1215 store float 0x400A666660000000, ptr %f3, align 4, !tbaa !11
1216 call void @write_arg(ptr nonnull %s, i32 1)
1217 %i2 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1
1218 call void @write_arg(ptr nonnull %i2, i32 2)
1219 %i3 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
1220 call void @write_arg(ptr nonnull %i3, i32 3)
1221 %f11 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3
1222 %i = load float, ptr %f11, align 4, !tbaa !7
1223 %f12 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 3
1224 store float %i, ptr %f12, align 4, !tbaa !7
1225 %f23 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 4
1226 %i4 = load float, ptr %f23, align 8, !tbaa !10
1227 %mul = fmul float %i4, 2.000000e+00
1228 %f24 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 4
1229 store float %mul, ptr %f24, align 4, !tbaa !10
1230 %f35 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 5
1231 %i5 = load float, ptr %f35, align 4, !tbaa !11
1232 %f16 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 3
1233 %i6 = load float, ptr %f16, align 4, !tbaa !7
1234 %add = fadd float %i5, %i6
1235 %f37 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 5
1236 store float %add, ptr %f37, align 4, !tbaa !11
1237 %i7 = load i32, ptr %s, align 8, !tbaa !12
1238 store i32 %i7, ptr %agg.result, align 4, !tbaa !12
1239 %i210 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 1
1240 %i8 = load i32, ptr %i210, align 4, !tbaa !13
1241 %mul11 = shl nsw i32 %i8, 1
1242 %i212 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 1
1243 store i32 %mul11, ptr %i212, align 4, !tbaa !13
1244 %i313 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
1245 %i9 = load i32, ptr %i313, align 8, !tbaa !14
1246 %i10 = load i32, ptr %s, align 8, !tbaa !12
1247 %add15 = add nsw i32 %i9, %i10
1248 %i316 = getelementptr inbounds %struct.S, ptr %agg.result, i64 0, i32 2
1249 store i32 %add15, ptr %i316, align 4, !tbaa !14
1253 ; void noalias_arg_simplifiable_2(char Bytes[1024]) {
1254 ; for (int i = 0; i < 100; ++i)
1255 ; Bytes[i * 10] = 0;
1256 ; for (int i = 0; i < 10; ++i)
1257 ; ((float *)Bytes)[i * 10 + 1] = 0;
1258 ; for (int i = 0; i < 20; ++i)
1259 ; ((long long int *)Bytes)[i * 10 + 2] = 0;
1261 ; write_arg((int *)&Bytes[500], 0);
1263 ; for (int i = 0; i < 1024; ++i)
1264 ; globalBytes[i] = Bytes[i];
1267 define void @noalias_arg_simplifiable_2(ptr %Bytes) {
1268 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1269 ; TUNIT-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_2
1270 ; TUNIT-SAME: (ptr nocapture nofree [[BYTES:%.*]]) #[[ATTR3]] {
1271 ; TUNIT-NEXT: entry:
1272 ; TUNIT-NEXT: br label [[FOR_COND:%.*]]
1274 ; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
1275 ; TUNIT-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100
1276 ; TUNIT-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
1277 ; TUNIT: for.cond.cleanup:
1278 ; TUNIT-NEXT: br label [[FOR_END:%.*]]
1280 ; TUNIT-NEXT: [[I:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10
1281 ; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 [[I]]
1282 ; TUNIT-NEXT: store i8 0, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA19]]
1283 ; TUNIT-NEXT: br label [[FOR_INC]]
1285 ; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1286 ; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP25:![0-9]+]]
1288 ; TUNIT-NEXT: br label [[FOR_COND2:%.*]]
1290 ; TUNIT-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ]
1291 ; TUNIT-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10
1292 ; TUNIT-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]]
1293 ; TUNIT: for.cond.cleanup4:
1294 ; TUNIT-NEXT: br label [[FOR_END11:%.*]]
1296 ; TUNIT-NEXT: [[I16:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
1297 ; TUNIT-NEXT: [[I17:%.*]] = or i64 [[I16]], 1
1298 ; TUNIT-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I17]]
1299 ; TUNIT-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA26:![0-9]+]]
1300 ; TUNIT-NEXT: br label [[FOR_INC9]]
1302 ; TUNIT-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
1303 ; TUNIT-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP27:![0-9]+]]
1305 ; TUNIT-NEXT: br label [[FOR_COND13:%.*]]
1306 ; TUNIT: for.cond13:
1307 ; TUNIT-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC21:%.*]] ], [ 0, [[FOR_END11]] ]
1308 ; TUNIT-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20
1309 ; TUNIT-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]]
1310 ; TUNIT: for.cond.cleanup15:
1311 ; TUNIT-NEXT: br label [[FOR_END23:%.*]]
1312 ; TUNIT: for.body16:
1313 ; TUNIT-NEXT: [[I19:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10
1314 ; TUNIT-NEXT: [[I20:%.*]] = add nuw nsw i64 [[I19]], 2
1315 ; TUNIT-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I20]]
1316 ; TUNIT-NEXT: store i64 0, ptr [[ARRAYIDX20]], align 8, !tbaa [[TBAA28:![0-9]+]]
1317 ; TUNIT-NEXT: br label [[FOR_INC21]]
1319 ; TUNIT-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
1320 ; TUNIT-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP30:![0-9]+]]
1322 ; TUNIT-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 1023
1323 ; TUNIT-NEXT: store i8 0, ptr [[ARRAYIDX24]], align 1, !tbaa [[TBAA19]]
1324 ; TUNIT-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 500
1325 ; TUNIT-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 [[ARRAYIDX25]], i32 noundef 0) #[[ATTR18]]
1326 ; TUNIT-NEXT: br label [[FOR_COND27:%.*]]
1327 ; TUNIT: for.cond27:
1328 ; TUNIT-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ]
1329 ; TUNIT-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024
1330 ; TUNIT-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY30:%.*]], label [[FOR_COND_CLEANUP29:%.*]]
1331 ; TUNIT: for.cond.cleanup29:
1332 ; TUNIT-NEXT: br label [[FOR_END37:%.*]]
1333 ; TUNIT: for.body30:
1334 ; TUNIT-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 [[INDVARS_IV12]]
1335 ; TUNIT-NEXT: [[I22:%.*]] = load i8, ptr [[ARRAYIDX32]], align 1, !tbaa [[TBAA19]]
1336 ; TUNIT-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]]
1337 ; TUNIT-NEXT: store i8 [[I22]], ptr [[ARRAYIDX34]], align 1, !tbaa [[TBAA19]]
1338 ; TUNIT-NEXT: br label [[FOR_INC35]]
1340 ; TUNIT-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1
1341 ; TUNIT-NEXT: br label [[FOR_COND27]], !llvm.loop [[LOOP31:![0-9]+]]
1343 ; TUNIT-NEXT: ret void
1345 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
1346 ; CGSCC-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_2
1347 ; CGSCC-SAME: (ptr nocapture nofree [[BYTES:%.*]]) #[[ATTR3]] {
1348 ; CGSCC-NEXT: entry:
1349 ; CGSCC-NEXT: br label [[FOR_COND:%.*]]
1351 ; CGSCC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
1352 ; CGSCC-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], 100
1353 ; CGSCC-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
1354 ; CGSCC: for.cond.cleanup:
1355 ; CGSCC-NEXT: br label [[FOR_END:%.*]]
1357 ; CGSCC-NEXT: [[I:%.*]] = mul nuw nsw i64 [[INDVARS_IV]], 10
1358 ; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 [[I]]
1359 ; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA15]]
1360 ; CGSCC-NEXT: br label [[FOR_INC]]
1362 ; CGSCC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
1363 ; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP28:![0-9]+]]
1365 ; CGSCC-NEXT: br label [[FOR_COND2:%.*]]
1367 ; CGSCC-NEXT: [[INDVARS_IV2:%.*]] = phi i64 [ [[INDVARS_IV_NEXT3:%.*]], [[FOR_INC9:%.*]] ], [ 0, [[FOR_END]] ]
1368 ; CGSCC-NEXT: [[EXITCOND6:%.*]] = icmp ne i64 [[INDVARS_IV2]], 10
1369 ; CGSCC-NEXT: br i1 [[EXITCOND6]], label [[FOR_BODY5:%.*]], label [[FOR_COND_CLEANUP4:%.*]]
1370 ; CGSCC: for.cond.cleanup4:
1371 ; CGSCC-NEXT: br label [[FOR_END11:%.*]]
1373 ; CGSCC-NEXT: [[I16:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
1374 ; CGSCC-NEXT: [[I17:%.*]] = or i64 [[I16]], 1
1375 ; CGSCC-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I17]]
1376 ; CGSCC-NEXT: store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA18]]
1377 ; CGSCC-NEXT: br label [[FOR_INC9]]
1379 ; CGSCC-NEXT: [[INDVARS_IV_NEXT3]] = add nuw nsw i64 [[INDVARS_IV2]], 1
1380 ; CGSCC-NEXT: br label [[FOR_COND2]], !llvm.loop [[LOOP29:![0-9]+]]
1382 ; CGSCC-NEXT: br label [[FOR_COND13:%.*]]
1383 ; CGSCC: for.cond13:
1384 ; CGSCC-NEXT: [[INDVARS_IV7:%.*]] = phi i64 [ [[INDVARS_IV_NEXT8:%.*]], [[FOR_INC21:%.*]] ], [ 0, [[FOR_END11]] ]
1385 ; CGSCC-NEXT: [[EXITCOND11:%.*]] = icmp ne i64 [[INDVARS_IV7]], 20
1386 ; CGSCC-NEXT: br i1 [[EXITCOND11]], label [[FOR_BODY16:%.*]], label [[FOR_COND_CLEANUP15:%.*]]
1387 ; CGSCC: for.cond.cleanup15:
1388 ; CGSCC-NEXT: br label [[FOR_END23:%.*]]
1389 ; CGSCC: for.body16:
1390 ; CGSCC-NEXT: [[I19:%.*]] = mul nuw nsw i64 [[INDVARS_IV7]], 10
1391 ; CGSCC-NEXT: [[I20:%.*]] = add nuw nsw i64 [[I19]], 2
1392 ; CGSCC-NEXT: [[ARRAYIDX20:%.*]] = getelementptr inbounds i64, ptr [[BYTES]], i64 [[I20]]
1393 ; CGSCC-NEXT: store i64 0, ptr [[ARRAYIDX20]], align 8, !tbaa [[TBAA20]]
1394 ; CGSCC-NEXT: br label [[FOR_INC21]]
1396 ; CGSCC-NEXT: [[INDVARS_IV_NEXT8]] = add nuw nsw i64 [[INDVARS_IV7]], 1
1397 ; CGSCC-NEXT: br label [[FOR_COND13]], !llvm.loop [[LOOP30:![0-9]+]]
1399 ; CGSCC-NEXT: [[ARRAYIDX24:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 1023
1400 ; CGSCC-NEXT: store i8 0, ptr [[ARRAYIDX24]], align 1, !tbaa [[TBAA15]]
1401 ; CGSCC-NEXT: [[ARRAYIDX25:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 500
1402 ; CGSCC-NEXT: call void @write_arg(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[ARRAYIDX25]], i32 noundef 0) #[[ATTR21]]
1403 ; CGSCC-NEXT: br label [[FOR_COND27:%.*]]
1404 ; CGSCC: for.cond27:
1405 ; CGSCC-NEXT: [[INDVARS_IV12:%.*]] = phi i64 [ [[INDVARS_IV_NEXT13:%.*]], [[FOR_INC35:%.*]] ], [ 0, [[FOR_END23]] ]
1406 ; CGSCC-NEXT: [[EXITCOND14:%.*]] = icmp ne i64 [[INDVARS_IV12]], 1024
1407 ; CGSCC-NEXT: br i1 [[EXITCOND14]], label [[FOR_BODY30:%.*]], label [[FOR_COND_CLEANUP29:%.*]]
1408 ; CGSCC: for.cond.cleanup29:
1409 ; CGSCC-NEXT: br label [[FOR_END37:%.*]]
1410 ; CGSCC: for.body30:
1411 ; CGSCC-NEXT: [[ARRAYIDX32:%.*]] = getelementptr inbounds i8, ptr [[BYTES]], i64 [[INDVARS_IV12]]
1412 ; CGSCC-NEXT: [[I22:%.*]] = load i8, ptr [[ARRAYIDX32]], align 1, !tbaa [[TBAA15]]
1413 ; CGSCC-NEXT: [[ARRAYIDX34:%.*]] = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 [[INDVARS_IV12]]
1414 ; CGSCC-NEXT: store i8 [[I22]], ptr [[ARRAYIDX34]], align 1, !tbaa [[TBAA15]]
1415 ; CGSCC-NEXT: br label [[FOR_INC35]]
1417 ; CGSCC-NEXT: [[INDVARS_IV_NEXT13]] = add nuw nsw i64 [[INDVARS_IV12]], 1
1418 ; CGSCC-NEXT: br label [[FOR_COND27]], !llvm.loop [[LOOP31:![0-9]+]]
1420 ; CGSCC-NEXT: ret void
1425 for.cond: ; preds = %for.inc, %entry
1426 %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
1427 %exitcond = icmp ne i64 %indvars.iv, 100
1428 br i1 %exitcond, label %for.body, label %for.cond.cleanup
1430 for.cond.cleanup: ; preds = %for.cond
1433 for.body: ; preds = %for.cond
1434 %i = mul nuw nsw i64 %indvars.iv, 10
1435 %arrayidx = getelementptr inbounds i8, ptr %Bytes, i64 %i
1436 store i8 0, ptr %arrayidx, align 1, !tbaa !15
1439 for.inc: ; preds = %for.body
1440 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
1441 br label %for.cond, !llvm.loop !28
1443 for.end: ; preds = %for.cond.cleanup
1446 for.cond2: ; preds = %for.inc9, %for.end
1447 %indvars.iv2 = phi i64 [ %indvars.iv.next3, %for.inc9 ], [ 0, %for.end ]
1448 %exitcond6 = icmp ne i64 %indvars.iv2, 10
1449 br i1 %exitcond6, label %for.body5, label %for.cond.cleanup4
1451 for.cond.cleanup4: ; preds = %for.cond2
1454 for.body5: ; preds = %for.cond2
1455 %i16 = mul nuw nsw i64 %indvars.iv2, 10
1456 %i17 = or i64 %i16, 1
1457 %arrayidx8 = getelementptr inbounds float, ptr %Bytes, i64 %i17
1458 store float 0.000000e+00, ptr %arrayidx8, align 4, !tbaa !18
1461 for.inc9: ; preds = %for.body5
1462 %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1
1463 br label %for.cond2, !llvm.loop !29
1465 for.end11: ; preds = %for.cond.cleanup4
1466 br label %for.cond13
1468 for.cond13: ; preds = %for.inc21, %for.end11
1469 %indvars.iv7 = phi i64 [ %indvars.iv.next8, %for.inc21 ], [ 0, %for.end11 ]
1470 %exitcond11 = icmp ne i64 %indvars.iv7, 20
1471 br i1 %exitcond11, label %for.body16, label %for.cond.cleanup15
1473 for.cond.cleanup15: ; preds = %for.cond13
1476 for.body16: ; preds = %for.cond13
1477 %i19 = mul nuw nsw i64 %indvars.iv7, 10
1478 %i20 = add nuw nsw i64 %i19, 2
1479 %arrayidx20 = getelementptr inbounds i64, ptr %Bytes, i64 %i20
1480 store i64 0, ptr %arrayidx20, align 8, !tbaa !20
1483 for.inc21: ; preds = %for.body16
1484 %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1
1485 br label %for.cond13, !llvm.loop !30
1487 for.end23: ; preds = %for.cond.cleanup15
1488 %arrayidx24 = getelementptr inbounds i8, ptr %Bytes, i64 1023
1489 store i8 0, ptr %arrayidx24, align 1, !tbaa !15
1490 %arrayidx25 = getelementptr inbounds i8, ptr %Bytes, i64 500
1491 call void @write_arg(ptr nonnull %arrayidx25, i32 0)
1492 br label %for.cond27
1494 for.cond27: ; preds = %for.inc35, %for.end23
1495 %indvars.iv12 = phi i64 [ %indvars.iv.next13, %for.inc35 ], [ 0, %for.end23 ]
1496 %exitcond14 = icmp ne i64 %indvars.iv12, 1024
1497 br i1 %exitcond14, label %for.body30, label %for.cond.cleanup29
1499 for.cond.cleanup29: ; preds = %for.cond27
1502 for.body30: ; preds = %for.cond27
1503 %arrayidx32 = getelementptr inbounds i8, ptr %Bytes, i64 %indvars.iv12
1504 %i22 = load i8, ptr %arrayidx32, align 1, !tbaa !15
1505 %arrayidx34 = getelementptr inbounds [1024 x i8], ptr @globalBytes, i64 0, i64 %indvars.iv12
1506 store i8 %i22, ptr %arrayidx34, align 1, !tbaa !15
1509 for.inc35: ; preds = %for.body30
1510 %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1
1511 br label %for.cond27, !llvm.loop !31
1513 for.end37: ; preds = %for.cond.cleanup29
1517 ; int local_alloca_not_simplifiable_1() {
1526 define i32 @local_alloca_not_simplifiable_1() {
1527 ; TUNIT-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() {
1528 ; TUNIT-NEXT: entry:
1529 ; TUNIT-NEXT: [[X:%.*]] = alloca i32, align 4
1530 ; TUNIT-NEXT: [[Y:%.*]] = alloca i32, align 4
1531 ; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[X]]) #[[ATTR17]]
1532 ; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[Y]]) #[[ATTR17]]
1533 ; TUNIT-NEXT: store i32 1, ptr [[Y]], align 4, !tbaa [[TBAA3]]
1534 ; TUNIT-NEXT: store i32 1, ptr [[X]], align 4, !tbaa [[TBAA3]]
1535 ; TUNIT-NEXT: call void @escape(ptr noundef nonnull align 4 dereferenceable(4) [[X]])
1536 ; TUNIT-NEXT: call void @write_random(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Y]])
1537 ; TUNIT-NEXT: [[I3:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA3]]
1538 ; TUNIT-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0
1539 ; TUNIT-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1
1540 ; TUNIT-NEXT: [[I4:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA3]]
1541 ; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]]
1542 ; TUNIT-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]]
1543 ; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[Y]])
1544 ; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[X]])
1545 ; TUNIT-NEXT: ret i32 [[ADD1]]
1547 ; CGSCC-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_1() {
1548 ; CGSCC-NEXT: entry:
1549 ; CGSCC-NEXT: [[X:%.*]] = alloca i32, align 4
1550 ; CGSCC-NEXT: [[Y:%.*]] = alloca i32, align 4
1551 ; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[X]]) #[[ATTR20]]
1552 ; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[Y]]) #[[ATTR20]]
1553 ; CGSCC-NEXT: store i32 1, ptr [[Y]], align 4, !tbaa [[TBAA3]]
1554 ; CGSCC-NEXT: store i32 1, ptr [[X]], align 4, !tbaa [[TBAA3]]
1555 ; CGSCC-NEXT: call void @escape(ptr noundef nonnull align 4 dereferenceable(4) [[X]])
1556 ; CGSCC-NEXT: call void @write_random(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Y]])
1557 ; CGSCC-NEXT: [[I3:%.*]] = load i32, ptr [[X]], align 4, !tbaa [[TBAA3]]
1558 ; CGSCC-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[I3]], 0
1559 ; CGSCC-NEXT: [[COND:%.*]] = select i1 [[TOBOOL_NOT]], i32 2, i32 1
1560 ; CGSCC-NEXT: [[I4:%.*]] = load i32, ptr [[Y]], align 4, !tbaa [[TBAA3]]
1561 ; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[I3]], [[I4]]
1562 ; CGSCC-NEXT: [[ADD1:%.*]] = add nsw i32 [[ADD]], [[COND]]
1563 ; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[Y]])
1564 ; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 4, ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[X]])
1565 ; CGSCC-NEXT: ret i32 [[ADD1]]
1568 %X = alloca i32, align 4
1569 %Y = alloca i32, align 4
1570 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %X)
1571 call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %Y)
1572 store i32 1, ptr %Y, align 4, !tbaa !3
1573 store i32 1, ptr %X, align 4, !tbaa !3
1574 call void @escape(ptr nonnull %X)
1575 call void @write_random(ptr nonnull %Y)
1576 %i3 = load i32, ptr %X, align 4, !tbaa !3
1577 %tobool.not = icmp eq i32 %i3, 0
1578 %cond = select i1 %tobool.not, i32 2, i32 1
1579 %i4 = load i32, ptr %Y, align 4, !tbaa !3
1580 %add = add nsw i32 %i3, %i4
1581 %add1 = add nsw i32 %add, %cond
1582 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %Y)
1583 call void @llvm.lifetime.end.p0(i64 4, ptr nonnull %X)
1587 define i8 @local_alloca_not_simplifiable_2(i64 %index1, i64 %index2, i1 %cnd) {
1588 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1589 ; CHECK-LABEL: define {{[^@]+}}@local_alloca_not_simplifiable_2
1590 ; CHECK-SAME: (i64 [[INDEX1:%.*]], i64 [[INDEX2:%.*]], i1 noundef [[CND:%.*]]) #[[ATTR4]] {
1591 ; CHECK-NEXT: entry:
1592 ; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
1593 ; CHECK-NEXT: store i8 7, ptr [[BYTES]], align 16
1594 ; CHECK-NEXT: br i1 [[CND]], label [[LEFT:%.*]], label [[RIGHT:%.*]]
1596 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX1]]
1597 ; CHECK-NEXT: br label [[JOIN:%.*]]
1599 ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX2]]
1600 ; CHECK-NEXT: br label [[JOIN]]
1602 ; CHECK-NEXT: [[GEP_JOIN:%.*]] = phi ptr [ [[GEP1]], [[LEFT]] ], [ [[GEP2]], [[RIGHT]] ]
1603 ; CHECK-NEXT: store i8 9, ptr [[GEP_JOIN]], align 4
1604 ; CHECK-NEXT: [[I:%.*]] = load i8, ptr [[BYTES]], align 16
1605 ; CHECK-NEXT: ret i8 [[I]]
1608 %Bytes = alloca [1024 x i8], align 16
1609 store i8 7, ptr %Bytes, align 4
1610 br i1 %cnd, label %left, label %right
1612 left: ; preds = %entry
1613 %gep1 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %index1
1616 right: ; preds = %entry
1617 %gep2 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %index2
1620 join: ; preds = %right, %left
1621 %gep.join = phi ptr [ %gep1, %left ], [ %gep2, %right ]
1622 store i8 9, ptr %gep.join, align 4
1624 ; This load cannot be replaced by the value 7 from %entry, since the previous
1625 ; store interferes due to its unknown offset.
1626 %i = load i8, ptr %Bytes, align 4
1630 ; We could simplify these if we separate accessed bins wrt. alignment (here mod 4).
1631 define i32 @unknown_access_mixed_simplifiable(i32 %arg1, i32 %arg2) {
1632 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1633 ; CHECK-LABEL: define {{[^@]+}}@unknown_access_mixed_simplifiable
1634 ; CHECK-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]]) #[[ATTR4]] {
1635 ; CHECK-NEXT: entry:
1636 ; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 4
1637 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
1638 ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG1]]
1639 ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG2]]
1640 ; CHECK-NEXT: store i32 7, ptr [[GEP1]], align 4
1641 ; CHECK-NEXT: store i32 7, ptr [[GEP2]], align 4
1642 ; CHECK-NEXT: store i32 7, ptr [[GEP3]], align 4
1643 ; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[GEP1]], align 4
1644 ; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[GEP2]], align 4
1645 ; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[GEP3]], align 4
1646 ; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[L1]], [[L2]]
1647 ; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[L3]]
1648 ; CHECK-NEXT: ret i32 [[ADD2]]
1651 %s = alloca %struct.S, align 4
1652 %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
1653 %gep2 = getelementptr inbounds i32, ptr %s, i32 %arg1
1654 %gep3 = getelementptr inbounds i32, ptr %s, i32 %arg2
1655 store i32 7, ptr %gep1
1656 store i32 7, ptr %gep2
1657 store i32 7, ptr %gep3
1658 %l1 = load i32, ptr %gep1
1659 %l2 = load i32, ptr %gep2
1660 %l3 = load i32, ptr %gep3
1661 %add1 = add i32 %l1, %l2
1662 %add2 = add i32 %add1, %l3
1666 ; The access to bc4b could go anywhere, nothing is simplifiable.
1667 define i32 @unknown_access_mixed_not_simplifiable(i32 %arg1, i32 %arg2, i32 %arg3) {
1668 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
1669 ; CHECK-LABEL: define {{[^@]+}}@unknown_access_mixed_not_simplifiable
1670 ; CHECK-SAME: (i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]]) #[[ATTR4]] {
1671 ; CHECK-NEXT: entry:
1672 ; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 4
1673 ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds [[STRUCT_S]], ptr [[S]], i64 0, i32 2
1674 ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG1]]
1675 ; CHECK-NEXT: [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[S]], i32 [[ARG2]]
1676 ; CHECK-NEXT: [[GEP4:%.*]] = getelementptr inbounds i8, ptr [[S]], i32 [[ARG3]]
1677 ; CHECK-NEXT: store i32 7, ptr [[GEP1]], align 4
1678 ; CHECK-NEXT: store i32 7, ptr [[GEP2]], align 4
1679 ; CHECK-NEXT: store i32 7, ptr [[GEP3]], align 4
1680 ; CHECK-NEXT: store i32 7, ptr [[GEP4]], align 4
1681 ; CHECK-NEXT: [[L1:%.*]] = load i32, ptr [[GEP1]], align 4
1682 ; CHECK-NEXT: [[L2:%.*]] = load i32, ptr [[GEP2]], align 4
1683 ; CHECK-NEXT: [[L3:%.*]] = load i32, ptr [[GEP3]], align 4
1684 ; CHECK-NEXT: [[L4:%.*]] = load i32, ptr [[GEP4]], align 4
1685 ; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[L1]], [[L2]]
1686 ; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[L3]]
1687 ; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[L4]]
1688 ; CHECK-NEXT: ret i32 [[ADD3]]
1691 %s = alloca %struct.S, align 4
1692 %gep1 = getelementptr inbounds %struct.S, ptr %s, i64 0, i32 2
1693 %gep2 = getelementptr inbounds i32, ptr %s, i32 %arg1
1694 %gep3 = getelementptr inbounds i32, ptr %s, i32 %arg2
1695 %gep4 = getelementptr inbounds i8, ptr %s, i32 %arg3
1696 store i32 7, ptr %gep1
1697 store i32 7, ptr %gep2
1698 store i32 7, ptr %gep3
1699 store i32 7, ptr %gep4
1700 %l1 = load i32, ptr %gep1
1701 %l2 = load i32, ptr %gep2
1702 %l3 = load i32, ptr %gep3
1703 %l4 = load i32, ptr %gep4
1704 %add1 = add i32 %l1, %l2
1705 %add2 = add i32 %add1, %l3
1706 %add3 = add i32 %add2, %l4
1710 declare void @escape(ptr)
1713 ; int global_not_simplifiable_1(int cnd) {
1717 define i32 @global_not_simplifiable_1(i32 %cnd) {
1718 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
1719 ; TUNIT-LABEL: define {{[^@]+}}@global_not_simplifiable_1
1720 ; TUNIT-SAME: (i32 [[CND:%.*]]) #[[ATTR6:[0-9]+]] {
1721 ; TUNIT-NEXT: entry:
1722 ; TUNIT-NEXT: [[I:%.*]] = load i32, ptr @Flag0, align 4, !tbaa [[TBAA3]]
1723 ; TUNIT-NEXT: ret i32 [[I]]
1725 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
1726 ; CGSCC-LABEL: define {{[^@]+}}@global_not_simplifiable_1
1727 ; CGSCC-SAME: (i32 [[CND:%.*]]) #[[ATTR7:[0-9]+]] {
1728 ; CGSCC-NEXT: entry:
1729 ; CGSCC-NEXT: [[I:%.*]] = load i32, ptr @Flag0, align 4, !tbaa [[TBAA3]]
1730 ; CGSCC-NEXT: ret i32 [[I]]
1733 %i = load i32, ptr @Flag0, align 4, !tbaa !3
1737 ; static int Flag1 __attribute__((loader_uninitialized));
1738 ; int static_global_not_simplifiable_1(int cnd) {
1746 define i32 @static_global_not_simplifiable_1(i32 %cnd) {
1747 ; CHECK-LABEL: define {{[^@]+}}@static_global_not_simplifiable_1
1748 ; CHECK-SAME: (i32 [[CND:%.*]]) {
1749 ; CHECK-NEXT: entry:
1750 ; CHECK-NEXT: call void @sync()
1751 ; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[CND]], 0
1752 ; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
1754 ; CHECK-NEXT: br label [[IF_END]]
1756 ; CHECK-NEXT: ret i32 1
1759 %i = load i32, ptr @Flag1, align 4, !tbaa !3
1761 %tobool.not = icmp eq i32 %cnd, 0
1762 br i1 %tobool.not, label %if.end, label %if.then
1764 if.then: ; preds = %entry
1765 store i32 1, ptr @Flag1, align 4, !tbaa !3
1768 if.end: ; preds = %if.then, %entry
1772 declare void @sync()
1774 ; static int Flag2 __attribute__((loader_uninitialized));
1775 ; int static_global_simplifiable_4(int cnd) {
1782 define i32 @static_global_simplifiable_4(i32 %cnd) {
1783 ; CHECK-LABEL: define {{[^@]+}}@static_global_simplifiable_4
1784 ; CHECK-SAME: (i32 [[CND:%.*]]) {
1785 ; CHECK-NEXT: entry:
1786 ; CHECK-NEXT: store i32 1, ptr @Flag2, align 4, !tbaa [[TBAA3]]
1787 ; CHECK-NEXT: call void @sync()
1788 ; CHECK-NEXT: [[I:%.*]] = load i32, ptr @Flag2, align 4, !tbaa [[TBAA3]]
1789 ; CHECK-NEXT: store i32 2, ptr @Flag2, align 4, !tbaa [[TBAA3]]
1790 ; CHECK-NEXT: ret i32 [[I]]
1793 store i32 1, ptr @Flag2, align 4, !tbaa !3
1795 %i = load i32, ptr @Flag2, align 4, !tbaa !3
1796 store i32 2, ptr @Flag2, align 4, !tbaa !3
1800 ; static int Flag2 __attribute__((loader_uninitialized));
1801 ; int static_global_not_simplifiable_2(int cnd) {
1808 define i32 @static_global_not_simplifiable_2(i32 %cnd) {
1809 ; TUNIT-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2
1810 ; TUNIT-SAME: (i32 [[CND:%.*]]) {
1811 ; TUNIT-NEXT: entry:
1812 ; TUNIT-NEXT: store i32 1, ptr @Flag4, align 4, !tbaa [[TBAA3]]
1813 ; TUNIT-NEXT: call void @sync() #[[ATTR19:[0-9]+]]
1814 ; TUNIT-NEXT: [[I:%.*]] = load i32, ptr @Flag4, align 4, !tbaa [[TBAA3]]
1815 ; TUNIT-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[TBAA3]]
1816 ; TUNIT-NEXT: ret i32 [[I]]
1818 ; CGSCC-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2
1819 ; CGSCC-SAME: (i32 [[CND:%.*]]) {
1820 ; CGSCC-NEXT: entry:
1821 ; CGSCC-NEXT: store i32 1, ptr @Flag4, align 4, !tbaa [[TBAA3]]
1822 ; CGSCC-NEXT: call void @sync() #[[ATTR22:[0-9]+]]
1823 ; CGSCC-NEXT: [[I:%.*]] = load i32, ptr @Flag4, align 4, !tbaa [[TBAA3]]
1824 ; CGSCC-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[TBAA3]]
1825 ; CGSCC-NEXT: ret i32 [[I]]
1828 store i32 1, ptr @Flag4, align 4, !tbaa !3
1829 call void @sync() nocallback
1830 %i = load i32, ptr @Flag4, align 4, !tbaa !3
1831 store i32 2, ptr @Flag4, align 4, !tbaa !3
1834 define void @static_global_not_simplifiable_2_helper() {
1835 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1836 ; TUNIT-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2_helper
1837 ; TUNIT-SAME: () #[[ATTR5]] {
1838 ; TUNIT-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[TBAA3]]
1839 ; TUNIT-NEXT: ret void
1841 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1842 ; CGSCC-LABEL: define {{[^@]+}}@static_global_not_simplifiable_2_helper
1843 ; CGSCC-SAME: () #[[ATTR6]] {
1844 ; CGSCC-NEXT: store i32 2, ptr @Flag4, align 4, !tbaa [[TBAA3]]
1845 ; CGSCC-NEXT: ret void
1847 store i32 2, ptr @Flag4, align 4, !tbaa !3
1851 ; Similiar to static_global_simplifiable_3 but with a may-store.
1852 define i32 @static_global_not_simplifiable_3(i1 %c, ptr %p) {
1853 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1854 ; TUNIT-LABEL: define {{[^@]+}}@static_global_not_simplifiable_3
1855 ; TUNIT-SAME: (i1 [[C:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) #[[ATTR3]] {
1856 ; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], ptr @Flag3, ptr [[P]]
1857 ; TUNIT-NEXT: store i32 1, ptr [[SEL]], align 4, !tbaa [[TBAA3]]
1858 ; TUNIT-NEXT: [[I:%.*]] = load i32, ptr @Flag3, align 4, !tbaa [[TBAA3]]
1859 ; TUNIT-NEXT: ret i32 [[I]]
1861 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1862 ; CGSCC-LABEL: define {{[^@]+}}@static_global_not_simplifiable_3
1863 ; CGSCC-SAME: (i1 [[C:%.*]], ptr nocapture nofree writeonly [[P:%.*]]) #[[ATTR5]] {
1864 ; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], ptr @Flag3, ptr [[P]]
1865 ; CGSCC-NEXT: store i32 1, ptr [[SEL]], align 4, !tbaa [[TBAA3]]
1866 ; CGSCC-NEXT: [[I:%.*]] = load i32, ptr @Flag3, align 4, !tbaa [[TBAA3]]
1867 ; CGSCC-NEXT: ret i32 [[I]]
1869 %sel = select i1 %c, ptr @Flag3, ptr %p
1870 store i32 1, ptr %sel, align 4, !tbaa !3
1871 %i = load i32, ptr @Flag3, align 4, !tbaa !3
1876 ; int write_read{,_static,_static_undef}_global(void) {
1877 ; Gint{,static,_static_undef}1 = 7;
1880 ; void write{,_static,_static_undef}_global(void) {
1881 ; Gint{,static,_static_undef}2 = 7;
1883 ; int read{,_static,_static_undef}_global(void) {
1884 ; return Gint{,static,_static_undef}2;
1887 ; FIXME: We could replace these loads.
1888 define i32 @write_read_global() {
1889 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1890 ; TUNIT-LABEL: define {{[^@]+}}@write_read_global
1891 ; TUNIT-SAME: () #[[ATTR3]] {
1892 ; TUNIT-NEXT: store i32 7, ptr @Gint1, align 4
1893 ; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @Gint1, align 4
1894 ; TUNIT-NEXT: ret i32 [[L]]
1896 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
1897 ; CGSCC-LABEL: define {{[^@]+}}@write_read_global
1898 ; CGSCC-SAME: () #[[ATTR5]] {
1899 ; CGSCC-NEXT: store i32 7, ptr @Gint1, align 4
1900 ; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @Gint1, align 4
1901 ; CGSCC-NEXT: ret i32 [[L]]
1903 store i32 7, ptr @Gint1
1904 %l = load i32, ptr @Gint1
1907 define void @write_global() {
1908 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1909 ; TUNIT-LABEL: define {{[^@]+}}@write_global
1910 ; TUNIT-SAME: () #[[ATTR5]] {
1911 ; TUNIT-NEXT: store i32 7, ptr @Gint2, align 4
1912 ; TUNIT-NEXT: ret void
1914 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1915 ; CGSCC-LABEL: define {{[^@]+}}@write_global
1916 ; CGSCC-SAME: () #[[ATTR6]] {
1917 ; CGSCC-NEXT: store i32 7, ptr @Gint2, align 4
1918 ; CGSCC-NEXT: ret void
1920 store i32 7, ptr @Gint2
1923 define i32 @read_global() {
1924 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
1925 ; TUNIT-LABEL: define {{[^@]+}}@read_global
1926 ; TUNIT-SAME: () #[[ATTR6]] {
1927 ; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @Gint2, align 4
1928 ; TUNIT-NEXT: ret i32 [[L]]
1930 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
1931 ; CGSCC-LABEL: define {{[^@]+}}@read_global
1932 ; CGSCC-SAME: () #[[ATTR7]] {
1933 ; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @Gint2, align 4
1934 ; CGSCC-NEXT: ret i32 [[L]]
1936 %l = load i32, ptr @Gint2
1939 define i32 @write_read_static_global() {
1940 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1941 ; TUNIT-LABEL: define {{[^@]+}}@write_read_static_global
1942 ; TUNIT-SAME: () #[[ATTR5]] {
1943 ; TUNIT-NEXT: ret i32 7
1945 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1946 ; CGSCC-LABEL: define {{[^@]+}}@write_read_static_global
1947 ; CGSCC-SAME: () #[[ATTR6]] {
1948 ; CGSCC-NEXT: ret i32 7
1950 store i32 7, ptr @Gstatic_int1
1951 %l = load i32, ptr @Gstatic_int1
1954 define void @write_static_global() {
1955 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1956 ; TUNIT-LABEL: define {{[^@]+}}@write_static_global
1957 ; TUNIT-SAME: () #[[ATTR5]] {
1958 ; TUNIT-NEXT: store i32 7, ptr @Gstatic_int2, align 4
1959 ; TUNIT-NEXT: ret void
1961 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1962 ; CGSCC-LABEL: define {{[^@]+}}@write_static_global
1963 ; CGSCC-SAME: () #[[ATTR6]] {
1964 ; CGSCC-NEXT: store i32 7, ptr @Gstatic_int2, align 4
1965 ; CGSCC-NEXT: ret void
1967 store i32 7, ptr @Gstatic_int2
1970 define i32 @read_static_global() {
1971 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
1972 ; TUNIT-LABEL: define {{[^@]+}}@read_static_global
1973 ; TUNIT-SAME: () #[[ATTR6]] {
1974 ; TUNIT-NEXT: [[L:%.*]] = load i32, ptr @Gstatic_int2, align 4
1975 ; TUNIT-NEXT: ret i32 [[L]]
1977 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
1978 ; CGSCC-LABEL: define {{[^@]+}}@read_static_global
1979 ; CGSCC-SAME: () #[[ATTR7]] {
1980 ; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @Gstatic_int2, align 4
1981 ; CGSCC-NEXT: ret i32 [[L]]
1983 %l = load i32, ptr @Gstatic_int2
1986 define i32 @write_read_static_undef_global() {
1987 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1988 ; TUNIT-LABEL: define {{[^@]+}}@write_read_static_undef_global
1989 ; TUNIT-SAME: () #[[ATTR5]] {
1990 ; TUNIT-NEXT: ret i32 7
1992 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
1993 ; CGSCC-LABEL: define {{[^@]+}}@write_read_static_undef_global
1994 ; CGSCC-SAME: () #[[ATTR6]] {
1995 ; CGSCC-NEXT: ret i32 7
1997 store i32 7, ptr @Gstatic_undef_int1
1998 %l = load i32, ptr @Gstatic_undef_int1
2001 define void @write_static_undef_global() {
2002 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
2003 ; TUNIT-LABEL: define {{[^@]+}}@write_static_undef_global
2004 ; TUNIT-SAME: () #[[ATTR5]] {
2005 ; TUNIT-NEXT: ret void
2007 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write)
2008 ; CGSCC-LABEL: define {{[^@]+}}@write_static_undef_global
2009 ; CGSCC-SAME: () #[[ATTR6]] {
2010 ; CGSCC-NEXT: store i32 7, ptr @Gstatic_undef_int2, align 4
2011 ; CGSCC-NEXT: ret void
2013 store i32 7, ptr @Gstatic_undef_int2
2016 define i32 @read_static_undef_global() {
2017 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2018 ; CHECK-LABEL: define {{[^@]+}}@read_static_undef_global
2019 ; CHECK-SAME: () #[[ATTR4]] {
2020 ; CHECK-NEXT: ret i32 7
2022 %l = load i32, ptr @Gstatic_undef_int2
2026 define i32 @single_read_of_static_global() {
2027 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2028 ; CHECK-LABEL: define {{[^@]+}}@single_read_of_static_global
2029 ; CHECK-SAME: () #[[ATTR4]] {
2030 ; CHECK-NEXT: ret i32 0
2032 %l = load i32, ptr @Gstatic_int3
2036 define i8 @phi_store() {
2037 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2038 ; CHECK-LABEL: define {{[^@]+}}@phi_store
2039 ; CHECK-SAME: () #[[ATTR4]] {
2040 ; CHECK-NEXT: entry:
2041 ; CHECK-NEXT: [[A:%.*]] = alloca i16, align 2
2042 ; CHECK-NEXT: br label [[LOOP:%.*]]
2044 ; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
2045 ; CHECK-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
2046 ; CHECK-NEXT: store i8 1, ptr [[P]], align 1
2047 ; CHECK-NEXT: [[G]] = getelementptr i8, ptr [[P]], i64 1
2048 ; CHECK-NEXT: [[O]] = add nsw i8 [[I]], 1
2049 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 2
2050 ; CHECK-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
2052 ; CHECK-NEXT: [[S:%.*]] = getelementptr i8, ptr [[A]], i64 1
2053 ; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[S]], align 1
2054 ; CHECK-NEXT: ret i8 [[L]]
2060 %p = phi ptr [%a, %entry], [%g, %loop]
2061 %i = phi i8 [0, %entry], [%o, %loop]
2063 %g = getelementptr i8, ptr %p, i64 1
2064 %o = add nsw i8 %i, 1
2065 %c = icmp eq i8 %o, 2
2066 br i1 %c, label %end, label %loop
2068 %s = getelementptr i8, ptr %a, i64 1
2069 %l = load i8, ptr %s
2073 ; FIXME: This function returns 1.
2074 define i8 @phi_no_store_1() {
2076 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2077 ; TUNIT-LABEL: define {{[^@]+}}@phi_no_store_1
2078 ; TUNIT-SAME: () #[[ATTR3]] {
2079 ; TUNIT-NEXT: entry:
2080 ; TUNIT-NEXT: br label [[LOOP:%.*]]
2082 ; TUNIT-NEXT: [[P:%.*]] = phi ptr [ @a1, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
2083 ; TUNIT-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
2084 ; TUNIT-NEXT: store i8 1, ptr [[P]], align 1
2085 ; TUNIT-NEXT: [[G]] = getelementptr i8, ptr [[P]], i64 1
2086 ; TUNIT-NEXT: [[O]] = add nsw i8 [[I]], 1
2087 ; TUNIT-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 3
2088 ; TUNIT-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
2090 ; TUNIT-NEXT: [[S11:%.*]] = getelementptr i8, ptr @a1, i64 2
2091 ; TUNIT-NEXT: [[L11:%.*]] = load i8, ptr [[S11]], align 2
2092 ; TUNIT-NEXT: [[S12:%.*]] = getelementptr i8, ptr @a1, i64 3
2093 ; TUNIT-NEXT: [[L12:%.*]] = load i8, ptr [[S12]], align 1
2094 ; TUNIT-NEXT: [[ADD:%.*]] = add i8 [[L11]], [[L12]]
2095 ; TUNIT-NEXT: ret i8 [[ADD]]
2097 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2098 ; CGSCC-LABEL: define {{[^@]+}}@phi_no_store_1
2099 ; CGSCC-SAME: () #[[ATTR5]] {
2100 ; CGSCC-NEXT: entry:
2101 ; CGSCC-NEXT: br label [[LOOP:%.*]]
2103 ; CGSCC-NEXT: [[P:%.*]] = phi ptr [ @a1, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
2104 ; CGSCC-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
2105 ; CGSCC-NEXT: store i8 1, ptr [[P]], align 1
2106 ; CGSCC-NEXT: [[G]] = getelementptr i8, ptr [[P]], i64 1
2107 ; CGSCC-NEXT: [[O]] = add nsw i8 [[I]], 1
2108 ; CGSCC-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 3
2109 ; CGSCC-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
2111 ; CGSCC-NEXT: [[S11:%.*]] = getelementptr i8, ptr @a1, i64 2
2112 ; CGSCC-NEXT: [[L11:%.*]] = load i8, ptr [[S11]], align 2
2113 ; CGSCC-NEXT: [[S12:%.*]] = getelementptr i8, ptr @a1, i64 3
2114 ; CGSCC-NEXT: [[L12:%.*]] = load i8, ptr [[S12]], align 1
2115 ; CGSCC-NEXT: [[ADD:%.*]] = add i8 [[L11]], [[L12]]
2116 ; CGSCC-NEXT: ret i8 [[ADD]]
2121 %p = phi ptr [@a1, %entry], [%g, %loop]
2122 %i = phi i8 [0, %entry], [%o, %loop]
2124 %g = getelementptr i8, ptr %p, i64 1
2125 %o = add nsw i8 %i, 1
2126 %c = icmp eq i8 %o, 3
2127 br i1 %c, label %end, label %loop
2129 %s11 = getelementptr i8, ptr @a1, i64 2
2130 %l11 = load i8, ptr %s11
2131 %s12 = getelementptr i8, ptr @a1, i64 3
2132 %l12 = load i8, ptr %s12
2133 %add = add i8 %l11, %l12
2137 ; FIXME: This function returns 1.
2138 define i8 @phi_no_store_2() {
2140 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2141 ; TUNIT-LABEL: define {{[^@]+}}@phi_no_store_2
2142 ; TUNIT-SAME: () #[[ATTR3]] {
2143 ; TUNIT-NEXT: entry:
2144 ; TUNIT-NEXT: br label [[LOOP:%.*]]
2146 ; TUNIT-NEXT: [[P:%.*]] = phi ptr [ @a2, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
2147 ; TUNIT-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
2148 ; TUNIT-NEXT: store i8 1, ptr [[P]], align 1
2149 ; TUNIT-NEXT: [[G]] = getelementptr i8, ptr @a2, i64 2
2150 ; TUNIT-NEXT: [[O]] = add nsw i8 [[I]], 1
2151 ; TUNIT-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7
2152 ; TUNIT-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
2154 ; TUNIT-NEXT: [[S21:%.*]] = getelementptr i8, ptr @a2, i64 2
2155 ; TUNIT-NEXT: [[L21:%.*]] = load i8, ptr [[S21]], align 2
2156 ; TUNIT-NEXT: [[S22:%.*]] = getelementptr i8, ptr @a2, i64 3
2157 ; TUNIT-NEXT: [[L22:%.*]] = load i8, ptr [[S22]], align 1
2158 ; TUNIT-NEXT: [[ADD:%.*]] = add i8 [[L21]], [[L22]]
2159 ; TUNIT-NEXT: ret i8 [[ADD]]
2161 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2162 ; CGSCC-LABEL: define {{[^@]+}}@phi_no_store_2
2163 ; CGSCC-SAME: () #[[ATTR5]] {
2164 ; CGSCC-NEXT: entry:
2165 ; CGSCC-NEXT: br label [[LOOP:%.*]]
2167 ; CGSCC-NEXT: [[P:%.*]] = phi ptr [ @a2, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
2168 ; CGSCC-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
2169 ; CGSCC-NEXT: store i8 1, ptr [[P]], align 1
2170 ; CGSCC-NEXT: [[G]] = getelementptr i8, ptr @a2, i64 2
2171 ; CGSCC-NEXT: [[O]] = add nsw i8 [[I]], 1
2172 ; CGSCC-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7
2173 ; CGSCC-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
2175 ; CGSCC-NEXT: [[S21:%.*]] = getelementptr i8, ptr @a2, i64 2
2176 ; CGSCC-NEXT: [[L21:%.*]] = load i8, ptr [[S21]], align 2
2177 ; CGSCC-NEXT: [[S22:%.*]] = getelementptr i8, ptr @a2, i64 3
2178 ; CGSCC-NEXT: [[L22:%.*]] = load i8, ptr [[S22]], align 1
2179 ; CGSCC-NEXT: [[ADD:%.*]] = add i8 [[L21]], [[L22]]
2180 ; CGSCC-NEXT: ret i8 [[ADD]]
2185 %p = phi ptr [@a2, %entry], [%g, %loop]
2186 %i = phi i8 [0, %entry], [%o, %loop]
2188 %g = getelementptr i8, ptr @a2, i64 2
2189 %o = add nsw i8 %i, 1
2190 %c = icmp eq i8 %o, 7
2191 br i1 %c, label %end, label %loop
2193 %s21 = getelementptr i8, ptr @a2, i64 2
2194 %l21 = load i8, ptr %s21
2195 %s22 = getelementptr i8, ptr @a2, i64 3
2196 %l22 = load i8, ptr %s22
2197 %add = add i8 %l21, %l22
2201 define i8 @phi_no_store_3() {
2202 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2203 ; TUNIT-LABEL: define {{[^@]+}}@phi_no_store_3
2204 ; TUNIT-SAME: () #[[ATTR3]] {
2205 ; TUNIT-NEXT: entry:
2206 ; TUNIT-NEXT: [[S30:%.*]] = getelementptr i8, ptr @a3, i64 3
2207 ; TUNIT-NEXT: store i8 0, ptr [[S30]], align 1
2208 ; TUNIT-NEXT: br label [[LOOP:%.*]]
2210 ; TUNIT-NEXT: [[P:%.*]] = phi ptr [ @a3, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
2211 ; TUNIT-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
2212 ; TUNIT-NEXT: store i8 1, ptr [[P]], align 1
2213 ; TUNIT-NEXT: [[G]] = getelementptr i8, ptr @a3, i64 2
2214 ; TUNIT-NEXT: [[O]] = add nsw i8 [[I]], 1
2215 ; TUNIT-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7
2216 ; TUNIT-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
2218 ; TUNIT-NEXT: [[S31:%.*]] = getelementptr i8, ptr @a3, i64 2
2219 ; TUNIT-NEXT: [[L31:%.*]] = load i8, ptr [[S31]], align 2
2220 ; TUNIT-NEXT: [[S32:%.*]] = getelementptr i8, ptr @a3, i64 3
2221 ; TUNIT-NEXT: [[L32:%.*]] = load i8, ptr [[S32]], align 1
2222 ; TUNIT-NEXT: [[ADD:%.*]] = add i8 [[L31]], [[L32]]
2223 ; TUNIT-NEXT: [[S34:%.*]] = getelementptr i8, ptr @a3, i64 4
2224 ; TUNIT-NEXT: [[L34:%.*]] = load i8, ptr [[S34]], align 4
2225 ; TUNIT-NEXT: [[ADD2:%.*]] = add i8 [[ADD]], [[L34]]
2226 ; TUNIT-NEXT: ret i8 [[ADD2]]
2228 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2229 ; CGSCC-LABEL: define {{[^@]+}}@phi_no_store_3
2230 ; CGSCC-SAME: () #[[ATTR5]] {
2231 ; CGSCC-NEXT: entry:
2232 ; CGSCC-NEXT: [[S30:%.*]] = getelementptr i8, ptr @a3, i64 3
2233 ; CGSCC-NEXT: store i8 0, ptr [[S30]], align 1
2234 ; CGSCC-NEXT: br label [[LOOP:%.*]]
2236 ; CGSCC-NEXT: [[P:%.*]] = phi ptr [ @a3, [[ENTRY:%.*]] ], [ [[G:%.*]], [[LOOP]] ]
2237 ; CGSCC-NEXT: [[I:%.*]] = phi i8 [ 0, [[ENTRY]] ], [ [[O:%.*]], [[LOOP]] ]
2238 ; CGSCC-NEXT: store i8 1, ptr [[P]], align 1
2239 ; CGSCC-NEXT: [[G]] = getelementptr i8, ptr @a3, i64 2
2240 ; CGSCC-NEXT: [[O]] = add nsw i8 [[I]], 1
2241 ; CGSCC-NEXT: [[C:%.*]] = icmp eq i8 [[O]], 7
2242 ; CGSCC-NEXT: br i1 [[C]], label [[END:%.*]], label [[LOOP]]
2244 ; CGSCC-NEXT: [[S31:%.*]] = getelementptr i8, ptr @a3, i64 2
2245 ; CGSCC-NEXT: [[L31:%.*]] = load i8, ptr [[S31]], align 2
2246 ; CGSCC-NEXT: [[S32:%.*]] = getelementptr i8, ptr @a3, i64 3
2247 ; CGSCC-NEXT: [[L32:%.*]] = load i8, ptr [[S32]], align 1
2248 ; CGSCC-NEXT: [[ADD:%.*]] = add i8 [[L31]], [[L32]]
2249 ; CGSCC-NEXT: [[S34:%.*]] = getelementptr i8, ptr @a3, i64 4
2250 ; CGSCC-NEXT: [[L34:%.*]] = load i8, ptr [[S34]], align 4
2251 ; CGSCC-NEXT: [[ADD2:%.*]] = add i8 [[ADD]], [[L34]]
2252 ; CGSCC-NEXT: ret i8 [[ADD2]]
2255 %s30 = getelementptr i8, ptr @a3, i64 3
2256 store i8 0, ptr %s30
2259 %p = phi ptr [@a3, %entry], [%g, %loop]
2260 %i = phi i8 [0, %entry], [%o, %loop]
2262 %g = getelementptr i8, ptr @a3, i64 2
2263 %o = add nsw i8 %i, 1
2264 %c = icmp eq i8 %o, 7
2265 br i1 %c, label %end, label %loop
2267 %s31 = getelementptr i8, ptr @a3, i64 2
2268 %l31 = load i8, ptr %s31
2269 %s32 = getelementptr i8, ptr @a3, i64 3
2270 %l32 = load i8, ptr %s32
2271 %add = add i8 %l31, %l32
2272 %s34 = getelementptr i8, ptr @a3, i64 4
2273 %l34 = load i8, ptr %s34
2274 %add2 = add i8 %add, %l34
2278 define i8 @cast_and_load_1() {
2279 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2280 ; TUNIT-LABEL: define {{[^@]+}}@cast_and_load_1
2281 ; TUNIT-SAME: () #[[ATTR3]] {
2282 ; TUNIT-NEXT: store i32 42, ptr @bytes1, align 4
2283 ; TUNIT-NEXT: [[L:%.*]] = load i8, ptr @bytes1, align 4
2284 ; TUNIT-NEXT: ret i8 [[L]]
2286 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2287 ; CGSCC-LABEL: define {{[^@]+}}@cast_and_load_1
2288 ; CGSCC-SAME: () #[[ATTR5]] {
2289 ; CGSCC-NEXT: store i32 42, ptr @bytes1, align 4
2290 ; CGSCC-NEXT: [[L:%.*]] = load i8, ptr @bytes1, align 4
2291 ; CGSCC-NEXT: ret i8 [[L]]
2293 store i32 42, ptr @bytes1
2294 %l = load i8, ptr @bytes1
2298 define i64 @cast_and_load_2() {
2299 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2300 ; TUNIT-LABEL: define {{[^@]+}}@cast_and_load_2
2301 ; TUNIT-SAME: () #[[ATTR3]] {
2302 ; TUNIT-NEXT: store i32 42, ptr @bytes2, align 4
2303 ; TUNIT-NEXT: [[L:%.*]] = load i64, ptr @bytes2, align 4
2304 ; TUNIT-NEXT: ret i64 [[L]]
2306 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
2307 ; CGSCC-LABEL: define {{[^@]+}}@cast_and_load_2
2308 ; CGSCC-SAME: () #[[ATTR5]] {
2309 ; CGSCC-NEXT: store i32 42, ptr @bytes2, align 4
2310 ; CGSCC-NEXT: [[L:%.*]] = load i64, ptr @bytes2, align 4
2311 ; CGSCC-NEXT: ret i64 [[L]]
2313 store i32 42, ptr @bytes2
2314 %l = load i64, ptr @bytes2
2318 define void @recursive_load_store(i64 %N, i32 %v) {
2320 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(write)
2321 ; TUNIT-LABEL: define {{[^@]+}}@recursive_load_store
2322 ; TUNIT-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR7:[0-9]+]] {
2323 ; TUNIT-NEXT: entry:
2324 ; TUNIT-NEXT: br label [[FOR_COND:%.*]]
2326 ; TUNIT-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
2327 ; TUNIT-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]]
2328 ; TUNIT-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
2330 ; TUNIT-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
2331 ; TUNIT-NEXT: br label [[FOR_COND]]
2333 ; TUNIT-NEXT: ret void
2335 ; CGSCC: Function Attrs: nofree norecurse nosync nounwind memory(write)
2336 ; CGSCC-LABEL: define {{[^@]+}}@recursive_load_store
2337 ; CGSCC-SAME: (i64 [[N:%.*]], i32 [[V:%.*]]) #[[ATTR8:[0-9]+]] {
2338 ; CGSCC-NEXT: entry:
2339 ; CGSCC-NEXT: br label [[FOR_COND:%.*]]
2341 ; CGSCC-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY:%.*]] ], [ 0, [[ENTRY:%.*]] ]
2342 ; CGSCC-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDVARS_IV]], [[N]]
2343 ; CGSCC-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]]
2345 ; CGSCC-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
2346 ; CGSCC-NEXT: br label [[FOR_COND]]
2348 ; CGSCC-NEXT: ret void
2351 store i32 %v, ptr @rec_storage
2355 %indvars.iv = phi i64 [ %indvars.iv.next, %for.body ], [ 0, %entry ]
2356 %exitcond = icmp ne i64 %indvars.iv, %N
2357 br i1 %exitcond, label %for.body, label %for.end
2360 %ll = load i32, ptr @rec_storage
2361 store i32 %ll, ptr @rec_storage
2362 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
2366 %lr = load i32, ptr @rec_storage
2367 store i32 %lr, ptr @rec_storage
2371 define dso_local i32 @round_trip_malloc(i32 %x) {
2372 ; CHECK-LABEL: define {{[^@]+}}@round_trip_malloc
2373 ; CHECK-SAME: (i32 returned [[X:%.*]]) {
2374 ; CHECK-NEXT: entry:
2375 ; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1
2376 ; CHECK-NEXT: store i32 [[X]], ptr [[CALL_H2S]], align 4
2377 ; CHECK-NEXT: ret i32 [[X]]
2380 %call = call noalias ptr @malloc(i64 4) norecurse
2381 store i32 %x, ptr %call, align 4
2382 %0 = load i32, ptr %call, align 4
2383 call void @free(ptr %call) norecurse
2387 define dso_local i32 @round_trip_malloc_constant() {
2388 ; CHECK-LABEL: define {{[^@]+}}@round_trip_malloc_constant() {
2389 ; CHECK-NEXT: entry:
2390 ; CHECK-NEXT: ret i32 7
2393 %call = call noalias ptr @malloc(i64 4) norecurse
2394 store i32 7, ptr %call, align 4
2395 %0 = load i32, ptr %call, align 4
2396 call void @free(ptr %call) norecurse
2400 declare noalias ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc"
2402 declare void @free(ptr) allockind("free") "alloc-family"="malloc"
2404 define dso_local i32 @conditional_malloc(i32 %x) {
2405 ; CHECK-LABEL: define {{[^@]+}}@conditional_malloc
2406 ; CHECK-SAME: (i32 returned [[X:%.*]]) {
2407 ; CHECK-NEXT: entry:
2408 ; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1
2409 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
2410 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
2412 ; CHECK-NEXT: store i32 [[X]], ptr [[CALL_H2S]], align 4
2413 ; CHECK-NEXT: br label [[IF_END]]
2415 ; CHECK-NEXT: ret i32 [[X]]
2418 %call = call noalias ptr @malloc(i64 4) norecurse
2419 %tobool = icmp ne i32 %x, 0
2420 br i1 %tobool, label %if.then, label %if.end
2422 if.then: ; preds = %entry
2423 store i32 %x, ptr %call, align 4
2426 if.end: ; preds = %if.then, %entry
2427 %0 = load i32, ptr %call, align 4
2431 define dso_local i32 @round_trip_calloc(i32 %x) {
2432 ; CHECK-LABEL: define {{[^@]+}}@round_trip_calloc
2433 ; CHECK-SAME: (i32 returned [[X:%.*]]) {
2434 ; CHECK-NEXT: entry:
2435 ; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1
2436 ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false)
2437 ; CHECK-NEXT: store i32 [[X]], ptr [[CALL_H2S]], align 4
2438 ; CHECK-NEXT: ret i32 [[X]]
2441 %call = call noalias ptr @calloc(i64 4, i64 1) norecurse
2442 store i32 %x, ptr %call, align 4
2443 %0 = load i32, ptr %call, align 4
2447 define dso_local i32 @round_trip_calloc_constant() {
2448 ; CHECK-LABEL: define {{[^@]+}}@round_trip_calloc_constant() {
2449 ; CHECK-NEXT: entry:
2450 ; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1
2451 ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false)
2452 ; CHECK-NEXT: ret i32 11
2455 %call = call noalias ptr @calloc(i64 4, i64 1) norecurse
2456 store i32 11, ptr %call, align 4
2457 %0 = load i32, ptr %call, align 4
2461 declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0, 1) "alloc-family"="malloc"
2463 define dso_local i32 @conditional_calloc(i32 %x) {
2464 ; CHECK-LABEL: define {{[^@]+}}@conditional_calloc
2465 ; CHECK-SAME: (i32 [[X:%.*]]) {
2466 ; CHECK-NEXT: entry:
2467 ; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1
2468 ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false)
2469 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
2470 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
2472 ; CHECK-NEXT: store i32 [[X]], ptr [[CALL_H2S]], align 4
2473 ; CHECK-NEXT: br label [[IF_END]]
2475 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL_H2S]], align 4
2476 ; CHECK-NEXT: ret i32 [[TMP0]]
2479 %call = call noalias ptr @calloc(i64 1, i64 4) norecurse
2480 %tobool = icmp ne i32 %x, 0
2481 br i1 %tobool, label %if.end, label %if.then
2483 if.then: ; preds = %entry
2484 store i32 %x, ptr %call, align 4
2487 if.end: ; preds = %if.then, %entry
2488 %0 = load i32, ptr %call, align 4
2489 call void @free(ptr %call) norecurse
2493 define dso_local i32 @conditional_calloc_zero(i1 %c) {
2494 ; CHECK-LABEL: define {{[^@]+}}@conditional_calloc_zero
2495 ; CHECK-SAME: (i1 [[C:%.*]]) {
2496 ; CHECK-NEXT: entry:
2497 ; CHECK-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 4, align 1
2498 ; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr [[CALL_H2S]], i8 0, i64 4, i1 false)
2499 ; CHECK-NEXT: br i1 [[C]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
2501 ; CHECK-NEXT: br label [[IF_END]]
2503 ; CHECK-NEXT: ret i32 0
2506 %call = call noalias ptr @calloc(i64 1, i64 4) norecurse
2507 br i1 %c, label %if.end, label %if.then
2509 if.then: ; preds = %entry
2510 store i32 0, ptr %call, align 4
2513 if.end: ; preds = %if.then, %entry
2514 %0 = load i32, ptr %call, align 4
2515 call void @free(ptr %call) norecurse
2519 define dso_local ptr @malloc_like(i32 %s) {
2520 ; TUNIT-LABEL: define {{[^@]+}}@malloc_like
2521 ; TUNIT-SAME: (i32 [[S:%.*]]) {
2522 ; TUNIT-NEXT: entry:
2523 ; TUNIT-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64
2524 ; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR20:[0-9]+]]
2525 ; TUNIT-NEXT: ret ptr [[CALL]]
2527 ; CGSCC-LABEL: define {{[^@]+}}@malloc_like
2528 ; CGSCC-SAME: (i32 [[S:%.*]]) {
2529 ; CGSCC-NEXT: entry:
2530 ; CGSCC-NEXT: [[CONV:%.*]] = sext i32 [[S]] to i64
2531 ; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc(i64 [[CONV]]) #[[ATTR23:[0-9]+]]
2532 ; CGSCC-NEXT: ret ptr [[CALL]]
2535 %conv = sext i32 %s to i64
2536 %call = call noalias ptr @malloc(i64 %conv) norecurse
2540 define dso_local i32 @round_trip_malloc_like(i32 %x) {
2541 ; TUNIT-LABEL: define {{[^@]+}}@round_trip_malloc_like
2542 ; TUNIT-SAME: (i32 [[X:%.*]]) {
2543 ; TUNIT-NEXT: entry:
2544 ; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR20]]
2545 ; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4
2546 ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
2547 ; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
2548 ; TUNIT-NEXT: ret i32 [[TMP0]]
2550 ; CGSCC-LABEL: define {{[^@]+}}@round_trip_malloc_like
2551 ; CGSCC-SAME: (i32 [[X:%.*]]) {
2552 ; CGSCC-NEXT: entry:
2553 ; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @malloc_like(i32 noundef 4) #[[ATTR23]]
2554 ; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4
2555 ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
2556 ; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
2557 ; CGSCC-NEXT: ret i32 [[TMP0]]
2560 %call = call ptr @malloc_like(i32 4) norecurse
2561 store i32 %x, ptr %call, align 4
2562 %0 = load i32, ptr %call, align 4
2563 call void @free(ptr %call) norecurse
2567 define dso_local i32 @round_trip_unknown_alloc(i32 %x) {
2568 ; TUNIT-LABEL: define {{[^@]+}}@round_trip_unknown_alloc
2569 ; TUNIT-SAME: (i32 [[X:%.*]]) {
2570 ; TUNIT-NEXT: entry:
2571 ; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR20]]
2572 ; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4
2573 ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
2574 ; TUNIT-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
2575 ; TUNIT-NEXT: ret i32 [[TMP0]]
2577 ; CGSCC-LABEL: define {{[^@]+}}@round_trip_unknown_alloc
2578 ; CGSCC-SAME: (i32 [[X:%.*]]) {
2579 ; CGSCC-NEXT: entry:
2580 ; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR23]]
2581 ; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4
2582 ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
2583 ; CGSCC-NEXT: call void @free(ptr noundef nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
2584 ; CGSCC-NEXT: ret i32 [[TMP0]]
2587 %call = call ptr @unknown_alloc(i32 4) norecurse
2588 store i32 %x, ptr %call, align 4
2589 %0 = load i32, ptr %call, align 4
2590 call void @free(ptr %call) norecurse
2594 declare noalias ptr @unknown_alloc(i32)
2596 define dso_local i32 @conditional_unknown_alloc(i32 %x) {
2597 ; TUNIT-LABEL: define {{[^@]+}}@conditional_unknown_alloc
2598 ; TUNIT-SAME: (i32 [[X:%.*]]) {
2599 ; TUNIT-NEXT: entry:
2600 ; TUNIT-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR20]]
2601 ; TUNIT-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
2602 ; TUNIT-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
2604 ; TUNIT-NEXT: store i32 [[X]], ptr [[CALL]], align 4
2605 ; TUNIT-NEXT: br label [[IF_END]]
2607 ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
2608 ; TUNIT-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR20]]
2609 ; TUNIT-NEXT: ret i32 [[TMP0]]
2611 ; CGSCC-LABEL: define {{[^@]+}}@conditional_unknown_alloc
2612 ; CGSCC-SAME: (i32 [[X:%.*]]) {
2613 ; CGSCC-NEXT: entry:
2614 ; CGSCC-NEXT: [[CALL:%.*]] = call noalias ptr @unknown_alloc(i32 noundef 4) #[[ATTR23]]
2615 ; CGSCC-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[X]], 0
2616 ; CGSCC-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
2618 ; CGSCC-NEXT: store i32 [[X]], ptr [[CALL]], align 4
2619 ; CGSCC-NEXT: br label [[IF_END]]
2621 ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[CALL]], align 4
2622 ; CGSCC-NEXT: call void @free(ptr nonnull align 4 dereferenceable(4) [[CALL]]) #[[ATTR23]]
2623 ; CGSCC-NEXT: ret i32 [[TMP0]]
2626 %call = call noalias ptr @unknown_alloc(i32 4) norecurse
2627 %tobool = icmp ne i32 %x, 0
2628 br i1 %tobool, label %if.end, label %if.then
2630 if.then: ; preds = %entry
2631 store i32 %x, ptr %call, align 4
2634 if.end: ; preds = %if.then, %entry
2635 %0 = load i32, ptr %call, align 4
2636 call void @free(ptr %call) norecurse
2640 %struct.STy = type { ptr, ptr, ptr }
2642 @global = internal global %struct.STy zeroinitializer, align 8
2644 ; We mark %dst as writeonly and %src as readonly, that is (for now) all we can expect.
2645 define dso_local void @test_nested_memory(ptr %dst, ptr %src) {
2646 ; TUNIT-LABEL: define {{[^@]+}}@test_nested_memory
2647 ; TUNIT-SAME: (ptr nocapture nofree writeonly [[DST:%.*]], ptr nocapture nofree readonly [[SRC:%.*]]) {
2648 ; TUNIT-NEXT: entry:
2649 ; TUNIT-NEXT: [[CALL_H2S:%.*]] = alloca i8, i64 24, align 1
2650 ; TUNIT-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8
2651 ; TUNIT-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[LOCAL]], i64 0, i32 2
2652 ; TUNIT-NEXT: store ptr @global, ptr [[INNER]], align 8
2653 ; TUNIT-NEXT: store ptr [[DST]], ptr [[CALL_H2S]], align 8
2654 ; TUNIT-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, ptr [[CALL_H2S]], i64 8
2655 ; TUNIT-NEXT: store ptr [[SRC]], ptr [[SRC2]], align 8
2656 ; TUNIT-NEXT: store ptr [[CALL_H2S]], ptr getelementptr inbounds ([[STRUCT_STY]], ptr @global, i64 0, i32 2), align 8
2657 ; TUNIT-NEXT: [[TMP0:%.*]] = load ptr, ptr [[LOCAL]], align 8
2658 ; TUNIT-NEXT: [[LOCAL_B8:%.*]] = getelementptr i8, ptr [[LOCAL]], i64 8
2659 ; TUNIT-NEXT: [[TMP1:%.*]] = load ptr, ptr [[LOCAL_B8]], align 8
2660 ; TUNIT-NEXT: [[LOCAL_B16:%.*]] = getelementptr i8, ptr [[LOCAL]], i64 16
2661 ; TUNIT-NEXT: [[TMP2:%.*]] = load ptr, ptr [[LOCAL_B16]], align 8
2662 ; TUNIT-NEXT: call fastcc void @nested_memory_callee(ptr [[TMP0]], ptr [[TMP1]], ptr [[TMP2]]) #[[ATTR21:[0-9]+]]
2663 ; TUNIT-NEXT: ret void
2665 ; CGSCC-LABEL: define {{[^@]+}}@test_nested_memory
2666 ; CGSCC-SAME: (ptr nofree [[DST:%.*]], ptr nofree [[SRC:%.*]]) {
2667 ; CGSCC-NEXT: entry:
2668 ; CGSCC-NEXT: [[LOCAL:%.*]] = alloca [[STRUCT_STY:%.*]], align 8
2669 ; CGSCC-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[LOCAL]], i64 0, i32 2
2670 ; CGSCC-NEXT: [[CALL:%.*]] = call noalias dereferenceable_or_null(24) ptr @malloc(i64 noundef 24)
2671 ; CGSCC-NEXT: store ptr [[DST]], ptr [[CALL]], align 8
2672 ; CGSCC-NEXT: [[SRC2:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
2673 ; CGSCC-NEXT: store ptr [[SRC]], ptr [[SRC2]], align 8
2674 ; CGSCC-NEXT: store ptr [[CALL]], ptr getelementptr inbounds ([[STRUCT_STY]], ptr @global, i64 0, i32 2), align 8
2675 ; CGSCC-NEXT: call fastcc void @nested_memory_callee(ptr nofree align 4294967296 undef, ptr nofree align 4294967296 undef, ptr nofree noundef nonnull align 8 dereferenceable(24) @global) #[[ATTR24:[0-9]+]]
2676 ; CGSCC-NEXT: ret void
2679 %local = alloca %struct.STy, align 8
2680 %inner = getelementptr inbounds %struct.STy, ptr %local, i64 0, i32 2
2681 store ptr @global, ptr %inner, align 8
2682 %call = call noalias dereferenceable_or_null(24) ptr @malloc(i64 24) #4
2683 store ptr %dst, ptr %call, align 8
2684 %src2 = getelementptr inbounds i8, ptr %call, i64 8
2685 store ptr %src, ptr %src2, align 8
2686 store ptr %call, ptr getelementptr inbounds (%struct.STy, ptr @global, i64 0, i32 2), align 8
2687 call fastcc void @nested_memory_callee(ptr nonnull %local)
2691 define internal fastcc void @nested_memory_callee(ptr nocapture readonly %S) nofree norecurse nounwind uwtable {
2692 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn uwtable
2693 ; TUNIT-LABEL: define {{[^@]+}}@nested_memory_callee
2694 ; TUNIT-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]], ptr [[TMP2:%.*]]) #[[ATTR11:[0-9]+]] {
2695 ; TUNIT-NEXT: entry:
2696 ; TUNIT-NEXT: [[S_PRIV:%.*]] = alloca [[STRUCT_STY:%.*]], align 8
2697 ; TUNIT-NEXT: store ptr [[TMP0]], ptr [[S_PRIV]], align 8
2698 ; TUNIT-NEXT: [[S_PRIV_B8:%.*]] = getelementptr i8, ptr [[S_PRIV]], i64 8
2699 ; TUNIT-NEXT: store ptr [[TMP1]], ptr [[S_PRIV_B8]], align 8
2700 ; TUNIT-NEXT: [[S_PRIV_B16:%.*]] = getelementptr i8, ptr [[S_PRIV]], i64 16
2701 ; TUNIT-NEXT: store ptr [[TMP2]], ptr [[S_PRIV_B16]], align 8
2702 ; TUNIT-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[S_PRIV]], i64 0, i32 2
2703 ; TUNIT-NEXT: [[TMP3:%.*]] = load ptr, ptr [[INNER]], align 8
2704 ; TUNIT-NEXT: [[INNER1:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[TMP3]], i64 0, i32 2
2705 ; TUNIT-NEXT: [[TMP4:%.*]] = load ptr, ptr [[INNER1]], align 8
2706 ; TUNIT-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[TMP4]], i64 0, i32 1
2707 ; TUNIT-NEXT: [[TMP5:%.*]] = load ptr, ptr [[SRC]], align 8
2708 ; TUNIT-NEXT: [[TMP6:%.*]] = load double, ptr [[TMP5]], align 8
2709 ; TUNIT-NEXT: [[CONV:%.*]] = fptrunc double [[TMP6]] to float
2710 ; TUNIT-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP4]], align 8
2711 ; TUNIT-NEXT: store float [[CONV]], ptr [[TMP7]], align 4
2712 ; TUNIT-NEXT: ret void
2714 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn uwtable
2715 ; CGSCC-LABEL: define {{[^@]+}}@nested_memory_callee
2716 ; CGSCC-SAME: (ptr nofree [[TMP0:%.*]], ptr nofree [[TMP1:%.*]], ptr nofree [[TMP2:%.*]]) #[[ATTR12:[0-9]+]] {
2717 ; CGSCC-NEXT: entry:
2718 ; CGSCC-NEXT: [[S_PRIV:%.*]] = alloca [[STRUCT_STY:%.*]], align 8
2719 ; CGSCC-NEXT: store ptr [[TMP0]], ptr [[S_PRIV]], align 8
2720 ; CGSCC-NEXT: [[S_PRIV_B8:%.*]] = getelementptr i8, ptr [[S_PRIV]], i64 8
2721 ; CGSCC-NEXT: store ptr [[TMP1]], ptr [[S_PRIV_B8]], align 8
2722 ; CGSCC-NEXT: [[S_PRIV_B16:%.*]] = getelementptr i8, ptr [[S_PRIV]], i64 16
2723 ; CGSCC-NEXT: store ptr [[TMP2]], ptr [[S_PRIV_B16]], align 8
2724 ; CGSCC-NEXT: [[INNER:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[S_PRIV]], i64 0, i32 2
2725 ; CGSCC-NEXT: [[TMP3:%.*]] = load ptr, ptr [[INNER]], align 8
2726 ; CGSCC-NEXT: [[INNER1:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[TMP3]], i64 0, i32 2
2727 ; CGSCC-NEXT: [[TMP4:%.*]] = load ptr, ptr [[INNER1]], align 8
2728 ; CGSCC-NEXT: [[SRC:%.*]] = getelementptr inbounds [[STRUCT_STY]], ptr [[TMP4]], i64 0, i32 1
2729 ; CGSCC-NEXT: [[TMP5:%.*]] = load ptr, ptr [[SRC]], align 8
2730 ; CGSCC-NEXT: [[TMP6:%.*]] = load double, ptr [[TMP5]], align 8
2731 ; CGSCC-NEXT: [[CONV:%.*]] = fptrunc double [[TMP6]] to float
2732 ; CGSCC-NEXT: [[TMP7:%.*]] = load ptr, ptr [[TMP4]], align 8
2733 ; CGSCC-NEXT: store float [[CONV]], ptr [[TMP7]], align 4
2734 ; CGSCC-NEXT: ret void
2737 %inner = getelementptr inbounds %struct.STy, ptr %S, i64 0, i32 2
2738 %0 = load ptr, ptr %inner, align 8
2739 %inner1 = getelementptr inbounds %struct.STy, ptr %0, i64 0, i32 2
2740 %1 = load ptr, ptr %inner1, align 8
2741 %src = getelementptr inbounds %struct.STy, ptr %1, i64 0, i32 1
2742 %2 = load ptr, ptr %src, align 8
2743 %3 = load double, ptr %2, align 8
2744 %conv = fptrunc double %3 to float
2745 %4 = load ptr, ptr %1, align 8
2746 store float %conv, ptr %4, align 4
2750 ; Make sure the access %1 is not forwarded to the loads %2 and %3 as the indices are
2751 ; varying and the accesses thus not "exact". This used to simplify %cmp12 to true.
2752 define hidden void @no_propagation_of_unknown_index_access(ptr %in, ptr %out, i32 %idx) #0 {
2753 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
2754 ; TUNIT-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access
2755 ; TUNIT-SAME: (ptr nocapture nofree readonly [[IN:%.*]], ptr nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR1]] {
2756 ; TUNIT-NEXT: entry:
2757 ; TUNIT-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16
2758 ; TUNIT-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF]]) #[[ATTR17]]
2759 ; TUNIT-NEXT: br label [[FOR_COND:%.*]]
2761 ; TUNIT-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
2762 ; TUNIT-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128
2763 ; TUNIT-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
2764 ; TUNIT: for.cond.cleanup:
2765 ; TUNIT-NEXT: br label [[FOR_COND4:%.*]]
2767 ; TUNIT-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64
2768 ; TUNIT-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[IN]], i64 [[IDXPROM]]
2769 ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
2770 ; TUNIT-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM]]
2771 ; TUNIT-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4
2772 ; TUNIT-NEXT: [[INC]] = add nsw i32 [[I_0]], 1
2773 ; TUNIT-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]]
2775 ; TUNIT-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ]
2776 ; TUNIT-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128
2777 ; TUNIT-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]]
2778 ; TUNIT: for.cond.cleanup6:
2779 ; TUNIT-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF]]) #[[ATTR17]]
2780 ; TUNIT-NEXT: ret void
2782 ; TUNIT-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64
2783 ; TUNIT-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM8]]
2784 ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX9]], align 4
2785 ; TUNIT-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64
2786 ; TUNIT-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM10]]
2787 ; TUNIT-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4
2788 ; TUNIT-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]]
2789 ; TUNIT-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32
2790 ; TUNIT-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[OUT]], i64 [[IDXPROM8]]
2791 ; TUNIT-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX14]], align 4
2792 ; TUNIT-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1
2793 ; TUNIT-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]]
2795 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
2796 ; CGSCC-LABEL: define {{[^@]+}}@no_propagation_of_unknown_index_access
2797 ; CGSCC-SAME: (ptr nocapture nofree readonly [[IN:%.*]], ptr nocapture nofree writeonly [[OUT:%.*]], i32 [[IDX:%.*]]) #[[ATTR13:[0-9]+]] {
2798 ; CGSCC-NEXT: entry:
2799 ; CGSCC-NEXT: [[BUF:%.*]] = alloca [128 x i32], align 16
2800 ; CGSCC-NEXT: call void @llvm.lifetime.start.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF]]) #[[ATTR20]]
2801 ; CGSCC-NEXT: br label [[FOR_COND:%.*]]
2803 ; CGSCC-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]
2804 ; CGSCC-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], 128
2805 ; CGSCC-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
2806 ; CGSCC: for.cond.cleanup:
2807 ; CGSCC-NEXT: br label [[FOR_COND4:%.*]]
2809 ; CGSCC-NEXT: [[IDXPROM:%.*]] = sext i32 [[I_0]] to i64
2810 ; CGSCC-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[IN]], i64 [[IDXPROM]]
2811 ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
2812 ; CGSCC-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM]]
2813 ; CGSCC-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4
2814 ; CGSCC-NEXT: [[INC]] = add nsw i32 [[I_0]], 1
2815 ; CGSCC-NEXT: br label [[FOR_COND]], !llvm.loop [[TBAA10]]
2817 ; CGSCC-NEXT: [[I3_0:%.*]] = phi i32 [ 0, [[FOR_COND_CLEANUP]] ], [ [[INC16:%.*]], [[FOR_BODY7:%.*]] ]
2818 ; CGSCC-NEXT: [[CMP5:%.*]] = icmp slt i32 [[I3_0]], 128
2819 ; CGSCC-NEXT: br i1 [[CMP5]], label [[FOR_BODY7]], label [[FOR_COND_CLEANUP6:%.*]]
2820 ; CGSCC: for.cond.cleanup6:
2821 ; CGSCC-NEXT: call void @llvm.lifetime.end.p0(i64 noundef 512, ptr noalias nocapture nofree noundef nonnull align 16 dereferenceable(512) [[BUF]]) #[[ATTR20]]
2822 ; CGSCC-NEXT: ret void
2824 ; CGSCC-NEXT: [[IDXPROM8:%.*]] = sext i32 [[I3_0]] to i64
2825 ; CGSCC-NEXT: [[ARRAYIDX9:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM8]]
2826 ; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX9]], align 4
2827 ; CGSCC-NEXT: [[IDXPROM10:%.*]] = sext i32 [[IDX]] to i64
2828 ; CGSCC-NEXT: [[ARRAYIDX11:%.*]] = getelementptr inbounds [128 x i32], ptr [[BUF]], i64 0, i64 [[IDXPROM10]]
2829 ; CGSCC-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4
2830 ; CGSCC-NEXT: [[CMP12:%.*]] = icmp sle i32 [[TMP1]], [[TMP2]]
2831 ; CGSCC-NEXT: [[CONV:%.*]] = zext i1 [[CMP12]] to i32
2832 ; CGSCC-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds i32, ptr [[OUT]], i64 [[IDXPROM8]]
2833 ; CGSCC-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX14]], align 4
2834 ; CGSCC-NEXT: [[INC16]] = add nsw i32 [[I3_0]], 1
2835 ; CGSCC-NEXT: br label [[FOR_COND4]], !llvm.loop [[TBAA12]]
2838 %buf = alloca [128 x i32], align 16
2839 call void @llvm.lifetime.start.p0(i64 512, ptr %buf) #2
2842 for.cond: ; preds = %for.body, %entry
2843 %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
2844 %cmp = icmp slt i32 %i.0, 128
2845 br i1 %cmp, label %for.body, label %for.cond.cleanup
2847 for.cond.cleanup: ; preds = %for.cond
2850 for.body: ; preds = %for.cond
2851 %idxprom = sext i32 %i.0 to i64
2852 %arrayidx = getelementptr inbounds i32, ptr %in, i64 %idxprom
2853 %0 = load i32, ptr %arrayidx, align 4
2854 %arrayidx2 = getelementptr inbounds [128 x i32], ptr %buf, i64 0, i64 %idxprom
2855 store i32 %0, ptr %arrayidx2, align 4
2856 %inc = add nsw i32 %i.0, 1
2857 br label %for.cond, !llvm.loop !10
2859 for.cond4: ; preds = %for.body7, %for.cond.cleanup
2860 %i3.0 = phi i32 [ 0, %for.cond.cleanup ], [ %inc16, %for.body7 ]
2861 %cmp5 = icmp slt i32 %i3.0, 128
2862 br i1 %cmp5, label %for.body7, label %for.cond.cleanup6
2864 for.cond.cleanup6: ; preds = %for.cond4
2865 call void @llvm.lifetime.end.p0(i64 512, ptr %buf) #2
2868 for.body7: ; preds = %for.cond4
2869 %idxprom8 = sext i32 %i3.0 to i64
2870 %arrayidx9 = getelementptr inbounds [128 x i32], ptr %buf, i64 0, i64 %idxprom8
2871 %1 = load i32, ptr %arrayidx9, align 4
2872 %idxprom10 = sext i32 %idx to i64
2873 %arrayidx11 = getelementptr inbounds [128 x i32], ptr %buf, i64 0, i64 %idxprom10
2874 %2 = load i32, ptr %arrayidx11, align 4
2875 %cmp12 = icmp sle i32 %1, %2
2876 %conv = zext i1 %cmp12 to i32
2877 %arrayidx14 = getelementptr inbounds i32, ptr %out, i64 %idxprom8
2878 store i32 %conv, ptr %arrayidx14, align 4
2879 %inc16 = add nsw i32 %i3.0, 1
2880 br label %for.cond4, !llvm.loop !12
2883 ; Ensure we do not return true.
2884 define internal i1 @alloca_non_unique(ptr %p, i32 %in, i1 %c) {
2885 ; TUNIT: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
2886 ; TUNIT-LABEL: define {{[^@]+}}@alloca_non_unique
2887 ; TUNIT-SAME: (ptr noalias nocapture nofree readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 noundef [[C:%.*]]) #[[ATTR12:[0-9]+]] {
2888 ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
2889 ; TUNIT-NEXT: store i32 [[IN]], ptr [[A]], align 4
2890 ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
2892 ; TUNIT-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR14:[0-9]+]]
2893 ; TUNIT-NEXT: ret i1 [[R]]
2895 ; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4
2896 ; TUNIT-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]]
2897 ; TUNIT-NEXT: ret i1 [[CMP]]
2899 ; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
2900 ; CGSCC-LABEL: define {{[^@]+}}@alloca_non_unique
2901 ; CGSCC-SAME: (ptr noalias nocapture nofree readonly align 4 [[P:%.*]], i32 [[IN:%.*]], i1 noundef [[C:%.*]]) #[[ATTR14:[0-9]+]] {
2902 ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
2903 ; CGSCC-NEXT: store i32 [[IN]], ptr [[A]], align 4
2904 ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
2906 ; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR17:[0-9]+]]
2907 ; CGSCC-NEXT: ret i1 [[R]]
2909 ; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[P]], align 4
2910 ; CGSCC-NEXT: [[CMP:%.*]] = icmp eq i32 [[IN]], [[L]]
2911 ; CGSCC-NEXT: ret i1 [[CMP]]
2914 store i32 %in, ptr %a
2915 br i1 %c, label %t, label %f
2917 %r = call i1 @alloca_non_unique(ptr %a, i32 42, i1 false)
2920 %l = load i32, ptr %p
2921 %cmp = icmp eq i32 %in, %l
2925 ; Ensure we do not return true.
2926 define i1 @alloca_non_unique_caller(i32 %in, i1 %c) {
2927 ; TUNIT: Function Attrs: nofree norecurse nosync nounwind memory(none)
2928 ; TUNIT-LABEL: define {{[^@]+}}@alloca_non_unique_caller
2929 ; TUNIT-SAME: (i32 [[IN:%.*]], i1 [[C:%.*]]) #[[ATTR13:[0-9]+]] {
2930 ; TUNIT-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr undef, i32 [[IN]], i1 noundef [[C]]) #[[ATTR14]]
2931 ; TUNIT-NEXT: ret i1 [[R]]
2933 ; CGSCC: Function Attrs: nofree nosync nounwind memory(none)
2934 ; CGSCC-LABEL: define {{[^@]+}}@alloca_non_unique_caller
2935 ; CGSCC-SAME: (i32 [[IN:%.*]], i1 noundef [[C:%.*]]) #[[ATTR15:[0-9]+]] {
2936 ; CGSCC-NEXT: [[R:%.*]] = call i1 @alloca_non_unique(ptr nofree undef, i32 [[IN]], i1 noundef [[C]]) #[[ATTR25:[0-9]+]]
2937 ; CGSCC-NEXT: ret i1 [[R]]
2939 %r = call i1 @alloca_non_unique(ptr undef, i32 %in, i1 %c)
2943 ; Ensure we do not return %bad or %l, but %sel
2944 define i32 @scope_value_traversal(i32 %bad, i1 %c, i1 %c2) {
2945 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2946 ; TUNIT-LABEL: define {{[^@]+}}@scope_value_traversal
2947 ; TUNIT-SAME: (i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR4]] {
2948 ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
2949 ; TUNIT-NEXT: store i32 [[BAD]], ptr [[A]], align 4
2950 ; TUNIT-NEXT: call void @scope_value_traversal_helper(ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR22:[0-9]+]]
2951 ; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
2952 ; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]]
2953 ; TUNIT-NEXT: ret i32 [[SEL]]
2955 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
2956 ; CGSCC-LABEL: define {{[^@]+}}@scope_value_traversal
2957 ; CGSCC-SAME: (i32 [[BAD:%.*]], i1 [[C:%.*]], i1 [[C2:%.*]]) #[[ATTR16:[0-9]+]] {
2958 ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
2959 ; CGSCC-NEXT: store i32 [[BAD]], ptr [[A]], align 4
2960 ; CGSCC-NEXT: call void @scope_value_traversal_helper(ptr noalias nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A]], i1 [[C2]]) #[[ATTR26:[0-9]+]]
2961 ; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
2962 ; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[BAD]], i32 [[L]]
2963 ; CGSCC-NEXT: ret i32 [[SEL]]
2966 store i32 %bad, ptr %a
2967 call void @scope_value_traversal_helper(ptr %a, i1 %c2)
2968 %l = load i32, ptr %a
2969 %sel = select i1 %c, i32 %bad, i32 %l
2973 define void @scope_value_traversal_helper(ptr %a, i1 %c) {
2974 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
2975 ; TUNIT-LABEL: define {{[^@]+}}@scope_value_traversal_helper
2976 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]], i1 [[C:%.*]]) #[[ATTR1]] {
2977 ; TUNIT-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
2978 ; TUNIT-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[L]], i32 42
2979 ; TUNIT-NEXT: store i32 [[SEL]], ptr [[A]], align 4
2980 ; TUNIT-NEXT: ret void
2982 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite)
2983 ; CGSCC-LABEL: define {{[^@]+}}@scope_value_traversal_helper
2984 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull align 4 dereferenceable(4) [[A:%.*]], i1 [[C:%.*]]) #[[ATTR13]] {
2985 ; CGSCC-NEXT: [[L:%.*]] = load i32, ptr [[A]], align 4
2986 ; CGSCC-NEXT: [[SEL:%.*]] = select i1 [[C]], i32 [[L]], i32 42
2987 ; CGSCC-NEXT: store i32 [[SEL]], ptr [[A]], align 4
2988 ; CGSCC-NEXT: ret void
2990 %l = load i32, ptr %a
2991 %sel = select i1 %c, i32 %l, i32 42
2992 store i32 %sel, ptr %a
2996 define i8 @gep_index_from_binary_operator(i1 %cnd1, i1 %cnd2) {
2997 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
2998 ; CHECK-LABEL: define {{[^@]+}}@gep_index_from_binary_operator
2999 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR4]] {
3000 ; CHECK-NEXT: entry:
3001 ; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
3002 ; CHECK-NEXT: [[GEP_FIXED:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 12
3003 ; CHECK-NEXT: ret i8 100
3006 %Bytes = alloca [1024 x i8], align 16
3007 %offset = add i64 5, 7
3008 %gep.fixed = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 12
3009 %gep.sum = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %offset
3010 store i8 100, ptr %gep.fixed, align 4
3011 %i = load i8, ptr %gep.sum, align 4
3015 define i8 @gep_index_from_memory(i1 %cnd1, i1 %cnd2) {
3016 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3017 ; CHECK-LABEL: define {{[^@]+}}@gep_index_from_memory
3018 ; CHECK-SAME: (i1 [[CND1:%.*]], i1 [[CND2:%.*]]) #[[ATTR4]] {
3019 ; CHECK-NEXT: entry:
3020 ; CHECK-NEXT: [[BYTES:%.*]] = alloca [1024 x i8], align 16
3021 ; CHECK-NEXT: [[GEP_LOADED:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 12
3022 ; CHECK-NEXT: ret i8 100
3025 %Bytes = alloca [1024 x i8], align 16
3026 %addr = alloca i64, align 16
3027 store i64 12, ptr %addr, align 8
3028 %offset = load i64, ptr %addr, align 8
3029 %gep.fixed = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 12
3031 %gep.loaded = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %offset
3032 store i8 100, ptr %gep.loaded, align 4
3034 %i = load i8, ptr %gep.fixed, align 4
3038 @G = internal global i32 0, align 4
3040 ; Ensure this is not flattened to return 3
3041 define i32 @a(i1 %c) {
3042 ; TUNIT: Function Attrs: nofree nosync nounwind
3043 ; TUNIT-LABEL: define {{[^@]+}}@a
3044 ; TUNIT-SAME: (i1 noundef [[C:%.*]]) #[[ATTR14]] {
3045 ; TUNIT-NEXT: store i32 3, ptr @G, align 4
3046 ; TUNIT-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
3048 ; TUNIT-NEXT: [[REC:%.*]] = call i32 @a(i1 noundef false) #[[ATTR14]]
3049 ; TUNIT-NEXT: br label [[F]]
3051 ; TUNIT-NEXT: [[R:%.*]] = load i32, ptr @G, align 4
3052 ; TUNIT-NEXT: store i32 5, ptr @G, align 4
3053 ; TUNIT-NEXT: ret i32 [[R]]
3055 ; CGSCC: Function Attrs: nofree nosync nounwind
3056 ; CGSCC-LABEL: define {{[^@]+}}@a
3057 ; CGSCC-SAME: (i1 noundef [[C:%.*]]) #[[ATTR17]] {
3058 ; CGSCC-NEXT: store i32 3, ptr @G, align 4
3059 ; CGSCC-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
3061 ; CGSCC-NEXT: [[REC:%.*]] = call i32 @a(i1 noundef false) #[[ATTR17]]
3062 ; CGSCC-NEXT: br label [[F]]
3064 ; CGSCC-NEXT: [[R:%.*]] = load i32, ptr @G, align 4
3065 ; CGSCC-NEXT: store i32 5, ptr @G, align 4
3066 ; CGSCC-NEXT: ret i32 [[R]]
3069 br i1 %c, label %t, label %f
3072 %rec = call i32 @a(i1 false)
3076 %r = load i32, ptr @G
3081 @GC = internal global i32 undef, align 4
3082 define void @atomicrmw(ptr %p, i32 %i, i1 %cnd) {
3083 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
3084 ; TUNIT-LABEL: define {{[^@]+}}@atomicrmw
3085 ; TUNIT-SAME: (ptr nofree [[P:%.*]], i32 [[I:%.*]], i1 noundef [[CND:%.*]]) #[[ATTR3]] {
3086 ; TUNIT-NEXT: br i1 [[CND]], label [[T:%.*]], label [[M:%.*]]
3088 ; TUNIT-NEXT: br label [[M]]
3090 ; TUNIT-NEXT: [[ARMW:%.*]] = atomicrmw add ptr @GC, i32 [[I]] monotonic, align 4
3091 ; TUNIT-NEXT: ret void
3093 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
3094 ; CGSCC-LABEL: define {{[^@]+}}@atomicrmw
3095 ; CGSCC-SAME: (ptr nofree [[P:%.*]], i32 [[I:%.*]], i1 noundef [[CND:%.*]]) #[[ATTR5]] {
3096 ; CGSCC-NEXT: br i1 [[CND]], label [[T:%.*]], label [[M:%.*]]
3098 ; CGSCC-NEXT: br label [[M]]
3100 ; CGSCC-NEXT: [[ARMW:%.*]] = atomicrmw add ptr @GC, i32 [[I]] monotonic, align 4
3101 ; CGSCC-NEXT: ret void
3103 %alloca = alloca <2 x ptr>
3104 %gep1 = getelementptr ptr, ptr %alloca, i32 0
3105 %gep2 = getelementptr ptr, ptr %alloca, i32 1
3106 store <2 x ptr> <ptr @GC, ptr @GC>, ptr %alloca
3107 br i1 %cnd, label %t, label %m
3109 store ptr null, ptr %gep2
3112 %l1 = load ptr, ptr %gep1
3113 %l2 = load ptr, ptr %gep2
3114 %c1 = icmp eq ptr %l2, %p
3115 call void @llvm.assume(i1 %c1)
3116 %s = select i1 true, ptr %l1, ptr %l2
3117 %armw = atomicrmw add ptr %s, i32 %i monotonic
3121 @GRS = internal thread_local global i32 undef
3122 @GRS2 = global i32 undef
3124 define i32 @recSimplify(i32 %v, i1 %cond) {
3125 ; TUNIT: Function Attrs: nofree nosync nounwind
3126 ; TUNIT-LABEL: define {{[^@]+}}@recSimplify
3127 ; TUNIT-SAME: (i32 [[V:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR14]] {
3128 ; TUNIT-NEXT: br i1 [[COND]], label [[REC:%.*]], label [[COMP:%.*]]
3130 ; TUNIT-NEXT: [[RV:%.*]] = call i32 @recSimplify(i32 undef, i1 noundef false) #[[ATTR14]]
3131 ; TUNIT-NEXT: ret i32 1
3133 ; TUNIT-NEXT: store i32 1, ptr @GRS2, align 4
3134 ; TUNIT-NEXT: ret i32 1
3136 ; CGSCC: Function Attrs: nofree nosync nounwind
3137 ; CGSCC-LABEL: define {{[^@]+}}@recSimplify
3138 ; CGSCC-SAME: (i32 [[V:%.*]], i1 noundef [[COND:%.*]]) #[[ATTR17]] {
3139 ; CGSCC-NEXT: br i1 [[COND]], label [[REC:%.*]], label [[COMP:%.*]]
3141 ; CGSCC-NEXT: [[RV:%.*]] = call i32 @recSimplify(i32 [[V]], i1 noundef false) #[[ATTR17]]
3142 ; CGSCC-NEXT: ret i32 [[RV]]
3144 ; CGSCC-NEXT: store i32 [[V]], ptr @GRS, align 4
3145 ; CGSCC-NEXT: store i32 1, ptr @GRS2, align 4
3146 ; CGSCC-NEXT: [[L:%.*]] = load i32, ptr @GRS, align 4
3147 ; CGSCC-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 1
3148 ; CGSCC-NEXT: call void @llvm.assume(i1 noundef [[C]]) #[[ATTR27:[0-9]+]]
3149 ; CGSCC-NEXT: [[R:%.*]] = call i32 @recSimplify2() #[[ATTR27]]
3150 ; CGSCC-NEXT: ret i32 [[R]]
3152 br i1 %cond, label %rec, label %comp
3154 %rv = call i32 @recSimplify(i32 %v, i1 false)
3157 store i32 %v, ptr @GRS
3158 %s1 = select i1 %cond, i32 1, i32 1
3159 %s2 = select i1 %cond, i32 1, i32 %s1
3160 store i32 %s2, ptr @GRS2
3161 %l = load i32, ptr @GRS
3162 %c = icmp eq i32 %l, %s2
3163 call void @llvm.assume(i1 %c)
3164 %r = call i32 @recSimplify2()
3168 define internal i32 @recSimplify2() {
3169 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(read)
3170 ; CGSCC-LABEL: define {{[^@]+}}@recSimplify2
3171 ; CGSCC-SAME: () #[[ATTR7]] {
3172 ; CGSCC-NEXT: [[R:%.*]] = load i32, ptr @GRS, align 4
3173 ; CGSCC-NEXT: ret i32 [[R]]
3175 %r = load i32, ptr @GRS
3179 ; Verify we do not return 10.
3180 define i32 @may_access_after_return(i32 noundef %N, i32 noundef %M) {
3181 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3182 ; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return
3183 ; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] {
3184 ; TUNIT-NEXT: entry:
3185 ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
3186 ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
3187 ; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR18]]
3188 ; TUNIT-NEXT: ret i32 8
3190 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
3191 ; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return
3192 ; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] {
3193 ; CGSCC-NEXT: entry:
3194 ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
3195 ; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
3196 ; CGSCC-NEXT: call void @write_both(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR21]]
3197 ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3198 ; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3199 ; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3200 ; CGSCC-NEXT: ret i32 [[ADD]]
3203 %A = alloca i32, align 4
3204 %B = alloca i32, align 4
3205 %call = call ptr @passthrough(ptr noundef %A)
3206 %call1 = call ptr @passthrough(ptr noundef %B)
3207 call void @write_both(ptr noundef %call, ptr noundef %call1)
3208 %0 = load i32, ptr %A, align 4
3209 %1 = load i32, ptr %B, align 4
3210 %add = add nsw i32 %0, %1
3214 define internal void @write_both(ptr noundef %Q, ptr noundef %R) {
3215 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write)
3216 ; CHECK-LABEL: define {{[^@]+}}@write_both
3217 ; CHECK-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[Q:%.*]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[R:%.*]]) #[[ATTR0]] {
3218 ; CHECK-NEXT: entry:
3219 ; CHECK-NEXT: store i32 3, ptr [[Q]], align 4
3220 ; CHECK-NEXT: store i32 5, ptr [[R]], align 4
3221 ; CHECK-NEXT: ret void
3224 store i32 3, ptr %Q, align 4
3225 store i32 5, ptr %R, align 4
3229 define internal ptr @passthrough(ptr noundef %P) {
3230 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3231 ; CGSCC-LABEL: define {{[^@]+}}@passthrough
3232 ; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] {
3233 ; CGSCC-NEXT: entry:
3234 ; CGSCC-NEXT: ret ptr [[P]]
3240 ; Verify we do not return 10.
3241 define i32 @may_access_after_return_choice(i32 noundef %N, i32 noundef %M, i1 %c) {
3242 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3243 ; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_choice
3244 ; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], i1 [[C:%.*]]) #[[ATTR4]] {
3245 ; TUNIT-NEXT: entry:
3246 ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
3247 ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
3248 ; TUNIT-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]]) #[[ATTR23:[0-9]+]]
3249 ; TUNIT-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
3250 ; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL1]]) #[[ATTR18]]
3251 ; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3252 ; TUNIT-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3253 ; TUNIT-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3254 ; TUNIT-NEXT: ret i32 [[ADD]]
3256 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
3257 ; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_choice
3258 ; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]], i1 [[C:%.*]]) #[[ATTR3]] {
3259 ; CGSCC-NEXT: entry:
3260 ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
3261 ; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
3262 ; CGSCC-NEXT: [[CALL:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]]) #[[ATTR28:[0-9]+]]
3263 ; CGSCC-NEXT: [[CALL1:%.*]] = call nonnull align 4 dereferenceable(4) ptr @passthrough_choice(i1 [[C]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) [[A]]) #[[ATTR28]]
3264 ; CGSCC-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[CALL1]]) #[[ATTR21]]
3265 ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3266 ; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3267 ; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3268 ; CGSCC-NEXT: ret i32 [[ADD]]
3271 %A = alloca i32, align 4
3272 %B = alloca i32, align 4
3273 %call = call ptr @passthrough_choice(i1 %c, ptr noundef %A, ptr noundef %B)
3274 %call1 = call ptr @passthrough_choice(i1 %c, ptr noundef %B, ptr noundef %A)
3275 call void @write_both(ptr noundef %call, ptr noundef %call1)
3276 %0 = load i32, ptr %A, align 4
3277 %1 = load i32, ptr %B, align 4
3278 %add = add nsw i32 %0, %1
3282 define internal ptr @passthrough_choice(i1 %c, ptr noundef %P, ptr noundef %Q) {
3283 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3284 ; CHECK-LABEL: define {{[^@]+}}@passthrough_choice
3285 ; CHECK-SAME: (i1 [[C:%.*]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]], ptr noalias nofree noundef nonnull readnone align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q:%.*]]) #[[ATTR4]] {
3286 ; CHECK-NEXT: entry:
3287 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], ptr [[P]], ptr [[Q]]
3288 ; CHECK-NEXT: ret ptr [[R]]
3291 %R = select i1 %c, ptr %P, ptr %Q
3295 ; Verify we do not return 10.
3296 define i32 @may_access_after_return_no_choice1(i32 noundef %N, i32 noundef %M) {
3297 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3298 ; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1
3299 ; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] {
3300 ; TUNIT-NEXT: entry:
3301 ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
3302 ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
3303 ; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR18]]
3304 ; TUNIT-NEXT: ret i32 8
3306 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
3307 ; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice1
3308 ; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] {
3309 ; CGSCC-NEXT: entry:
3310 ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
3311 ; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
3312 ; CGSCC-NEXT: call void @write_both(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]], ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]]) #[[ATTR21]]
3313 ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3314 ; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3315 ; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3316 ; CGSCC-NEXT: ret i32 [[ADD]]
3319 %A = alloca i32, align 4
3320 %B = alloca i32, align 4
3321 %call = call ptr @passthrough_no_choice_true(i1 true, ptr noundef %A, ptr noundef %B)
3322 %call1 = call ptr @passthrough_no_choice_true(i1 true, ptr noundef %B, ptr noundef %A)
3323 call void @write_both(ptr noundef %call, ptr noundef %call1)
3324 %0 = load i32, ptr %A, align 4
3325 %1 = load i32, ptr %B, align 4
3326 %add = add nsw i32 %0, %1
3330 ; Verify we do not return 10.
3331 define i32 @may_access_after_return_no_choice2(i32 noundef %N, i32 noundef %M) {
3332 ; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3333 ; TUNIT-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2
3334 ; TUNIT-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR4]] {
3335 ; TUNIT-NEXT: entry:
3336 ; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 4
3337 ; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
3338 ; TUNIT-NEXT: call void @write_both(ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]], ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR18]]
3339 ; TUNIT-NEXT: ret i32 8
3341 ; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
3342 ; CGSCC-LABEL: define {{[^@]+}}@may_access_after_return_no_choice2
3343 ; CGSCC-SAME: (i32 noundef [[N:%.*]], i32 noundef [[M:%.*]]) #[[ATTR16]] {
3344 ; CGSCC-NEXT: entry:
3345 ; CGSCC-NEXT: [[A:%.*]] = alloca i32, align 4
3346 ; CGSCC-NEXT: [[B:%.*]] = alloca i32, align 4
3347 ; CGSCC-NEXT: call void @write_both(ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[B]], ptr noalias nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[A]]) #[[ATTR21]]
3348 ; CGSCC-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 4
3349 ; CGSCC-NEXT: [[TMP1:%.*]] = load i32, ptr [[B]], align 4
3350 ; CGSCC-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
3351 ; CGSCC-NEXT: ret i32 [[ADD]]
3354 %A = alloca i32, align 4
3355 %B = alloca i32, align 4
3356 %call = call ptr @passthrough_no_choice_false(i1 false, ptr noundef %A, ptr noundef %B)
3357 %call1 = call ptr @passthrough_no_choice_false(i1 false, ptr noundef %B, ptr noundef %A)
3358 call void @write_both(ptr noundef %call, ptr noundef %call1)
3359 %0 = load i32, ptr %A, align 4
3360 %1 = load i32, ptr %B, align 4
3361 %add = add nsw i32 %0, %1
3365 define internal ptr @passthrough_no_choice_true(i1 %c, ptr noundef %P, ptr noundef %Q) {
3366 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3367 ; CGSCC-LABEL: define {{[^@]+}}@passthrough_no_choice_true
3368 ; CGSCC-SAME: (ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]], i32 [[TMP0:%.*]]) #[[ATTR4]] {
3369 ; CGSCC-NEXT: entry:
3370 ; CGSCC-NEXT: [[Q_PRIV:%.*]] = alloca i32, align 4
3371 ; CGSCC-NEXT: store i32 [[TMP0]], ptr [[Q_PRIV]], align 4
3372 ; CGSCC-NEXT: ret ptr [[P]]
3375 %R = select i1 %c, ptr %P, ptr %Q
3378 define internal ptr @passthrough_no_choice_false(i1 %c, ptr noundef %P, ptr noundef %Q) {
3379 ; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3380 ; CGSCC-LABEL: define {{[^@]+}}@passthrough_no_choice_false
3381 ; CGSCC-SAME: (i32 [[TMP0:%.*]], ptr noalias nofree noundef nonnull readnone returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[Q:%.*]]) #[[ATTR4]] {
3382 ; CGSCC-NEXT: entry:
3383 ; CGSCC-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4
3384 ; CGSCC-NEXT: store i32 [[TMP0]], ptr [[P_PRIV]], align 4
3385 ; CGSCC-NEXT: ret ptr [[Q]]
3388 %R = select i1 %c, ptr %P, ptr %Q
3392 define ptr @move2(ptr %p) {
3393 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3394 ; CHECK-LABEL: define {{[^@]+}}@move2
3395 ; CHECK-SAME: (ptr nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] {
3396 ; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P]], i32 2
3397 ; CHECK-NEXT: ret ptr [[G]]
3399 %g = getelementptr i8, ptr %p, i32 2
3402 define internal ptr @move4(ptr %p) {
3403 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3404 ; CHECK-LABEL: define {{[^@]+}}@move4
3405 ; CHECK-SAME: (ptr noalias nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] {
3406 ; CHECK-NEXT: [[G:%.*]] = getelementptr i8, ptr [[P]], i32 4
3407 ; CHECK-NEXT: ret ptr [[G]]
3409 %g = getelementptr i8, ptr %p, i32 4
3413 define ptr @move246(i32 %i, ptr %p) {
3414 ; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
3415 ; CHECK-LABEL: define {{[^@]+}}@move246
3416 ; CHECK-SAME: (i32 [[I:%.*]], ptr nofree readnone "no-capture-maybe-returned" [[P:%.*]]) #[[ATTR4]] {
3417 ; CHECK-NEXT: [[C0:%.*]] = icmp eq i32 [[I]], 0
3418 ; CHECK-NEXT: br i1 [[C0]], label [[BG2:%.*]], label [[BG46:%.*]]
3420 ; CHECK-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[P]], i32 2
3421 ; CHECK-NEXT: ret ptr [[G2]]
3423 ; CHECK-NEXT: [[C1:%.*]] = icmp eq i32 [[I]], 1
3424 ; CHECK-NEXT: br i1 [[C1]], label [[BG4:%.*]], label [[BG6:%.*]]
3426 ; CHECK-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[P]], i32 4
3427 ; CHECK-NEXT: ret ptr [[G4]]
3429 ; CHECK-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[P]], i32 6
3430 ; CHECK-NEXT: ret ptr [[G6]]
3432 %c0 = icmp eq i32 %i, 0
3433 br i1 %c0, label %bg2, label %bg46
3435 %g2 = getelementptr i8, ptr %p, i32 2
3438 %c1 = icmp eq i32 %i, 1
3439 br i1 %c1, label %bg4, label %bg6
3441 %g4 = getelementptr i8, ptr %p, i32 4
3444 %g6 = getelementptr i8, ptr %p, i32 6
3448 declare void @use3i8(i8, i8, i8)
3450 define void @returnedPtrAccesses() {
3451 ; TUNIT-LABEL: define {{[^@]+}}@returnedPtrAccesses() {
3452 ; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8
3453 ; TUNIT-NEXT: [[A2:%.*]] = call ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
3454 ; TUNIT-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
3455 ; TUNIT-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree readnone "no-capture-maybe-returned" [[A2]]) #[[ATTR23]]
3456 ; TUNIT-NEXT: store i8 2, ptr [[A2]], align 1
3457 ; TUNIT-NEXT: store i8 4, ptr [[A4]], align 1
3458 ; TUNIT-NEXT: store i8 6, ptr [[A6]], align 1
3459 ; TUNIT-NEXT: call void @use3i8(i8 2, i8 4, i8 6)
3460 ; TUNIT-NEXT: ret void
3462 ; CGSCC-LABEL: define {{[^@]+}}@returnedPtrAccesses() {
3463 ; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8
3464 ; CGSCC-NEXT: [[A2:%.*]] = call nonnull dereferenceable(1) ptr @move2(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]]
3465 ; CGSCC-NEXT: [[A4:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]]
3466 ; CGSCC-NEXT: [[A6:%.*]] = call ptr @move4(ptr noalias nofree noundef nonnull readnone dereferenceable(1) [[A2]]) #[[ATTR20]]
3467 ; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2
3468 ; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4
3469 ; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6
3470 ; CGSCC-NEXT: store i8 2, ptr [[A2]], align 1
3471 ; CGSCC-NEXT: store i8 4, ptr [[A4]], align 1
3472 ; CGSCC-NEXT: store i8 6, ptr [[A6]], align 1
3473 ; CGSCC-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2
3474 ; CGSCC-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4
3475 ; CGSCC-NEXT: [[L6:%.*]] = load i8, ptr [[G6]], align 2
3476 ; CGSCC-NEXT: call void @use3i8(i8 [[L2]], i8 [[L4]], i8 [[L6]])
3477 ; CGSCC-NEXT: ret void
3480 %a2 = call ptr @move2(ptr %a)
3481 %a4 = call ptr @move4(ptr %a)
3482 %a6 = call ptr @move4(ptr %a2)
3483 %g2 = getelementptr i8, ptr %a, i32 2
3484 %g4 = getelementptr i8, ptr %a, i32 4
3485 %g6 = getelementptr i8, ptr %a, i32 6
3489 %l2 = load i8, ptr %g2
3490 %l4 = load i8, ptr %g4
3491 %l6 = load i8, ptr %g6
3492 call void @use3i8(i8 %l2, i8 %l4, i8 %l6)
3496 define void @returnedPtrAccessesMultiple(i32 %i) {
3497 ; TUNIT-LABEL: define {{[^@]+}}@returnedPtrAccessesMultiple
3498 ; TUNIT-SAME: (i32 [[I:%.*]]) {
3499 ; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8
3500 ; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
3501 ; TUNIT-NEXT: store i8 2, ptr [[AP]], align 1
3502 ; TUNIT-NEXT: call void @use3i8(i8 2, i8 2, i8 2)
3503 ; TUNIT-NEXT: ret void
3505 ; CGSCC-LABEL: define {{[^@]+}}@returnedPtrAccessesMultiple
3506 ; CGSCC-SAME: (i32 [[I:%.*]]) {
3507 ; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8
3508 ; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]]
3509 ; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2
3510 ; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4
3511 ; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6
3512 ; CGSCC-NEXT: store i8 2, ptr [[AP]], align 1
3513 ; CGSCC-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2
3514 ; CGSCC-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4
3515 ; CGSCC-NEXT: [[L6:%.*]] = load i8, ptr [[G6]], align 2
3516 ; CGSCC-NEXT: call void @use3i8(i8 [[L2]], i8 [[L4]], i8 [[L6]])
3517 ; CGSCC-NEXT: ret void
3520 %ap = call ptr @move246(i32 %i, ptr %a)
3521 %g2 = getelementptr i8, ptr %a, i32 2
3522 %g4 = getelementptr i8, ptr %a, i32 4
3523 %g6 = getelementptr i8, ptr %a, i32 6
3525 %l2 = load i8, ptr %g2
3526 %l4 = load i8, ptr %g4
3527 %l6 = load i8, ptr %g6
3528 call void @use3i8(i8 %l2, i8 %l4, i8 %l6)
3532 define void @returnedPtrAccessesMultiple2(i32 %i) {
3533 ; TUNIT-LABEL: define {{[^@]+}}@returnedPtrAccessesMultiple2
3534 ; TUNIT-SAME: (i32 [[I:%.*]]) {
3535 ; TUNIT-NEXT: [[A:%.*]] = alloca i64, align 8
3536 ; TUNIT-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2
3537 ; TUNIT-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4
3538 ; TUNIT-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6
3539 ; TUNIT-NEXT: store i8 0, ptr [[G2]], align 2
3540 ; TUNIT-NEXT: store i8 0, ptr [[G4]], align 4
3541 ; TUNIT-NEXT: store i8 0, ptr [[G6]], align 2
3542 ; TUNIT-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) "no-capture-maybe-returned" [[A]]) #[[ATTR23]]
3543 ; TUNIT-NEXT: store i8 2, ptr [[AP]], align 1
3544 ; TUNIT-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2
3545 ; TUNIT-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4
3546 ; TUNIT-NEXT: [[L6:%.*]] = load i8, ptr [[G6]], align 2
3547 ; TUNIT-NEXT: call void @use3i8(i8 noundef [[L2]], i8 noundef [[L4]], i8 noundef [[L6]])
3548 ; TUNIT-NEXT: ret void
3550 ; CGSCC-LABEL: define {{[^@]+}}@returnedPtrAccessesMultiple2
3551 ; CGSCC-SAME: (i32 [[I:%.*]]) {
3552 ; CGSCC-NEXT: [[A:%.*]] = alloca i64, align 8
3553 ; CGSCC-NEXT: [[G2:%.*]] = getelementptr i8, ptr [[A]], i32 2
3554 ; CGSCC-NEXT: [[G4:%.*]] = getelementptr i8, ptr [[A]], i32 4
3555 ; CGSCC-NEXT: [[G6:%.*]] = getelementptr i8, ptr [[A]], i32 6
3556 ; CGSCC-NEXT: store i8 0, ptr [[G2]], align 2
3557 ; CGSCC-NEXT: store i8 0, ptr [[G4]], align 4
3558 ; CGSCC-NEXT: store i8 0, ptr [[G6]], align 2
3559 ; CGSCC-NEXT: [[AP:%.*]] = call ptr @move246(i32 [[I]], ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(8) [[A]]) #[[ATTR20]]
3560 ; CGSCC-NEXT: store i8 2, ptr [[AP]], align 1
3561 ; CGSCC-NEXT: [[L2:%.*]] = load i8, ptr [[G2]], align 2
3562 ; CGSCC-NEXT: [[L4:%.*]] = load i8, ptr [[G4]], align 4
3563 ; CGSCC-NEXT: [[L6:%.*]] = load i8, ptr [[G6]], align 2
3564 ; CGSCC-NEXT: call void @use3i8(i8 [[L2]], i8 [[L4]], i8 [[L6]])
3565 ; CGSCC-NEXT: ret void
3568 %g2 = getelementptr i8, ptr %a, i32 2
3569 %g4 = getelementptr i8, ptr %a, i32 4
3570 %g6 = getelementptr i8, ptr %a, i32 6
3574 %ap = call ptr @move246(i32 %i, ptr %a)
3576 %l2 = load i8, ptr %g2
3577 %l4 = load i8, ptr %g4
3578 %l6 = load i8, ptr %g6
3579 call void @use3i8(i8 %l2, i8 %l4, i8 %l6)
3583 declare void @llvm.assume(i1 noundef)
3586 !llvm.module.flags = !{!0, !1}
3589 !0 = !{i32 1, !"wchar_size", i32 4}
3590 !1 = !{i32 7, !"uwtable", i32 1}
3591 !2 = !{!"clang version 13.0.0"}
3592 !3 = !{!4, !4, i64 0}
3593 !4 = !{!"int", !5, i64 0}
3594 !5 = !{!"omnipotent char", !6, i64 0}
3595 !6 = !{!"Simple C/C++ TBAA"}
3596 !7 = !{!8, !9, i64 12}
3597 !8 = !{!"S", !4, i64 0, !4, i64 4, !4, i64 8, !9, i64 12, !9, i64 16, !9, i64 20}
3598 !9 = !{!"float", !5, i64 0}
3599 !10 = !{!8, !9, i64 16}
3600 !11 = !{!8, !9, i64 20}
3601 !12 = !{!8, !4, i64 0}
3602 !13 = !{!8, !4, i64 4}
3603 !14 = !{!8, !4, i64 8}
3604 !15 = !{!5, !5, i64 0}
3605 !16 = distinct !{!16, !17}
3606 !17 = !{!"llvm.loop.mustprogress"}
3607 !18 = !{!9, !9, i64 0}
3608 !19 = distinct !{!19, !17}
3609 !20 = !{!21, !21, i64 0}
3610 !21 = !{!"long long", !5, i64 0}
3611 !22 = distinct !{!22, !17}
3612 !23 = distinct !{!23, !17}
3613 !24 = distinct !{!24, !17}
3614 !25 = distinct !{!25, !17}
3615 !26 = distinct !{!26, !17}
3616 !27 = distinct !{!27, !17}
3617 !28 = distinct !{!28, !17}
3618 !29 = distinct !{!29, !17}
3619 !30 = distinct !{!30, !17}
3620 !31 = distinct !{!31, !17}
3622 ; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
3623 ; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }
3624 ; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
3625 ; TUNIT: attributes #[[ATTR3]] = { mustprogress nofree norecurse nosync nounwind willreturn }
3626 ; TUNIT: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
3627 ; TUNIT: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
3628 ; TUNIT: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read) }
3629 ; TUNIT: attributes #[[ATTR7]] = { nofree norecurse nosync nounwind memory(write) }
3630 ; TUNIT: attributes #[[ATTR8:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" }
3631 ; TUNIT: attributes #[[ATTR9:[0-9]+]] = { allockind("free") "alloc-family"="malloc" }
3632 ; TUNIT: attributes #[[ATTR10:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" }
3633 ; TUNIT: attributes #[[ATTR11]] = { mustprogress nofree norecurse nosync nounwind willreturn uwtable }
3634 ; TUNIT: attributes #[[ATTR12]] = { nofree nosync nounwind memory(argmem: readwrite) }
3635 ; TUNIT: attributes #[[ATTR13]] = { nofree norecurse nosync nounwind memory(none) }
3636 ; TUNIT: attributes #[[ATTR14]] = { nofree nosync nounwind }
3637 ; TUNIT: attributes #[[ATTR15:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
3638 ; TUNIT: attributes #[[ATTR16:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
3639 ; TUNIT: attributes #[[ATTR17]] = { nofree willreturn }
3640 ; TUNIT: attributes #[[ATTR18]] = { nofree nosync nounwind willreturn memory(write) }
3641 ; TUNIT: attributes #[[ATTR19]] = { nocallback }
3642 ; TUNIT: attributes #[[ATTR20]] = { norecurse }
3643 ; TUNIT: attributes #[[ATTR21]] = { nounwind }
3644 ; TUNIT: attributes #[[ATTR22]] = { nofree nosync nounwind willreturn }
3645 ; TUNIT: attributes #[[ATTR23]] = { nofree nosync nounwind willreturn memory(none) }
3647 ; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: write) }
3648 ; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) }
3649 ; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
3650 ; CGSCC: attributes #[[ATTR3]] = { mustprogress nofree nosync nounwind willreturn }
3651 ; CGSCC: attributes #[[ATTR4]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
3652 ; CGSCC: attributes #[[ATTR5]] = { mustprogress nofree norecurse nosync nounwind willreturn }
3653 ; CGSCC: attributes #[[ATTR6]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(write) }
3654 ; CGSCC: attributes #[[ATTR7]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(read) }
3655 ; CGSCC: attributes #[[ATTR8]] = { nofree norecurse nosync nounwind memory(write) }
3656 ; CGSCC: attributes #[[ATTR9:[0-9]+]] = { allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc" }
3657 ; CGSCC: attributes #[[ATTR10:[0-9]+]] = { allockind("free") "alloc-family"="malloc" }
3658 ; CGSCC: attributes #[[ATTR11:[0-9]+]] = { allockind("alloc,zeroed") allocsize(0,1) "alloc-family"="malloc" }
3659 ; CGSCC: attributes #[[ATTR12]] = { mustprogress nofree norecurse nosync nounwind willreturn uwtable }
3660 ; CGSCC: attributes #[[ATTR13]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) }
3661 ; CGSCC: attributes #[[ATTR14]] = { nofree nosync nounwind memory(argmem: readwrite) }
3662 ; CGSCC: attributes #[[ATTR15]] = { nofree nosync nounwind memory(none) }
3663 ; CGSCC: attributes #[[ATTR16]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
3664 ; CGSCC: attributes #[[ATTR17]] = { nofree nosync nounwind }
3665 ; CGSCC: attributes #[[ATTR18:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) }
3666 ; CGSCC: attributes #[[ATTR19:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
3667 ; CGSCC: attributes #[[ATTR20]] = { nofree willreturn }
3668 ; CGSCC: attributes #[[ATTR21]] = { nofree nounwind willreturn memory(write) }
3669 ; CGSCC: attributes #[[ATTR22]] = { nocallback }
3670 ; CGSCC: attributes #[[ATTR23]] = { norecurse }
3671 ; CGSCC: attributes #[[ATTR24]] = { nounwind }
3672 ; CGSCC: attributes #[[ATTR25]] = { nofree nounwind }
3673 ; CGSCC: attributes #[[ATTR26]] = { nofree nounwind willreturn }
3674 ; CGSCC: attributes #[[ATTR27]] = { nofree }
3675 ; CGSCC: attributes #[[ATTR28]] = { nofree nosync willreturn }
3677 ; TUNIT: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
3678 ; TUNIT: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1}
3679 ; TUNIT: [[META2:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
3680 ; TUNIT: [[TBAA3]] = !{[[META4:![0-9]+]], [[META4]], i64 0}
3681 ; TUNIT: [[META4]] = !{!"int", [[META5:![0-9]+]], i64 0}
3682 ; TUNIT: [[META5]] = !{!"omnipotent char", [[META6:![0-9]+]], i64 0}
3683 ; TUNIT: [[META6]] = !{!"Simple C/C++ TBAA"}
3684 ; TUNIT: [[TBAA7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], i64 12}
3685 ; TUNIT: [[META8]] = !{!"S", [[META4]], i64 0, [[META4]], i64 4, [[META4]], i64 8, [[META9]], i64 12, [[META9]], i64 16, [[META9]], i64 20}
3686 ; TUNIT: [[META9]] = !{!"float", [[META5]], i64 0}
3687 ; TUNIT: [[TBAA10]] = !{[[META8]], [[META9]], i64 16}
3688 ; TUNIT: [[TBAA11]] = !{[[META8]], [[META9]], i64 20}
3689 ; TUNIT: [[TBAA12]] = !{[[META8]], [[META4]], i64 0}
3690 ; TUNIT: [[TBAA13]] = !{[[META8]], [[META4]], i64 4}
3691 ; TUNIT: [[TBAA14]] = !{[[META8]], [[META4]], i64 8}
3692 ; TUNIT: [[LOOP15]] = distinct !{[[LOOP15]], [[META16:![0-9]+]]}
3693 ; TUNIT: [[META16]] = !{!"llvm.loop.mustprogress"}
3694 ; TUNIT: [[LOOP17]] = distinct !{[[LOOP17]], [[META16]]}
3695 ; TUNIT: [[LOOP18]] = distinct !{[[LOOP18]], [[META16]]}
3696 ; TUNIT: [[TBAA19]] = !{[[META5]], [[META5]], i64 0}
3697 ; TUNIT: [[LOOP20]] = distinct !{[[LOOP20]], [[META16]]}
3698 ; TUNIT: [[LOOP21]] = distinct !{[[LOOP21]], [[META16]]}
3699 ; TUNIT: [[LOOP22]] = distinct !{[[LOOP22]], [[META16]]}
3700 ; TUNIT: [[LOOP23]] = distinct !{[[LOOP23]], [[META16]]}
3701 ; TUNIT: [[LOOP24]] = distinct !{[[LOOP24]], [[META16]]}
3702 ; TUNIT: [[LOOP25]] = distinct !{[[LOOP25]], [[META16]]}
3703 ; TUNIT: [[TBAA26]] = !{[[META9]], [[META9]], i64 0}
3704 ; TUNIT: [[LOOP27]] = distinct !{[[LOOP27]], [[META16]]}
3705 ; TUNIT: [[TBAA28]] = !{[[META29:![0-9]+]], [[META29]], i64 0}
3706 ; TUNIT: [[META29]] = !{!"long long", [[META5]], i64 0}
3707 ; TUNIT: [[LOOP30]] = distinct !{[[LOOP30]], [[META16]]}
3708 ; TUNIT: [[LOOP31]] = distinct !{[[LOOP31]], [[META16]]}
3710 ; CGSCC: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
3711 ; CGSCC: [[META1:![0-9]+]] = !{i32 7, !"uwtable", i32 1}
3712 ; CGSCC: [[META2:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
3713 ; CGSCC: [[TBAA3]] = !{[[META4:![0-9]+]], [[META4]], i64 0}
3714 ; CGSCC: [[META4]] = !{!"int", [[META5:![0-9]+]], i64 0}
3715 ; CGSCC: [[META5]] = !{!"omnipotent char", [[META6:![0-9]+]], i64 0}
3716 ; CGSCC: [[META6]] = !{!"Simple C/C++ TBAA"}
3717 ; CGSCC: [[TBAA7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], i64 12}
3718 ; CGSCC: [[META8]] = !{!"S", [[META4]], i64 0, [[META4]], i64 4, [[META4]], i64 8, [[META9]], i64 12, [[META9]], i64 16, [[META9]], i64 20}
3719 ; CGSCC: [[META9]] = !{!"float", [[META5]], i64 0}
3720 ; CGSCC: [[TBAA10]] = !{[[META8]], [[META9]], i64 16}
3721 ; CGSCC: [[TBAA11]] = !{[[META8]], [[META9]], i64 20}
3722 ; CGSCC: [[TBAA12]] = !{[[META8]], [[META4]], i64 0}
3723 ; CGSCC: [[TBAA13]] = !{[[META8]], [[META4]], i64 4}
3724 ; CGSCC: [[TBAA14]] = !{[[META8]], [[META4]], i64 8}
3725 ; CGSCC: [[TBAA15]] = !{[[META5]], [[META5]], i64 0}
3726 ; CGSCC: [[LOOP16]] = distinct !{[[LOOP16]], [[META17:![0-9]+]]}
3727 ; CGSCC: [[META17]] = !{!"llvm.loop.mustprogress"}
3728 ; CGSCC: [[TBAA18]] = !{[[META9]], [[META9]], i64 0}
3729 ; CGSCC: [[LOOP19]] = distinct !{[[LOOP19]], [[META17]]}
3730 ; CGSCC: [[TBAA20]] = !{[[META21:![0-9]+]], [[META21]], i64 0}
3731 ; CGSCC: [[META21]] = !{!"long long", [[META5]], i64 0}
3732 ; CGSCC: [[LOOP22]] = distinct !{[[LOOP22]], [[META17]]}
3733 ; CGSCC: [[LOOP23]] = distinct !{[[LOOP23]], [[META17]]}
3734 ; CGSCC: [[LOOP24]] = distinct !{[[LOOP24]], [[META17]]}
3735 ; CGSCC: [[LOOP25]] = distinct !{[[LOOP25]], [[META17]]}
3736 ; CGSCC: [[LOOP26]] = distinct !{[[LOOP26]], [[META17]]}
3737 ; CGSCC: [[LOOP27]] = distinct !{[[LOOP27]], [[META17]]}
3738 ; CGSCC: [[LOOP28]] = distinct !{[[LOOP28]], [[META17]]}
3739 ; CGSCC: [[LOOP29]] = distinct !{[[LOOP29]], [[META17]]}
3740 ; CGSCC: [[LOOP30]] = distinct !{[[LOOP30]], [[META17]]}
3741 ; CGSCC: [[LOOP31]] = distinct !{[[LOOP31]], [[META17]]}