1368d35a8SFlorian Hahn; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2368d35a8SFlorian Hahn; RUN: opt %s -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S | FileCheck %s
3368d35a8SFlorian Hahn
4368d35a8SFlorian Hahntarget datalayout = "e-m:e-i64:64-i128:128-n32:64-S128"
5368d35a8SFlorian Hahn
64bb006d0SFlorian Hahndefine void @same_step_and_size(ptr %a, i32* %b, i64 %n) {
7368d35a8SFlorian Hahn; CHECK-LABEL: @same_step_and_size(
8368d35a8SFlorian Hahn; CHECK-NEXT:  entry:
94bb006d0SFlorian Hahn; CHECK-NEXT:    [[A2:%.*]] = ptrtoint ptr [[A:%.*]] to i64
104bb006d0SFlorian Hahn; CHECK-NEXT:    [[B1:%.*]] = ptrtoint ptr [[B:%.*]] to i64
11368d35a8SFlorian Hahn; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
12368d35a8SFlorian Hahn; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
13368d35a8SFlorian Hahn; CHECK:       vector.memcheck:
14b7315ffcSFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = sub i64 [[B1]], [[A2]]
15b7315ffcSFlorian Hahn; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 16
16b7315ffcSFlorian Hahn; CHECK-NEXT:    br i1 [[DIFF_CHECK]], label %scalar.ph, label %vector.ph
17368d35a8SFlorian Hahn;
18368d35a8SFlorian Hahnentry:
19368d35a8SFlorian Hahn  br label %loop
20368d35a8SFlorian Hahn
21368d35a8SFlorian Hahnloop:
22368d35a8SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
234bb006d0SFlorian Hahn  %gep.a = getelementptr inbounds i32, ptr %a, i64 %iv
244bb006d0SFlorian Hahn  %l = load i32, ptr %gep.a
25368d35a8SFlorian Hahn  %mul = mul nsw i32 %l, 3
264bb006d0SFlorian Hahn  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
274bb006d0SFlorian Hahn  store i32 %mul, ptr %gep.b
28368d35a8SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
29368d35a8SFlorian Hahn  %exitcond = icmp eq i64 %iv.next, %n
30368d35a8SFlorian Hahn  br i1 %exitcond, label %exit, label %loop
31368d35a8SFlorian Hahn
32368d35a8SFlorian Hahnexit:
33368d35a8SFlorian Hahn  ret void
34368d35a8SFlorian Hahn}
35368d35a8SFlorian Hahn
364bb006d0SFlorian Hahndefine void @same_step_and_size_no_dominance_between_accesses(ptr %a, ptr %b, i64 %n, i64 %x) {
37368d35a8SFlorian Hahn; CHECK-LABEL: @same_step_and_size_no_dominance_between_accesses(
38368d35a8SFlorian Hahn; CHECK-NEXT:  entry:
394bb006d0SFlorian Hahn; CHECK-NEXT:    [[B2:%.*]] = ptrtoint ptr [[B:%.*]] to i64
404bb006d0SFlorian Hahn; CHECK-NEXT:    [[A1:%.*]] = ptrtoint ptr [[A:%.*]] to i64
41368d35a8SFlorian Hahn; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
42368d35a8SFlorian Hahn; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
43368d35a8SFlorian Hahn; CHECK:       vector.memcheck:
44b7315ffcSFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = sub i64 [[A1]], [[B2]]
45b7315ffcSFlorian Hahn; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 16
46b7315ffcSFlorian Hahn; CHECK-NEXT:    br i1 [[DIFF_CHECK]], label %scalar.ph, label %vector.ph
47368d35a8SFlorian Hahn;
48368d35a8SFlorian Hahnentry:
49368d35a8SFlorian Hahn  br label %loop
50368d35a8SFlorian Hahn
51368d35a8SFlorian Hahnloop:
52368d35a8SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
53368d35a8SFlorian Hahn  %cmp = icmp ne i64 %iv, %x
54368d35a8SFlorian Hahn  br i1 %cmp, label %then, label %else
55368d35a8SFlorian Hahn
56368d35a8SFlorian Hahnthen:
574bb006d0SFlorian Hahn  %gep.a = getelementptr inbounds i32, ptr %a, i64 %iv
584bb006d0SFlorian Hahn  store i32 0, ptr %gep.a
59368d35a8SFlorian Hahn  br label %loop.latch
60368d35a8SFlorian Hahn
61368d35a8SFlorian Hahnelse:
624bb006d0SFlorian Hahn  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
634bb006d0SFlorian Hahn  store i32 10, ptr %gep.b
64368d35a8SFlorian Hahn  br label %loop.latch
65368d35a8SFlorian Hahn
66368d35a8SFlorian Hahnloop.latch:
67368d35a8SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
68368d35a8SFlorian Hahn  %exitcond = icmp eq i64 %iv.next, %n
69368d35a8SFlorian Hahn  br i1 %exitcond, label %exit, label %loop
70368d35a8SFlorian Hahn
71368d35a8SFlorian Hahnexit:
72368d35a8SFlorian Hahn  ret void
73368d35a8SFlorian Hahn}
74368d35a8SFlorian Hahn
754bb006d0SFlorian Hahndefine void @different_steps_and_different_access_sizes(ptr %a, ptr %b, i64 %n) {
76368d35a8SFlorian Hahn; CHECK-LABEL: @different_steps_and_different_access_sizes(
77368d35a8SFlorian Hahn; CHECK-NEXT:  entry:
78368d35a8SFlorian Hahn; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
79368d35a8SFlorian Hahn; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
80368d35a8SFlorian Hahn; CHECK:       vector.memcheck:
814bb006d0SFlorian Hahn; CHECK-NEXT:    [[N_SHL_2:%.]] = shl i64 %n, 2
824bb006d0SFlorian Hahn; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr %b, i64 [[N_SHL_2]]
834bb006d0SFlorian Hahn; CHECK-NEXT:    [[N_SHL_1:%.]] = shl i64 %n, 1
844bb006d0SFlorian Hahn; CHECK-NEXT:    [[SCEVGEP4:%.*]] = getelementptr i8, ptr %a, i64 [[N_SHL_1]]
854bb006d0SFlorian Hahn; CHECK-NEXT:    [[BOUND0:%.*]] = icmp ult ptr %b, [[SCEVGEP4]]
864bb006d0SFlorian Hahn; CHECK-NEXT:    [[BOUND1:%.*]] = icmp ult ptr %a, [[SCEVGEP]]
87368d35a8SFlorian Hahn; CHECK-NEXT:    [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
88368d35a8SFlorian Hahn; CHECK-NEXT:    br i1 [[FOUND_CONFLICT]], label %scalar.ph, label %vector.ph
89368d35a8SFlorian Hahn;
90368d35a8SFlorian Hahnentry:
91368d35a8SFlorian Hahn  br label %loop
92368d35a8SFlorian Hahn
93368d35a8SFlorian Hahnloop:
94368d35a8SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
954bb006d0SFlorian Hahn  %gep.a = getelementptr inbounds i16, ptr %a, i64 %iv
964bb006d0SFlorian Hahn  %l = load i16, ptr %gep.a
97368d35a8SFlorian Hahn  %l.ext = sext i16 %l to i32
98368d35a8SFlorian Hahn  %mul = mul nsw i32 %l.ext, 3
994bb006d0SFlorian Hahn  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1004bb006d0SFlorian Hahn  store i32 %mul, ptr %gep.b
101368d35a8SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
102368d35a8SFlorian Hahn  %exitcond = icmp eq i64 %iv.next, %n
103368d35a8SFlorian Hahn  br i1 %exitcond, label %exit, label %loop
104368d35a8SFlorian Hahn
105368d35a8SFlorian Hahnexit:
106368d35a8SFlorian Hahn  ret void
107368d35a8SFlorian Hahn}
108368d35a8SFlorian Hahn
1094bb006d0SFlorian Hahndefine void @steps_match_but_different_access_sizes_1(ptr %a, ptr %b, i64 %n) {
110368d35a8SFlorian Hahn; CHECK-LABEL: @steps_match_but_different_access_sizes_1(
111368d35a8SFlorian Hahn; CHECK-NEXT:  entry:
1124bb006d0SFlorian Hahn; CHECK-NEXT:    [[A2:%.*]] = ptrtoint ptr [[A:%.*]] to i64
1134bb006d0SFlorian Hahn; CHECK-NEXT:    [[B1:%.*]] = ptrtoint ptr [[B:%.*]] to i64
114368d35a8SFlorian Hahn; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
115368d35a8SFlorian Hahn; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
116368d35a8SFlorian Hahn; CHECK:       vector.memcheck:
117b7315ffcSFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i64 [[A2]], 2
118b7315ffcSFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[B1]], [[TMP0]]
119b7315ffcSFlorian Hahn; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP1]], 16
120b7315ffcSFlorian Hahn; CHECK-NEXT:    br i1 [[DIFF_CHECK]], label %scalar.ph, label %vector.ph
121368d35a8SFlorian Hahn;
122368d35a8SFlorian Hahnentry:
123368d35a8SFlorian Hahn  br label %loop
124368d35a8SFlorian Hahn
125368d35a8SFlorian Hahnloop:
126368d35a8SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1274bb006d0SFlorian Hahn  %gep.a = getelementptr inbounds [2 x i16], ptr %a, i64 %iv, i64 1
1284bb006d0SFlorian Hahn  %l = load i16, ptr %gep.a
129368d35a8SFlorian Hahn  %l.ext = sext i16 %l to i32
130368d35a8SFlorian Hahn  %mul = mul nsw i32 %l.ext, 3
1314bb006d0SFlorian Hahn  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1324bb006d0SFlorian Hahn  store i32 %mul, ptr %gep.b
133368d35a8SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
134368d35a8SFlorian Hahn  %exitcond = icmp eq i64 %iv.next, %n
135368d35a8SFlorian Hahn  br i1 %exitcond, label %exit, label %loop
136368d35a8SFlorian Hahn
137368d35a8SFlorian Hahnexit:
138368d35a8SFlorian Hahn  ret void
139368d35a8SFlorian Hahn}
140368d35a8SFlorian Hahn
141368d35a8SFlorian Hahn; Same as @steps_match_but_different_access_sizes_1, but with source and sink
142368d35a8SFlorian Hahn; accesses flipped.
1434bb006d0SFlorian Hahndefine void @steps_match_but_different_access_sizes_2(ptr %a, ptr %b, i64 %n) {
144368d35a8SFlorian Hahn; CHECK-LABEL: @steps_match_but_different_access_sizes_2(
145368d35a8SFlorian Hahn; CHECK-NEXT:  entry:
1464bb006d0SFlorian Hahn; CHECK-NEXT:    [[B2:%.*]] = ptrtoint ptr [[B:%.*]] to i64
1474bb006d0SFlorian Hahn; CHECK-NEXT:    [[A1:%.*]] = ptrtoint ptr [[A:%.*]] to i64
148368d35a8SFlorian Hahn; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
149368d35a8SFlorian Hahn; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
150368d35a8SFlorian Hahn; CHECK:       vector.memcheck:
151b7315ffcSFlorian Hahn; CHECK-NEXT:    [[TMP0:%.*]] = add nuw i64 [[A1]], 2
152b7315ffcSFlorian Hahn; CHECK-NEXT:    [[TMP1:%.*]] = sub i64 [[TMP0]], [[B2]]
153b7315ffcSFlorian Hahn; CHECK-NEXT:    [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP1]], 16
154b7315ffcSFlorian Hahn; CHECK-NEXT:    br i1 [[DIFF_CHECK]], label %scalar.ph, label %vector.ph
155368d35a8SFlorian Hahn;
156368d35a8SFlorian Hahnentry:
157368d35a8SFlorian Hahn  br label %loop
158368d35a8SFlorian Hahn
159368d35a8SFlorian Hahnloop:
160368d35a8SFlorian Hahn  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
1614bb006d0SFlorian Hahn  %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1624bb006d0SFlorian Hahn  %l = load i32, ptr %gep.b
163368d35a8SFlorian Hahn  %mul = mul nsw i32 %l, 3
1644bb006d0SFlorian Hahn  %gep.a = getelementptr inbounds [2 x i16], ptr %a, i64 %iv, i64 1
165368d35a8SFlorian Hahn  %trunc = trunc i32 %mul to i16
1664bb006d0SFlorian Hahn  store i16 %trunc, ptr %gep.a
167368d35a8SFlorian Hahn  %iv.next = add nuw nsw i64 %iv, 1
168368d35a8SFlorian Hahn  %exitcond = icmp eq i64 %iv.next, %n
169368d35a8SFlorian Hahn  br i1 %exitcond, label %exit, label %loop
170368d35a8SFlorian Hahn
171368d35a8SFlorian Hahnexit:
172368d35a8SFlorian Hahn  ret void
173368d35a8SFlorian Hahn}
174afde142bSFlorian Hahn
175*9070c258SFlorian Hahn; Full no-overlap checks are required instead of difference checks, as
176afde142bSFlorian Hahn; one of the add-recs used is invariant in the inner loop.
177afde142bSFlorian Hahn; Test case for PR57315.
1783367244bSFlorian Hahndefine void @nested_loop_outer_iv_addrec_invariant_in_inner1(ptr %a, ptr %b, i64 %n) {
1793367244bSFlorian Hahn; CHECK-LABEL: @nested_loop_outer_iv_addrec_invariant_in_inner1(
180afde142bSFlorian Hahn; CHECK:        entry:
181*9070c258SFlorian Hahn; CHECK-NEXT:    [[N_SHL_2:%.]] = shl i64 %n, 2
182*9070c258SFlorian Hahn; CHECK-NEXT:    [[B_GEP_UPPER:%.*]] = getelementptr i8, ptr %b, i64 [[N_SHL_2]]
183*9070c258SFlorian Hahn; CHECK-NEXT:    br label %outer
184*9070c258SFlorian Hahn
185*9070c258SFlorian Hahn; CHECK:       outer.header:
186*9070c258SFlorian Hahn; CHECK:         [[OUTER_IV_SHL_2:%.]] = shl i64 %outer.iv, 2
187*9070c258SFlorian Hahn; CHECK-NEXT:    [[A_GEP_UPPER:%.*]] = getelementptr i8, ptr %a, i64 [[OUTER_IV_SHL_2]]
188*9070c258SFlorian Hahn; CHECK-NEXT:    [[OUTER_IV_4:%.]] = add i64 [[OUTER_IV_SHL_2]], 4
189*9070c258SFlorian Hahn; CHECK-NEXT:    [[A_GEP_UPPER_4:%.*]] = getelementptr i8, ptr %a, i64 [[OUTER_IV_4]]
190*9070c258SFlorian Hahn; CHECK:         [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
191*9070c258SFlorian Hahn; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
192*9070c258SFlorian Hahn
193afde142bSFlorian Hahn; CHECK:       vector.memcheck:
194*9070c258SFlorian Hahn; CHECK-NEXT:    [[BOUND0:%.*]] = icmp ult ptr [[A_GEP_UPPER]], [[B_GEP_UPPER]]
195*9070c258SFlorian Hahn; CHECK-NEXT:    [[BOUND1:%.*]] = icmp ult ptr %b, [[A_GEP_UPPER_4]]
196*9070c258SFlorian Hahn; CHECK-NEXT:    [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
197*9070c258SFlorian Hahn; CHECK-NEXT:    br i1 [[FOUND_CONFLICT]], label %scalar.ph, label %vector.ph
198afde142bSFlorian Hahn;
199afde142bSFlorian Hahnentry:
200afde142bSFlorian Hahn  br label %outer.header
201afde142bSFlorian Hahn
202afde142bSFlorian Hahnouter.header:
203afde142bSFlorian Hahn  %outer.iv = phi i64 [ %outer.iv.next, %outer.latch ], [ 0, %entry ]
204afde142bSFlorian Hahn  %gep.a = getelementptr inbounds i32, ptr %a, i64 %outer.iv
205afde142bSFlorian Hahn  br label %inner.body
206afde142bSFlorian Hahn
207afde142bSFlorian Hahninner.body:
208afde142bSFlorian Hahn  %inner.iv = phi i64 [ 0, %outer.header ], [ %inner.iv.next, %inner.body ]
209afde142bSFlorian Hahn  %gep.b = getelementptr inbounds i32, ptr %b, i64 %inner.iv
210afde142bSFlorian Hahn  %l = load i32, ptr %gep.b, align 4
2113367244bSFlorian Hahn  %sub = sub i32 %l, 10
2123367244bSFlorian Hahn  store i32 %sub, ptr %gep.a, align 4
2133367244bSFlorian Hahn  %inner.iv.next = add nuw nsw i64 %inner.iv, 1
2143367244bSFlorian Hahn  %inner.cond = icmp eq i64 %inner.iv.next, %n
2153367244bSFlorian Hahn  br i1 %inner.cond, label %outer.latch, label %inner.body
2163367244bSFlorian Hahn
2173367244bSFlorian Hahnouter.latch:
2183367244bSFlorian Hahn  %outer.iv.next = add nuw nsw i64 %outer.iv, 1
2193367244bSFlorian Hahn  %outer.cond = icmp eq i64 %outer.iv.next, %n
2203367244bSFlorian Hahn  br i1 %outer.cond, label %exit, label %outer.header
2213367244bSFlorian Hahn
2223367244bSFlorian Hahnexit:
2233367244bSFlorian Hahn  ret void
2243367244bSFlorian Hahn}
2253367244bSFlorian Hahn
2263367244bSFlorian Hahn; Same as @nested_loop_outer_iv_addrec_invariant_in_inner1 but with dependence
2273367244bSFlorian Hahn; sink and source swapped.
2283367244bSFlorian Hahndefine void @nested_loop_outer_iv_addrec_invariant_in_inner2(ptr %a, ptr %b, i64 %n) {
2293367244bSFlorian Hahn; CHECK-LABEL: @nested_loop_outer_iv_addrec_invariant_in_inner2(
2303367244bSFlorian Hahn; CHECK:        entry:
231*9070c258SFlorian Hahn; CHECK-NEXT:    [[N_SHL_2:%.]] = shl i64 %n, 2
232*9070c258SFlorian Hahn; CHECK-NEXT:    [[B_GEP_UPPER:%.*]] = getelementptr i8, ptr %b, i64 [[N_SHL_2]]
233*9070c258SFlorian Hahn; CHECK-NEXT:    br label %outer
234*9070c258SFlorian Hahn
235*9070c258SFlorian Hahn; CHECK:       outer.header:
236*9070c258SFlorian Hahn; CHECK:         [[OUTER_IV_SHL_2:%.]] = shl i64 %outer.iv, 2
237*9070c258SFlorian Hahn; CHECK-NEXT:    [[A_GEP_UPPER:%.*]] = getelementptr i8, ptr %a, i64 [[OUTER_IV_SHL_2]]
238*9070c258SFlorian Hahn; CHECK-NEXT:    [[OUTER_IV_4:%.]] = add i64 [[OUTER_IV_SHL_2]], 4
239*9070c258SFlorian Hahn; CHECK-NEXT:    [[A_GEP_UPPER_4:%.*]] = getelementptr i8, ptr %a, i64 [[OUTER_IV_4]]
240*9070c258SFlorian Hahn; CHECK:         [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
241*9070c258SFlorian Hahn; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
242*9070c258SFlorian Hahn
2433367244bSFlorian Hahn; CHECK:       vector.memcheck:
244*9070c258SFlorian Hahn; CHECK-NEXT:    [[BOUND0:%.*]] = icmp ult ptr %b, [[A_GEP_UPPER_4]]
245*9070c258SFlorian Hahn; CHECK-NEXT:    [[BOUND1:%.*]] = icmp ult ptr [[A_GEP_UPPER]], [[B_GEP_UPPER]]
246*9070c258SFlorian Hahn; CHECK-NEXT:    [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
247*9070c258SFlorian Hahn; CHECK-NEXT:    br i1 [[FOUND_CONFLICT]], label %scalar.ph, label %vector.ph
2483367244bSFlorian Hahn;
2493367244bSFlorian Hahnentry:
2503367244bSFlorian Hahn  br label %outer.header
2513367244bSFlorian Hahn
2523367244bSFlorian Hahnouter.header:
2533367244bSFlorian Hahn  %outer.iv = phi i64 [ %outer.iv.next, %outer.latch ], [ 0, %entry ]
2543367244bSFlorian Hahn  %gep.a = getelementptr inbounds i32, ptr %a, i64 %outer.iv
2553367244bSFlorian Hahn  br label %inner.body
2563367244bSFlorian Hahn
2573367244bSFlorian Hahninner.body:
2583367244bSFlorian Hahn  %inner.iv = phi i64 [ 0, %outer.header ], [ %inner.iv.next, %inner.body ]
2593367244bSFlorian Hahn  %l = load i32, ptr %gep.a, align 4
2603367244bSFlorian Hahn  %sub = sub i32 %l, 10
2613367244bSFlorian Hahn  %gep.b = getelementptr inbounds i32, ptr %b, i64 %inner.iv
2623367244bSFlorian Hahn  store i32 %sub, ptr %gep.b, align 4
263afde142bSFlorian Hahn  %inner.iv.next = add nuw nsw i64 %inner.iv, 1
264afde142bSFlorian Hahn  %inner.cond = icmp eq i64 %inner.iv.next, %n
265afde142bSFlorian Hahn  br i1 %inner.cond, label %outer.latch, label %inner.body
266afde142bSFlorian Hahn
267afde142bSFlorian Hahnouter.latch:
268afde142bSFlorian Hahn  %outer.iv.next = add nuw nsw i64 %outer.iv, 1
269afde142bSFlorian Hahn  %outer.cond = icmp eq i64 %outer.iv.next, %n
270afde142bSFlorian Hahn  br i1 %outer.cond, label %exit, label %outer.header
271afde142bSFlorian Hahn
272afde142bSFlorian Hahnexit:
273afde142bSFlorian Hahn  ret void
274afde142bSFlorian Hahn}
275