xref: /llvm-project/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll (revision 29441e4f5fa5f5c7709f7cf180815ba97f611297)
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
4;
5%struct.S = type { i32, i32, i32, float, float, float }
6
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
33
34;.
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
66;.
67define 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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[P:%.*]], i32 [[V:%.*]]) #[[ATTR0:[0-9]+]] {
71; CHECK-NEXT:  entry:
72; CHECK-NEXT:    store i32 [[V]], ptr [[P]], align 4, !tbaa [[TBAA3:![0-9]+]]
73; CHECK-NEXT:    ret void
74;
75entry:
76  store i32 %v, ptr %p, align 4, !tbaa !3
77  ret void
78}
79
80define void @write_random(ptr %p) {
81; CHECK-LABEL: define {{[^@]+}}@write_random
82; CHECK-SAME: (ptr nofree writeonly captures(none) [[P:%.*]]) {
83; CHECK-NEXT:  entry:
84; CHECK-NEXT:    [[CALL:%.*]] = call i32 (...) @random()
85; CHECK-NEXT:    store i32 [[CALL]], ptr [[P]], align 4, !tbaa [[TBAA3]]
86; CHECK-NEXT:    ret void
87;
88entry:
89  %call = call i32 (...) @random()
90  store i32 %call, ptr %p, align 4, !tbaa !3
91  ret void
92}
93
94declare i32 @random(...)
95
96;    struct S local_alloca_simplifiable_1(void) {
97;      struct S s;
98;      s.f1 = 1.1;
99;      s.f2 = 2.2;
100;      s.f3 = 3.3;
101;      write_arg(&s.i1, 1);
102;      write_arg(&s.i2, 2);
103;      write_arg(&s.i3, 3);
104;      struct S r;
105;      r.f1 = s.f1;
106;      r.f2 = s.f2 * 2;
107;      r.f3 = s.f3 + s.f1;
108;      r.i1 = s.i1;
109;      r.i2 = s.i2 * 2;
110;      r.i3 = s.i3 + s.i1;
111;      return r;
112;    }
113define 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 nofree writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable_or_null(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] {
117; TUNIT-NEXT:  entry:
118; TUNIT-NEXT:    [[S:%.*]] = alloca [[STRUCT_S]], align 4
119; TUNIT-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 24, ptr noalias nofree noundef nonnull align 4 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull align 4 captures(none) dereferenceable(24) [[S]]) #[[ATTR17]]
140; TUNIT-NEXT:    ret void
141;
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 nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR1:[0-9]+]] {
145; CGSCC-NEXT:  entry:
146; CGSCC-NEXT:    [[S:%.*]] = alloca [[STRUCT_S]], align 4
147; CGSCC-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 24, ptr noalias nofree noundef nonnull align 4 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull align 4 captures(none) dereferenceable(24) [[S]]) #[[ATTR20]]
189; CGSCC-NEXT:    ret void
190;
191entry:
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)
235  ret void
236}
237
238declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture)
239
240declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture)
241
242;    void local_alloca_simplifiable_2(void) {
243;      char Bytes[1024];
244;      for (int i = 0; i < 100; ++i)
245;        Bytes[i * 10] = 0;
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;
250;      Bytes[1023] = 0;
251;      write_arg((int *)&Bytes[500], 0);
252;      struct S R;
253;      for (int i = 0; i < 1024; ++i)
254;        globalBytes[i] = Bytes[i];
255;    }
256;
257define 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]+]] {
261; TUNIT-NEXT:  entry:
262; TUNIT-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
263; TUNIT-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 1024, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1024) [[BYTES]]) #[[ATTR17]]
264; TUNIT-NEXT:    br label [[FOR_COND:%.*]]
265; TUNIT:       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:%.*]]
271; TUNIT:       for.body:
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]]
275; TUNIT:       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]+]]
278; TUNIT:       for.end:
279; TUNIT-NEXT:    br label [[FOR_COND2:%.*]]
280; TUNIT:       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:%.*]]
286; TUNIT:       for.body5:
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]]
291; TUNIT:       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]+]]
294; TUNIT:       for.end11:
295; TUNIT-NEXT:    br label [[FOR_COND13:%.*]]
296; TUNIT:       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:%.*]]
302; TUNIT:       for.body16:
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]]
307; TUNIT:       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]+]]
310; TUNIT:       for.end24:
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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(524) [[ARRAYIDX26]], i32 noundef 0) #[[ATTR18]]
314; TUNIT-NEXT:    br label [[FOR_COND28:%.*]]
315; TUNIT:       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:%.*]]
321; TUNIT:       for.body31:
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]]
325; TUNIT:       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]+]]
328; TUNIT:       for.end38:
329; TUNIT-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 1024, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1024) [[BYTES]]) #[[ATTR17]]
330; TUNIT-NEXT:    ret void
331;
332; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
333; CGSCC-LABEL: define {{[^@]+}}@local_alloca_simplifiable_2
334; CGSCC-SAME: () #[[ATTR3:[0-9]+]] {
335; CGSCC-NEXT:  entry:
336; CGSCC-NEXT:    [[BYTES:%.*]] = alloca [1024 x i8], align 16
337; CGSCC-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 1024, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1024) [[BYTES]]) #[[ATTR20]]
338; CGSCC-NEXT:    br label [[FOR_COND:%.*]]
339; CGSCC:       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:%.*]]
345; CGSCC:       for.body:
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]]
350; CGSCC:       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]+]]
353; CGSCC:       for.end:
354; CGSCC-NEXT:    br label [[FOR_COND2:%.*]]
355; CGSCC:       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:%.*]]
361; CGSCC:       for.body5:
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]]
367; CGSCC:       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]+]]
370; CGSCC:       for.end11:
371; CGSCC-NEXT:    br label [[FOR_COND13:%.*]]
372; CGSCC:       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:%.*]]
378; CGSCC:       for.body16:
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]]
384; CGSCC:       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]+]]
387; CGSCC:       for.end24:
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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(524) [[ARRAYIDX26]], i32 noundef 0) #[[ATTR21]]
392; CGSCC-NEXT:    br label [[FOR_COND28:%.*]]
393; CGSCC:       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:%.*]]
399; CGSCC:       for.body31:
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]]
405; CGSCC:       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]+]]
408; CGSCC:       for.end38:
409; CGSCC-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 1024, ptr noalias nofree noundef nonnull align 16 captures(none) dereferenceable(1024) [[BYTES]]) #[[ATTR20]]
410; CGSCC-NEXT:    ret void
411;
412entry:
413  %Bytes = alloca [1024 x i8], align 16
414  call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %Bytes)
415  br label %for.cond
416
417for.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
421
422for.cond.cleanup:                                 ; preds = %for.cond
423  br label %for.end
424
425for.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
429  br label %for.inc
430
431for.inc:                                          ; preds = %for.body
432  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
433  br label %for.cond, !llvm.loop !16
434
435for.end:                                          ; preds = %for.cond.cleanup
436  br label %for.cond2
437
438for.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
442
443for.cond.cleanup4:                                ; preds = %for.cond2
444  br label %for.end11
445
446for.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
451  br label %for.inc9
452
453for.inc9:                                         ; preds = %for.body5
454  %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1
455  br label %for.cond2, !llvm.loop !19
456
457for.end11:                                        ; preds = %for.cond.cleanup4
458  br label %for.cond13
459
460for.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
464
465for.cond.cleanup15:                               ; preds = %for.cond13
466  br label %for.end24
467
468for.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
473  br label %for.inc22
474
475for.inc22:                                        ; preds = %for.body16
476  %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1
477  br label %for.cond13, !llvm.loop !22
478
479for.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)
484  br label %for.cond28
485
486for.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
490
491for.cond.cleanup30:                               ; preds = %for.cond28
492  br label %for.end38
493
494for.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
499  br label %for.inc36
500
501for.inc36:                                        ; preds = %for.body31
502  %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1
503  br label %for.cond28, !llvm.loop !23
504
505for.end38:                                        ; preds = %for.cond.cleanup30
506  call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %Bytes)
507  ret void
508}
509
510;    int local_alloca_simplifiable_3() {
511;      int A = 1;
512;      // split
513;      A = 2;
514;      return A;
515;    }
516;
517define 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:%.*]]
522; CHECK:       split:
523; CHECK-NEXT:    ret i32 2
524;
525  %A = alloca i32, align 4
526  store i32 1, ptr %A
527  br label %split
528split:
529  store i32 2, ptr %A
530  %l = load i32, ptr %A, align 4
531  ret i32 %l
532}
533;    int local_alloca_simplifiable_4() {
534;      int A;
535;      return A;
536;    }
537;
538define 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
543;
544  %A = alloca i32, align 4
545  %l = load i32, ptr %A, align 4
546  ret i32 %l
547}
548
549;    static int GI1 __attribute__((loader_uninitialized));
550;    int multi_obj_simplifiable_1(int cnd) {
551;      int L = GI1 = 5;
552;      int *p = cnd ? &GI1 : &L;
553;      return *p;
554;    }
555define 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]] {
559; TUNIT-NEXT:  entry:
560; TUNIT-NEXT:    [[L:%.*]] = alloca i32, align 4
561; TUNIT-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) 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:%.*]]
564; TUNIT:       cond.true:
565; TUNIT-NEXT:    br label [[COND_END:%.*]]
566; TUNIT:       cond.false:
567; TUNIT-NEXT:    br label [[COND_END]]
568; TUNIT:       cond.end:
569; TUNIT-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR17]]
570; TUNIT-NEXT:    ret i32 5
571;
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]+]] {
575; CGSCC-NEXT:  entry:
576; CGSCC-NEXT:    [[L:%.*]] = alloca i32, align 4
577; CGSCC-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) 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:%.*]]
580; CGSCC:       cond.true:
581; CGSCC-NEXT:    br label [[COND_END:%.*]]
582; CGSCC:       cond.false:
583; CGSCC-NEXT:    br label [[COND_END]]
584; CGSCC:       cond.end:
585; CGSCC-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR20]]
586; CGSCC-NEXT:    ret i32 5
587;
588entry:
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
595
596cond.true:                                        ; preds = %entry
597  br label %cond.end
598
599cond.false:                                       ; preds = %entry
600  br label %cond.end
601
602cond.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)
606  ret i32 %i1
607}
608
609;    static int GI2 __attribute__((loader_uninitialized));
610;    int multi_obj_simplifiable_2(int cnd) {
611;      int L;
612;      int *p = cnd ? &GI2 : &L;
613;      *p = 5;
614;      return *p;
615;    }
616;
617define 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]] {
621; TUNIT-NEXT:  entry:
622; TUNIT-NEXT:    [[L:%.*]] = alloca i32, align 4
623; TUNIT-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) 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:%.*]]
626; TUNIT:       cond.true:
627; TUNIT-NEXT:    br label [[COND_END:%.*]]
628; TUNIT:       cond.false:
629; TUNIT-NEXT:    br label [[COND_END]]
630; TUNIT:       cond.end:
631; TUNIT-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR17]]
632; TUNIT-NEXT:    ret i32 5
633;
634; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn
635; CGSCC-LABEL: define {{[^@]+}}@multi_obj_simplifiable_2
636; CGSCC-SAME: (i32 [[CND:%.*]]) #[[ATTR5]] {
637; CGSCC-NEXT:  entry:
638; CGSCC-NEXT:    [[L:%.*]] = alloca i32, align 4
639; CGSCC-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) 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:%.*]]
642; CGSCC:       cond.true:
643; CGSCC-NEXT:    br label [[COND_END:%.*]]
644; CGSCC:       cond.false:
645; CGSCC-NEXT:    br label [[COND_END]]
646; CGSCC:       cond.end:
647; CGSCC-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[L]]) #[[ATTR20]]
648; CGSCC-NEXT:    ret i32 5
649;
650entry:
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
655
656cond.true:                                        ; preds = %entry
657  br label %cond.end
658
659cond.false:                                       ; preds = %entry
660  br label %cond.end
661
662cond.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)
667  ret i32 %l
668}
669
670;    static struct S Gs __attribute__((loader_uninitialized));
671;    struct S static_global_simplifiable_1(void) {
672;      Gs.f1 = 1.1;
673;      Gs.f2 = 2.2;
674;      Gs.f3 = 3.3;
675;      write_arg(&Gs.i1, 1);
676;      write_arg(&Gs.i2, 2);
677;      write_arg(&Gs.i3, 3);
678;      struct S r;
679;      r.f1 = Gs.f1;
680;      r.f2 = Gs.f2 * 2;
681;      r.f3 = Gs.f3 + Gs.f1;
682;      r.i1 = Gs.i1;
683;      r.i2 = Gs.i2 * 2;
684;      r.i3 = Gs.i3 + Gs.i1;
685;      return r;
686;    }
687;
688define 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 nofree writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable_or_null(24) [[AGG_RESULT:%.*]]) #[[ATTR5:[0-9]+]] {
692; TUNIT-NEXT:  entry:
693; TUNIT-NEXT:    call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(24) @Gs1, i32 noundef 1) #[[ATTR18]]
694; TUNIT-NEXT:    call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR18]]
695; TUNIT-NEXT:    call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) 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
708;
709; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
710; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_1
711; CGSCC-SAME: (ptr noalias nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable(24) [[AGG_RESULT:%.*]]) #[[ATTR3]] {
712; CGSCC-NEXT:  entry:
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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(24) @Gs1, i32 noundef 1) #[[ATTR21]]
717; CGSCC-NEXT:    call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(20) getelementptr inbounds ([[STRUCT_S]], ptr @Gs1, i64 0, i32 1), i32 noundef 2) #[[ATTR21]]
718; CGSCC-NEXT:    call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) 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
743;
744entry:
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
774  ret void
775}
776
777define 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
782;
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
787;
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
793  ret i32 %add
794}
795
796define 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]]
805;
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]]
814;
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
820  ret i32 %add
821}
822
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;
831;      GBytes[1023] = 0;
832;      write_arg((int *)&GBytes[500], 0);
833;      struct S R;
834;      for (int i = 0; i < 1024; ++i)
835;        globalBytes[i] = GBytes[i];
836;    }
837;
838define 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]] {
842; TUNIT-NEXT:  entry:
843; TUNIT-NEXT:    br label [[FOR_COND:%.*]]
844; TUNIT:       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:%.*]]
850; TUNIT:       for.body:
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]]
854; TUNIT:       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]+]]
857; TUNIT:       for.end:
858; TUNIT-NEXT:    br label [[FOR_COND2:%.*]]
859; TUNIT:       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:%.*]]
865; TUNIT:       for.body5:
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]]
870; TUNIT:       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]+]]
873; TUNIT:       for.end11:
874; TUNIT-NEXT:    br label [[FOR_COND13:%.*]]
875; TUNIT:       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:%.*]]
881; TUNIT:       for.body16:
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]]
886; TUNIT:       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]+]]
889; TUNIT:       for.end23:
890; TUNIT-NEXT:    call void @write_arg(ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(524) getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 500), i32 noundef 0) #[[ATTR18]]
891; TUNIT-NEXT:    br label [[FOR_COND25:%.*]]
892; TUNIT:       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:%.*]]
898; TUNIT:       for.body28:
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]]
902; TUNIT:       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]+]]
905; TUNIT:       for.end35:
906; TUNIT-NEXT:    ret void
907;
908; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
909; CGSCC-LABEL: define {{[^@]+}}@static_global_simplifiable_2
910; CGSCC-SAME: () #[[ATTR3]] {
911; CGSCC-NEXT:  entry:
912; CGSCC-NEXT:    br label [[FOR_COND:%.*]]
913; CGSCC:       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:%.*]]
919; CGSCC:       for.body:
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]]
924; CGSCC:       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]+]]
927; CGSCC:       for.end:
928; CGSCC-NEXT:    br label [[FOR_COND2:%.*]]
929; CGSCC:       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:%.*]]
935; CGSCC:       for.body5:
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]]
941; CGSCC:       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]+]]
944; CGSCC:       for.end11:
945; CGSCC-NEXT:    br label [[FOR_COND13:%.*]]
946; CGSCC:       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:%.*]]
952; CGSCC:       for.body16:
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]]
958; CGSCC:       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]+]]
961; CGSCC:       for.end23:
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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(524) getelementptr inbounds ([1024 x i8], ptr @GBytes, i64 0, i64 500), i32 noundef 0) #[[ATTR21]]
964; CGSCC-NEXT:    br label [[FOR_COND25:%.*]]
965; CGSCC:       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:%.*]]
971; CGSCC:       for.body28:
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]]
977; CGSCC:       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]+]]
980; CGSCC:       for.end35:
981; CGSCC-NEXT:    ret void
982;
983entry:
984  br label %for.cond
985
986for.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
990
991for.cond.cleanup:                                 ; preds = %for.cond
992  br label %for.end
993
994for.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
998  br label %for.inc
999
1000for.inc:                                          ; preds = %for.body
1001  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
1002  br label %for.cond, !llvm.loop !24
1003
1004for.end:                                          ; preds = %for.cond.cleanup
1005  br label %for.cond2
1006
1007for.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
1011
1012for.cond.cleanup4:                                ; preds = %for.cond2
1013  br label %for.end11
1014
1015for.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
1020  br label %for.inc9
1021
1022for.inc9:                                         ; preds = %for.body5
1023  %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1
1024  br label %for.cond2, !llvm.loop !25
1025
1026for.end11:                                        ; preds = %for.cond.cleanup4
1027  br label %for.cond13
1028
1029for.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
1033
1034for.cond.cleanup15:                               ; preds = %for.cond13
1035  br label %for.end23
1036
1037for.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
1042  br label %for.inc21
1043
1044for.inc21:                                        ; preds = %for.body16
1045  %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1
1046  br label %for.cond13, !llvm.loop !26
1047
1048for.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
1052
1053for.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
1057
1058for.cond.cleanup27:                               ; preds = %for.cond25
1059  br label %for.end35
1060
1061for.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
1066  br label %for.inc33
1067
1068for.inc33:                                        ; preds = %for.body28
1069  %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1
1070  br label %for.cond25, !llvm.loop !27
1071
1072for.end35:                                        ; preds = %for.cond.cleanup27
1073  ret void
1074}
1075
1076;    static int Flag3;
1077;    int static_global_simplifiable_3() {
1078;      Flag3 = 1;
1079;      return Flag3;
1080;    }
1081define 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
1087;
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
1093;
1094  store i32 1, ptr @Flag3, align 4, !tbaa !3
1095  %i = load i32, ptr @Flag3, align 4, !tbaa !3
1096  ret i32 %i
1097}
1098
1099;    struct S noalias_arg_simplifiable_1(struct S s) {
1100;      s.f1 = 1.1;
1101;      s.f2 = 2.2;
1102;      s.f3 = 3.3;
1103;      write_arg(&s.i1, 1);
1104;      write_arg(&s.i2, 2);
1105;      write_arg(&s.i3, 3);
1106;      struct S r;
1107;      r.f1 = s.f1;
1108;      r.f2 = s.f2 * 2;
1109;      r.f3 = s.f3 + s.f1;
1110;      r.i1 = s.i1;
1111;      r.i2 = s.i2 * 2;
1112;      r.i3 = s.i3 + s.i1;
1113;      return r;
1114;    }
1115;
1116define 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 nofree writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable_or_null(24) [[AGG_RESULT:%.*]], ptr noalias nofree nonnull byval([[STRUCT_S]]) align 8 captures(none) 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 nofree noundef nonnull writeonly align 8 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull writeonly align 8 captures(none) 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
1162;
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 nofree noundef nonnull writeonly sret([[STRUCT_S:%.*]]) align 4 captures(none) dereferenceable(24) [[AGG_RESULT:%.*]], ptr noalias nofree noundef nonnull byval([[STRUCT_S]]) align 8 captures(none) 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 nofree noundef nonnull writeonly align 8 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull writeonly align 8 captures(none) 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
1208;
1209entry:
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
1250  ret void
1251}
1252
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;
1260;      Bytes[1023] = 0;
1261;      write_arg((int *)&Bytes[500], 0);
1262;      struct S R;
1263;      for (int i = 0; i < 1024; ++i)
1264;        globalBytes[i] = Bytes[i];
1265;    }
1266;
1267define 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 nofree captures(none) [[BYTES:%.*]]) #[[ATTR3]] {
1271; TUNIT-NEXT:  entry:
1272; TUNIT-NEXT:    br label [[FOR_COND:%.*]]
1273; TUNIT:       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:%.*]]
1279; TUNIT:       for.body:
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]]
1284; TUNIT:       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]+]]
1287; TUNIT:       for.end:
1288; TUNIT-NEXT:    br label [[FOR_COND2:%.*]]
1289; TUNIT:       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:%.*]]
1295; TUNIT:       for.body5:
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]]
1301; TUNIT:       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]+]]
1304; TUNIT:       for.end11:
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]]
1318; TUNIT:       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]+]]
1321; TUNIT:       for.end23:
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 nofree noundef nonnull writeonly align 4 captures(none) [[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]]
1339; TUNIT:       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]+]]
1342; TUNIT:       for.end37:
1343; TUNIT-NEXT:    ret void
1344;
1345; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn
1346; CGSCC-LABEL: define {{[^@]+}}@noalias_arg_simplifiable_2
1347; CGSCC-SAME: (ptr nofree captures(none) [[BYTES:%.*]]) #[[ATTR3]] {
1348; CGSCC-NEXT:  entry:
1349; CGSCC-NEXT:    br label [[FOR_COND:%.*]]
1350; CGSCC:       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:%.*]]
1356; CGSCC:       for.body:
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]]
1361; CGSCC:       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]+]]
1364; CGSCC:       for.end:
1365; CGSCC-NEXT:    br label [[FOR_COND2:%.*]]
1366; CGSCC:       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:%.*]]
1372; CGSCC:       for.body5:
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]]
1378; CGSCC:       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]+]]
1381; CGSCC:       for.end11:
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]]
1395; CGSCC:       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]+]]
1398; CGSCC:       for.end23:
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 nofree noundef nonnull writeonly align 4 captures(none) 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]]
1416; CGSCC:       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]+]]
1419; CGSCC:       for.end37:
1420; CGSCC-NEXT:    ret void
1421;
1422entry:
1423  br label %for.cond
1424
1425for.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
1429
1430for.cond.cleanup:                                 ; preds = %for.cond
1431  br label %for.end
1432
1433for.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
1437  br label %for.inc
1438
1439for.inc:                                          ; preds = %for.body
1440  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
1441  br label %for.cond, !llvm.loop !28
1442
1443for.end:                                          ; preds = %for.cond.cleanup
1444  br label %for.cond2
1445
1446for.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
1450
1451for.cond.cleanup4:                                ; preds = %for.cond2
1452  br label %for.end11
1453
1454for.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
1459  br label %for.inc9
1460
1461for.inc9:                                         ; preds = %for.body5
1462  %indvars.iv.next3 = add nuw nsw i64 %indvars.iv2, 1
1463  br label %for.cond2, !llvm.loop !29
1464
1465for.end11:                                        ; preds = %for.cond.cleanup4
1466  br label %for.cond13
1467
1468for.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
1472
1473for.cond.cleanup15:                               ; preds = %for.cond13
1474  br label %for.end23
1475
1476for.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
1481  br label %for.inc21
1482
1483for.inc21:                                        ; preds = %for.body16
1484  %indvars.iv.next8 = add nuw nsw i64 %indvars.iv7, 1
1485  br label %for.cond13, !llvm.loop !30
1486
1487for.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
1493
1494for.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
1498
1499for.cond.cleanup29:                               ; preds = %for.cond27
1500  br label %for.end37
1501
1502for.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
1507  br label %for.inc35
1508
1509for.inc35:                                        ; preds = %for.body30
1510  %indvars.iv.next13 = add nuw nsw i64 %indvars.iv12, 1
1511  br label %for.cond27, !llvm.loop !31
1512
1513for.end37:                                        ; preds = %for.cond.cleanup29
1514  ret void
1515}
1516
1517;    int local_alloca_not_simplifiable_1() {
1518;      int X, Y, Z;
1519;      X = Y = 1;
1520;      escape(&X);
1521;      write_random(&Y);
1522;      Z = X ? 1 : 2;
1523;      return X + Y + Z;
1524;    }
1525;
1526define 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 nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR17]]
1532; TUNIT-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]])
1544; TUNIT-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]])
1545; TUNIT-NEXT:    ret i32 [[ADD1]]
1546;
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 nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]]) #[[ATTR20]]
1552; CGSCC-NEXT:    call void @llvm.lifetime.start.p0(i64 noundef 4, ptr noalias nofree noundef nonnull align 4 captures(none) 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 nofree noundef nonnull writeonly align 4 captures(none) 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 nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[Y]])
1564; CGSCC-NEXT:    call void @llvm.lifetime.end.p0(i64 noundef 4, ptr nofree noundef nonnull align 4 captures(none) dereferenceable(4) [[X]])
1565; CGSCC-NEXT:    ret i32 [[ADD1]]
1566;
1567entry:
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)
1584  ret i32 %add1
1585}
1586
1587define 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:%.*]]
1595; CHECK:       left:
1596; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX1]]
1597; CHECK-NEXT:    br label [[JOIN:%.*]]
1598; CHECK:       right:
1599; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr inbounds [1024 x i8], ptr [[BYTES]], i64 0, i64 [[INDEX2]]
1600; CHECK-NEXT:    br label [[JOIN]]
1601; CHECK:       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]]
1606;
1607entry:
1608  %Bytes = alloca [1024 x i8], align 16
1609  store i8 7, ptr %Bytes, align 4
1610  br i1 %cnd, label %left, label %right
1611
1612left:                                             ; preds = %entry
1613  %gep1 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %index1
1614  br label %join
1615
1616right:                                            ; preds = %entry
1617  %gep2 = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %index2
1618  br label %join
1619
1620join:                                             ; preds = %right, %left
1621  %gep.join = phi ptr [ %gep1, %left ], [ %gep2, %right ]
1622  store i8 9, ptr %gep.join, align 4
1623
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
1627  ret i8 %i
1628}
1629
1630; We could simplify these if we separate accessed bins wrt. alignment (here mod 4).
1631define 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]]
1649;
1650entry:
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
1663  ret i32 %add2
1664}
1665
1666; The access to bc4b could go anywhere, nothing is simplifiable.
1667define 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]]
1689;
1690entry:
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
1707  ret i32 %add3
1708}
1709
1710declare void @escape(ptr)
1711
1712;    int Flag0 = 0;
1713;    int global_not_simplifiable_1(int cnd) {
1714;      return Flag0;
1715;    }
1716;
1717define 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]]
1724;
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]]
1731;
1732entry:
1733  %i = load i32, ptr @Flag0, align 4, !tbaa !3
1734  ret i32 %i
1735}
1736
1737;    static int Flag1 __attribute__((loader_uninitialized));
1738;    int static_global_not_simplifiable_1(int cnd) {
1739;      int v = Flag1;
1740;      sync();
1741;      if (cnd)
1742;        Flag1 = 1;
1743;      return v;
1744;    }
1745;
1746define 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:%.*]]
1753; CHECK:       if.then:
1754; CHECK-NEXT:    br label [[IF_END]]
1755; CHECK:       if.end:
1756; CHECK-NEXT:    ret i32 1
1757;
1758entry:
1759  %i = load i32, ptr @Flag1, align 4, !tbaa !3
1760  call void @sync()
1761  %tobool.not = icmp eq i32 %cnd, 0
1762  br i1 %tobool.not, label %if.end, label %if.then
1763
1764if.then:                                          ; preds = %entry
1765  store i32 1, ptr @Flag1, align 4, !tbaa !3
1766  br label %if.end
1767
1768if.end:                                           ; preds = %if.then, %entry
1769  ret i32 %i
1770}
1771
1772declare void @sync()
1773
1774;    static int Flag2 __attribute__((loader_uninitialized));
1775;    int static_global_simplifiable_4(int cnd) {
1776;      Flag2 = 1;
1777;      sync();
1778;      int v = Flag2;
1779;      Flag2 = 2;
1780;      return v;
1781;    }
1782define 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]]
1791;
1792entry:
1793  store i32 1, ptr @Flag2, align 4, !tbaa !3
1794  call void @sync()
1795  %i = load i32, ptr @Flag2, align 4, !tbaa !3
1796  store i32 2, ptr @Flag2, align 4, !tbaa !3
1797  ret i32 %i
1798}
1799
1800;    static int Flag2 __attribute__((loader_uninitialized));
1801;    int static_global_not_simplifiable_2(int cnd) {
1802;      Flag2 = 1;
1803;      sync();
1804;      int v = Flag2;
1805;      Flag2 = 2;
1806;      return v;
1807;    }
1808define 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]]
1817;
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]]
1826;
1827entry:
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
1832  ret i32 %i
1833}
1834define 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
1840;
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
1846;
1847  store i32 2, ptr @Flag4, align 4, !tbaa !3
1848  ret void
1849}
1850
1851; Similiar to static_global_simplifiable_3 but with a may-store.
1852define 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 nofree writeonly captures(none) [[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]]
1860;
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 nofree writeonly captures(none) [[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]]
1868;
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
1872  ret i32 %i
1873}
1874
1875
1876;    int write_read{,_static,_static_undef}_global(void) {
1877;      Gint{,static,_static_undef}1 = 7;
1878;      return Gint1;
1879;    }
1880;    void write{,_static,_static_undef}_global(void) {
1881;      Gint{,static,_static_undef}2 = 7;
1882;    }
1883;    int read{,_static,_static_undef}_global(void) {
1884;      return Gint{,static,_static_undef}2;
1885;    }
1886;
1887; FIXME: We could replace these loads.
1888define 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]]
1895;
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]]
1902;
1903  store i32 7, ptr @Gint1
1904  %l = load i32, ptr @Gint1
1905  ret i32 %l
1906}
1907define 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
1913;
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
1919;
1920  store i32 7, ptr @Gint2
1921  ret void
1922}
1923define 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]]
1929;
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]]
1935;
1936  %l = load i32, ptr @Gint2
1937  ret i32 %l
1938}
1939define 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
1944;
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
1949;
1950  store i32 7, ptr @Gstatic_int1
1951  %l = load i32, ptr @Gstatic_int1
1952  ret i32 %l
1953}
1954define 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
1960;
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
1966;
1967  store i32 7, ptr @Gstatic_int2
1968  ret void
1969}
1970define 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]]
1976;
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]]
1982;
1983  %l = load i32, ptr @Gstatic_int2
1984  ret i32 %l
1985}
1986define 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
1991;
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
1996;
1997  store i32 7, ptr @Gstatic_undef_int1
1998  %l = load i32, ptr @Gstatic_undef_int1
1999  ret i32 %l
2000}
2001define 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
2006;
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
2012;
2013  store i32 7, ptr @Gstatic_undef_int2
2014  ret void
2015}
2016define 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
2021;
2022  %l = load i32, ptr @Gstatic_undef_int2
2023  ret i32 %l
2024}
2025
2026define 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
2031;
2032  %l = load i32, ptr @Gstatic_int3
2033  ret i32 %l
2034}
2035
2036define 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:%.*]]
2043; CHECK:       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]]
2051; CHECK:       end:
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]]
2055;
2056entry:
2057  %a = alloca i16
2058  br label %loop
2059loop:
2060  %p = phi ptr [%a, %entry], [%g, %loop]
2061  %i = phi i8 [0, %entry], [%o, %loop]
2062  store i8 1, ptr %p
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
2067end:
2068  %s = getelementptr i8, ptr %a, i64 1
2069  %l = load i8, ptr %s
2070  ret i8 %l
2071}
2072
2073; FIXME: This function returns 1.
2074define i8 @phi_no_store_1() {
2075;
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:%.*]]
2081; TUNIT:       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]]
2089; TUNIT:       end:
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]]
2096;
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:%.*]]
2102; CGSCC:       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]]
2110; CGSCC:       end:
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]]
2117;
2118entry:
2119  br label %loop
2120loop:
2121  %p = phi ptr [@a1, %entry], [%g, %loop]
2122  %i = phi i8 [0, %entry], [%o, %loop]
2123  store i8 1, ptr %p
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
2128end:
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
2134  ret i8 %add
2135}
2136
2137; FIXME: This function returns 1.
2138define i8 @phi_no_store_2() {
2139;
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:%.*]]
2145; TUNIT:       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]]
2153; TUNIT:       end:
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]]
2160;
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:%.*]]
2166; CGSCC:       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]]
2174; CGSCC:       end:
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]]
2181;
2182entry:
2183  br label %loop
2184loop:
2185  %p = phi ptr [@a2, %entry], [%g, %loop]
2186  %i = phi i8 [0, %entry], [%o, %loop]
2187  store i8 1, ptr %p
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
2192end:
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
2198  ret i8 %add
2199}
2200
2201define 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:%.*]]
2209; TUNIT:       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]]
2217; TUNIT:       end:
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]]
2227;
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:%.*]]
2235; CGSCC:       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]]
2243; CGSCC:       end:
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]]
2253;
2254entry:
2255  %s30 = getelementptr i8, ptr @a3, i64 3
2256  store i8 0, ptr %s30
2257  br label %loop
2258loop:
2259  %p = phi ptr [@a3, %entry], [%g, %loop]
2260  %i = phi i8 [0, %entry], [%o, %loop]
2261  store i8 1, ptr %p
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
2266end:
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
2275  ret i8 %add2
2276}
2277
2278define 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]]
2285;
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]]
2292;
2293  store i32 42, ptr @bytes1
2294  %l = load i8, ptr @bytes1
2295  ret i8 %l
2296}
2297
2298define 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]]
2305;
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]]
2312;
2313  store i32 42, ptr @bytes2
2314  %l = load i64, ptr @bytes2
2315  ret i64 %l
2316}
2317
2318define void @recursive_load_store(i64 %N, i32 %v) {
2319;
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:%.*]]
2325; TUNIT:       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:%.*]]
2329; TUNIT:       for.body:
2330; TUNIT-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
2331; TUNIT-NEXT:    br label [[FOR_COND]]
2332; TUNIT:       for.end:
2333; TUNIT-NEXT:    ret void
2334;
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:%.*]]
2340; CGSCC:       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:%.*]]
2344; CGSCC:       for.body:
2345; CGSCC-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
2346; CGSCC-NEXT:    br label [[FOR_COND]]
2347; CGSCC:       for.end:
2348; CGSCC-NEXT:    ret void
2349;
2350entry:
2351  store i32 %v, ptr @rec_storage
2352  br label %for.cond
2353
2354for.cond:
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
2358
2359for.body:
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
2363  br label %for.cond
2364
2365for.end:
2366  %lr = load i32, ptr @rec_storage
2367  store i32 %lr, ptr @rec_storage
2368  ret void
2369}
2370
2371define 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]]
2378;
2379entry:
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
2384  ret i32 %0
2385}
2386
2387define 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
2391;
2392entry:
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
2397  ret i32 %0
2398}
2399
2400declare noalias ptr @malloc(i64) allockind("alloc,uninitialized") allocsize(0) "alloc-family"="malloc"
2401
2402declare void @free(ptr) allockind("free") "alloc-family"="malloc"
2403
2404define 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:%.*]]
2411; CHECK:       if.then:
2412; CHECK-NEXT:    store i32 [[X]], ptr [[CALL_H2S]], align 4
2413; CHECK-NEXT:    br label [[IF_END]]
2414; CHECK:       if.end:
2415; CHECK-NEXT:    ret i32 [[X]]
2416;
2417entry:
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
2421
2422if.then:                                          ; preds = %entry
2423  store i32 %x, ptr %call, align 4
2424  br label %if.end
2425
2426if.end:                                           ; preds = %if.then, %entry
2427  %0 = load i32, ptr %call, align 4
2428  ret i32 %0
2429}
2430
2431define 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]]
2439;
2440entry:
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
2444  ret i32 %0
2445}
2446
2447define 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
2453;
2454entry:
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
2458  ret i32 %0
2459}
2460
2461declare noalias ptr @calloc(i64, i64) allockind("alloc,zeroed") allocsize(0, 1) "alloc-family"="malloc"
2462
2463define 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:%.*]]
2471; CHECK:       if.then:
2472; CHECK-NEXT:    store i32 [[X]], ptr [[CALL_H2S]], align 4
2473; CHECK-NEXT:    br label [[IF_END]]
2474; CHECK:       if.end:
2475; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[CALL_H2S]], align 4
2476; CHECK-NEXT:    ret i32 [[TMP0]]
2477;
2478entry:
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
2482
2483if.then:                                          ; preds = %entry
2484  store i32 %x, ptr %call, align 4
2485  br label %if.end
2486
2487if.end:                                           ; preds = %if.then, %entry
2488  %0 = load i32, ptr %call, align 4
2489  call void @free(ptr %call) norecurse
2490  ret i32 %0
2491}
2492
2493define 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:%.*]]
2500; CHECK:       if.then:
2501; CHECK-NEXT:    br label [[IF_END]]
2502; CHECK:       if.end:
2503; CHECK-NEXT:    ret i32 0
2504;
2505entry:
2506  %call = call noalias ptr @calloc(i64 1, i64 4) norecurse
2507  br i1 %c, label %if.end, label %if.then
2508
2509if.then:                                          ; preds = %entry
2510  store i32 0, ptr %call, align 4
2511  br label %if.end
2512
2513if.end:                                           ; preds = %if.then, %entry
2514  %0 = load i32, ptr %call, align 4
2515  call void @free(ptr %call) norecurse
2516  ret i32 %0
2517}
2518
2519define 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]]
2526;
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]]
2533;
2534entry:
2535  %conv = sext i32 %s to i64
2536  %call = call noalias ptr @malloc(i64 %conv) norecurse
2537  ret ptr %call
2538}
2539
2540define 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]]
2549;
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]]
2558;
2559entry:
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
2564  ret i32 %0
2565}
2566
2567define 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]]
2576;
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]]
2585;
2586entry:
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
2591  ret i32 %0
2592}
2593
2594declare noalias ptr @unknown_alloc(i32)
2595
2596define 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:%.*]]
2603; TUNIT:       if.then:
2604; TUNIT-NEXT:    store i32 [[X]], ptr [[CALL]], align 4
2605; TUNIT-NEXT:    br label [[IF_END]]
2606; TUNIT:       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]]
2610;
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:%.*]]
2617; CGSCC:       if.then:
2618; CGSCC-NEXT:    store i32 [[X]], ptr [[CALL]], align 4
2619; CGSCC-NEXT:    br label [[IF_END]]
2620; CGSCC:       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]]
2624;
2625entry:
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
2629
2630if.then:                                          ; preds = %entry
2631  store i32 %x, ptr %call, align 4
2632  br label %if.end
2633
2634if.end:                                           ; preds = %if.then, %entry
2635  %0 = load i32, ptr %call, align 4
2636  call void @free(ptr %call) norecurse
2637  ret i32 %0
2638}
2639
2640%struct.STy = type { ptr, ptr, ptr }
2641
2642@global = internal global %struct.STy zeroinitializer, align 8
2643
2644; We mark %dst as writeonly and %src as readonly, that is (for now) all we can expect.
2645define dso_local void @test_nested_memory(ptr %dst, ptr %src) {
2646; TUNIT-LABEL: define {{[^@]+}}@test_nested_memory
2647; TUNIT-SAME: (ptr nofree writeonly captures(none) [[DST:%.*]], ptr nofree readonly captures(none) [[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
2664;
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
2677;
2678entry:
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)
2688  ret void
2689}
2690
2691define 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
2713;
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
2735;
2736entry:
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
2747  ret void
2748}
2749
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.
2752define 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 nofree readonly captures(none) [[IN:%.*]], ptr nofree writeonly captures(none) [[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 nofree noundef nonnull align 16 captures(none) dereferenceable(512) [[BUF]]) #[[ATTR17]]
2759; TUNIT-NEXT:    br label [[FOR_COND:%.*]]
2760; TUNIT:       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:%.*]]
2766; TUNIT:       for.body:
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]]
2774; TUNIT:       for.cond4:
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 nofree noundef nonnull align 16 captures(none) dereferenceable(512) [[BUF]]) #[[ATTR17]]
2780; TUNIT-NEXT:    ret void
2781; TUNIT:       for.body7:
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]]
2794;
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 nofree readonly captures(none) [[IN:%.*]], ptr nofree writeonly captures(none) [[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 nofree noundef nonnull align 16 captures(none) dereferenceable(512) [[BUF]]) #[[ATTR20]]
2801; CGSCC-NEXT:    br label [[FOR_COND:%.*]]
2802; CGSCC:       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:%.*]]
2808; CGSCC:       for.body:
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]]
2816; CGSCC:       for.cond4:
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 nofree noundef nonnull align 16 captures(none) dereferenceable(512) [[BUF]]) #[[ATTR20]]
2822; CGSCC-NEXT:    ret void
2823; CGSCC:       for.body7:
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]]
2836;
2837entry:
2838  %buf = alloca [128 x i32], align 16
2839  call void @llvm.lifetime.start.p0(i64 512, ptr %buf) #2
2840  br label %for.cond
2841
2842for.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
2846
2847for.cond.cleanup:                                 ; preds = %for.cond
2848  br label %for.cond4
2849
2850for.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
2858
2859for.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
2863
2864for.cond.cleanup6:                                ; preds = %for.cond4
2865  call void @llvm.lifetime.end.p0(i64 512, ptr %buf) #2
2866  ret void
2867
2868for.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
2881}
2882
2883; Ensure we do not return true.
2884define 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 nofree readonly align 4 captures(none) [[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:%.*]]
2891; TUNIT:       t:
2892; TUNIT-NEXT:    [[R:%.*]] = call i1 @alloca_non_unique(ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR14:[0-9]+]]
2893; TUNIT-NEXT:    ret i1 [[R]]
2894; TUNIT:       f:
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]]
2898;
2899; CGSCC: Function Attrs: nofree nosync nounwind memory(argmem: readwrite)
2900; CGSCC-LABEL: define {{[^@]+}}@alloca_non_unique
2901; CGSCC-SAME: (ptr noalias nofree readonly align 4 captures(none) [[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:%.*]]
2905; CGSCC:       t:
2906; CGSCC-NEXT:    [[R:%.*]] = call i1 @alloca_non_unique(ptr noalias nofree noundef nonnull readonly align 4 captures(none) dereferenceable(4) [[A]], i32 noundef 42, i1 noundef false) #[[ATTR17:[0-9]+]]
2907; CGSCC-NEXT:    ret i1 [[R]]
2908; CGSCC:       f:
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]]
2912;
2913  %a = alloca i32
2914  store i32 %in, ptr %a
2915  br i1 %c, label %t, label %f
2916t:
2917  %r = call i1 @alloca_non_unique(ptr %a, i32 42, i1 false)
2918  ret i1 %r
2919f:
2920  %l = load i32, ptr %p
2921  %cmp = icmp eq i32 %in, %l
2922  ret i1 %cmp
2923}
2924
2925; Ensure we do not return true.
2926define 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]]
2932;
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]]
2938;
2939  %r = call i1 @alloca_non_unique(ptr undef, i32 %in, i1 %c)
2940  ret i1 %r
2941}
2942
2943; Ensure we do not return %bad or %l, but %sel
2944define 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 nofree noundef nonnull align 4 captures(none) 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]]
2954;
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 nofree noundef nonnull align 4 captures(none) 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]]
2964;
2965  %a = alloca i32
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
2970  ret i32 %sel
2971}
2972
2973define 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 nofree noundef nonnull align 4 captures(none) 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
2981;
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 nofree noundef nonnull align 4 captures(none) 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
2989;
2990  %l = load i32, ptr %a
2991  %sel = select i1 %c, i32 %l, i32 42
2992  store i32 %sel, ptr %a
2993  ret void
2994}
2995
2996define 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
3004;
3005entry:
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
3012  ret i8 %i
3013}
3014
3015define 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
3023;
3024entry:
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
3030
3031  %gep.loaded = getelementptr inbounds [1024 x i8], ptr %Bytes, i64 0, i64 %offset
3032  store i8 100, ptr %gep.loaded, align 4
3033
3034  %i = load i8, ptr %gep.fixed, align 4
3035  ret i8 %i
3036}
3037
3038@G = internal global i32 0, align 4
3039
3040; Ensure this is not flattened to return 3
3041define 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:%.*]]
3047; TUNIT:       t:
3048; TUNIT-NEXT:    [[REC:%.*]] = call i32 @a(i1 noundef false) #[[ATTR14]]
3049; TUNIT-NEXT:    br label [[F]]
3050; TUNIT:       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]]
3054;
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:%.*]]
3060; CGSCC:       t:
3061; CGSCC-NEXT:    [[REC:%.*]] = call i32 @a(i1 noundef false) #[[ATTR17]]
3062; CGSCC-NEXT:    br label [[F]]
3063; CGSCC:       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]]
3067;
3068  store i32 3, ptr @G
3069  br i1 %c, label %t, label %f
3070
3071t:
3072  %rec = call i32 @a(i1 false)
3073  br label %f
3074
3075f:
3076  %r = load i32, ptr @G
3077  store i32 5, ptr @G
3078  ret i32 %r
3079}
3080
3081@GC = internal global i32 undef, align 4
3082define 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:%.*]]
3087; TUNIT:       t:
3088; TUNIT-NEXT:    br label [[M]]
3089; TUNIT:       m:
3090; TUNIT-NEXT:    [[ARMW:%.*]] = atomicrmw add ptr @GC, i32 [[I]] monotonic, align 4
3091; TUNIT-NEXT:    ret void
3092;
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:%.*]]
3097; CGSCC:       t:
3098; CGSCC-NEXT:    br label [[M]]
3099; CGSCC:       m:
3100; CGSCC-NEXT:    [[ARMW:%.*]] = atomicrmw add ptr @GC, i32 [[I]] monotonic, align 4
3101; CGSCC-NEXT:    ret void
3102;
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
3108t:
3109  store ptr null, ptr %gep2
3110  br label %m
3111m:
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
3118  ret void
3119}
3120
3121@GRS = internal thread_local global i32 undef
3122@GRS2 = global i32 undef
3123
3124define 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:%.*]]
3129; TUNIT:       rec:
3130; TUNIT-NEXT:    [[RV:%.*]] = call i32 @recSimplify(i32 undef, i1 noundef false) #[[ATTR14]]
3131; TUNIT-NEXT:    ret i32 1
3132; TUNIT:       comp:
3133; TUNIT-NEXT:    store i32 1, ptr @GRS2, align 4
3134; TUNIT-NEXT:    ret i32 1
3135;
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:%.*]]
3140; CGSCC:       rec:
3141; CGSCC-NEXT:    [[RV:%.*]] = call i32 @recSimplify(i32 [[V]], i1 noundef false) #[[ATTR17]]
3142; CGSCC-NEXT:    ret i32 [[RV]]
3143; CGSCC:       comp:
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]]
3151;
3152  br i1 %cond, label %rec, label %comp
3153rec:
3154  %rv = call i32 @recSimplify(i32 %v, i1 false)
3155  ret i32 %rv
3156comp:
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()
3165  ret i32 %r
3166}
3167
3168define 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]]
3174;
3175  %r = load i32, ptr @GRS
3176  ret i32 %r
3177}
3178
3179; Verify we do not return 10.
3180define 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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]]) #[[ATTR18]]
3188; TUNIT-NEXT:    ret i32 8
3189;
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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull writeonly align 4 captures(none) 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]]
3201;
3202entry:
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
3211  ret i32 %add
3212}
3213
3214define 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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[Q:%.*]], ptr nofree noundef nonnull writeonly align 4 captures(none) 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
3222;
3223entry:
3224  store i32 3, ptr %Q, align 4
3225  store i32 5, ptr %R, align 4
3226  ret void
3227}
3228
3229define 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]]
3235;
3236entry:
3237  ret ptr %P
3238}
3239
3240; Verify we do not return 10.
3241define 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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL]], ptr nofree noundef nonnull writeonly align 4 captures(none) 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]]
3255;
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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[CALL]], ptr nofree noundef nonnull writeonly align 4 captures(none) 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]]
3269;
3270entry:
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
3279  ret i32 %add
3280}
3281
3282define 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]]
3289;
3290entry:
3291  %R = select i1 %c, ptr %P, ptr %Q
3292  ret ptr %R
3293}
3294
3295; Verify we do not return 10.
3296define 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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]]) #[[ATTR18]]
3304; TUNIT-NEXT:    ret i32 8
3305;
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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]], ptr noalias nofree noundef nonnull writeonly align 4 captures(none) 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]]
3317;
3318entry:
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
3327  ret i32 %add
3328}
3329
3330; Verify we do not return 10.
3331define 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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]], ptr nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[A]]) #[[ATTR18]]
3339; TUNIT-NEXT:    ret i32 8
3340;
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 nofree noundef nonnull writeonly align 4 captures(none) dereferenceable(4) [[B]], ptr noalias nofree noundef nonnull writeonly align 4 captures(none) 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]]
3352;
3353entry:
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
3362  ret i32 %add
3363}
3364
3365define 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]]
3373;
3374entry:
3375  %R = select i1 %c, ptr %P, ptr %Q
3376  ret ptr %R
3377}
3378define 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]]
3386;
3387entry:
3388  %R = select i1 %c, ptr %P, ptr %Q
3389  ret ptr %R
3390}
3391
3392define 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]]
3398;
3399  %g = getelementptr i8, ptr %p, i32 2
3400  ret ptr %g
3401}
3402define 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]]
3408;
3409  %g = getelementptr i8, ptr %p, i32 4
3410  ret ptr %g
3411}
3412
3413define 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:%.*]]
3419; CHECK:       bg2:
3420; CHECK-NEXT:    [[G2:%.*]] = getelementptr i8, ptr [[P]], i32 2
3421; CHECK-NEXT:    ret ptr [[G2]]
3422; CHECK:       bg46:
3423; CHECK-NEXT:    [[C1:%.*]] = icmp eq i32 [[I]], 1
3424; CHECK-NEXT:    br i1 [[C1]], label [[BG4:%.*]], label [[BG6:%.*]]
3425; CHECK:       bg4:
3426; CHECK-NEXT:    [[G4:%.*]] = getelementptr i8, ptr [[P]], i32 4
3427; CHECK-NEXT:    ret ptr [[G4]]
3428; CHECK:       bg6:
3429; CHECK-NEXT:    [[G6:%.*]] = getelementptr i8, ptr [[P]], i32 6
3430; CHECK-NEXT:    ret ptr [[G6]]
3431;
3432  %c0 = icmp eq i32 %i, 0
3433  br i1 %c0, label %bg2, label %bg46
3434bg2:
3435  %g2 = getelementptr i8, ptr %p, i32 2
3436  ret ptr %g2
3437bg46:
3438  %c1 = icmp eq i32 %i, 1
3439  br i1 %c1, label %bg4, label %bg6
3440bg4:
3441  %g4 = getelementptr i8, ptr %p, i32 4
3442  ret ptr %g4
3443bg6:
3444  %g6 = getelementptr i8, ptr %p, i32 6
3445  ret ptr %g6
3446}
3447
3448declare void @use3i8(i8, i8, i8)
3449
3450define 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
3461;
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
3478;
3479  %a = alloca i64
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
3486  store i8 2, ptr %a2
3487  store i8 4, ptr %a4
3488  store i8 6, ptr %a6
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)
3493  ret void
3494}
3495
3496define 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
3504;
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
3518;
3519  %a = alloca i64
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
3524  store i8 2, ptr %ap
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)
3529  ret void
3530}
3531
3532define 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
3549;
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
3566;
3567  %a = alloca i64
3568  %g2 = getelementptr i8, ptr %a, i32 2
3569  %g4 = getelementptr i8, ptr %a, i32 4
3570  %g6 = getelementptr i8, ptr %a, i32 6
3571  store i8 0, ptr %g2
3572  store i8 0, ptr %g4
3573  store i8 0, ptr %g6
3574  %ap = call ptr @move246(i32 %i, ptr %a)
3575  store i8 2, ptr %ap
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)
3580  ret void
3581}
3582
3583declare void @llvm.assume(i1 noundef)
3584
3585
3586!llvm.module.flags = !{!0, !1}
3587!llvm.ident = !{!2}
3588
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}
3621;.
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) }
3646;.
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 }
3676;.
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]]}
3709;.
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]]}
3742;.
3743