1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -loop-unroll -unroll-allow-partial -unroll-optsize-threshold=18 -mtriple=thumbv8 -S %s -o - | FileCheck %s --check-prefix=CHECK-V8
3
4define void @test_i32_add_optsize(i32* %a, i32* %b, i32* %c) #0 {
5; CHECK-V8-LABEL: @test_i32_add_optsize(
6; CHECK-V8-NEXT:  entry:
7; CHECK-V8-NEXT:    br label [[LOOP:%.*]]
8; CHECK-V8:       loop:
9; CHECK-V8-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
10; CHECK-V8-NEXT:    [[ADDR_A:%.*]] = getelementptr i32, i32* [[A:%.*]], i32 [[IV]]
11; CHECK-V8-NEXT:    [[ADDR_B:%.*]] = getelementptr i32, i32* [[B:%.*]], i32 [[IV]]
12; CHECK-V8-NEXT:    [[DATA_A:%.*]] = load i32, i32* [[ADDR_A]], align 4
13; CHECK-V8-NEXT:    [[DATA_B:%.*]] = load i32, i32* [[ADDR_B]], align 4
14; CHECK-V8-NEXT:    [[RES:%.*]] = add i32 [[DATA_A]], [[DATA_B]]
15; CHECK-V8-NEXT:    [[ADDR_C:%.*]] = getelementptr i32, i32* [[C:%.*]], i32 [[IV]]
16; CHECK-V8-NEXT:    store i32 [[RES]], i32* [[ADDR_C]], align 4
17; CHECK-V8-NEXT:    [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
18; CHECK-V8-NEXT:    [[ADDR_A_1:%.*]] = getelementptr i32, i32* [[A]], i32 [[COUNT]]
19; CHECK-V8-NEXT:    [[ADDR_B_1:%.*]] = getelementptr i32, i32* [[B]], i32 [[COUNT]]
20; CHECK-V8-NEXT:    [[DATA_A_1:%.*]] = load i32, i32* [[ADDR_A_1]], align 4
21; CHECK-V8-NEXT:    [[DATA_B_1:%.*]] = load i32, i32* [[ADDR_B_1]], align 4
22; CHECK-V8-NEXT:    [[RES_1:%.*]] = add i32 [[DATA_A_1]], [[DATA_B_1]]
23; CHECK-V8-NEXT:    [[ADDR_C_1:%.*]] = getelementptr i32, i32* [[C]], i32 [[COUNT]]
24; CHECK-V8-NEXT:    store i32 [[RES_1]], i32* [[ADDR_C_1]], align 4
25; CHECK-V8-NEXT:    [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
26; CHECK-V8-NEXT:    [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
27; CHECK-V8-NEXT:    br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
28; CHECK-V8:       exit:
29; CHECK-V8-NEXT:    ret void
30;
31entry:
32  br label %loop
33
34loop:
35  %iv = phi i32 [ 0, %entry ], [ %count, %loop ]
36  %addr.a = getelementptr i32, i32* %a, i32 %iv
37  %addr.b = getelementptr i32, i32* %b, i32 %iv
38  %data.a = load i32, i32* %addr.a
39  %data.b = load i32, i32* %addr.b
40  %res = add i32 %data.a, %data.b
41  %addr.c = getelementptr i32, i32* %c, i32 %iv
42  store i32 %res, i32* %addr.c
43  %count = add nuw i32 %iv, 1
44  %end = icmp ne i32 %count, 100
45  br i1 %end, label %loop, label %exit
46
47exit:
48  ret void
49}
50
51define void @test_i32_add_minsize(i32* %a, i32* %b, i32* %c) #1 {
52; CHECK-V8-LABEL: @test_i32_add_minsize(
53; CHECK-V8-NEXT:  entry:
54; CHECK-V8-NEXT:    br label [[LOOP:%.*]]
55; CHECK-V8:       loop:
56; CHECK-V8-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
57; CHECK-V8-NEXT:    [[ADDR_A:%.*]] = getelementptr i32, i32* [[A:%.*]], i32 [[IV]]
58; CHECK-V8-NEXT:    [[ADDR_B:%.*]] = getelementptr i32, i32* [[B:%.*]], i32 [[IV]]
59; CHECK-V8-NEXT:    [[DATA_A:%.*]] = load i32, i32* [[ADDR_A]], align 4
60; CHECK-V8-NEXT:    [[DATA_B:%.*]] = load i32, i32* [[ADDR_B]], align 4
61; CHECK-V8-NEXT:    [[RES:%.*]] = add i32 [[DATA_A]], [[DATA_B]]
62; CHECK-V8-NEXT:    [[ADDR_C:%.*]] = getelementptr i32, i32* [[C:%.*]], i32 [[IV]]
63; CHECK-V8-NEXT:    store i32 [[RES]], i32* [[ADDR_C]], align 4
64; CHECK-V8-NEXT:    [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
65; CHECK-V8-NEXT:    [[ADDR_A_1:%.*]] = getelementptr i32, i32* [[A]], i32 [[COUNT]]
66; CHECK-V8-NEXT:    [[ADDR_B_1:%.*]] = getelementptr i32, i32* [[B]], i32 [[COUNT]]
67; CHECK-V8-NEXT:    [[DATA_A_1:%.*]] = load i32, i32* [[ADDR_A_1]], align 4
68; CHECK-V8-NEXT:    [[DATA_B_1:%.*]] = load i32, i32* [[ADDR_B_1]], align 4
69; CHECK-V8-NEXT:    [[RES_1:%.*]] = add i32 [[DATA_A_1]], [[DATA_B_1]]
70; CHECK-V8-NEXT:    [[ADDR_C_1:%.*]] = getelementptr i32, i32* [[C]], i32 [[COUNT]]
71; CHECK-V8-NEXT:    store i32 [[RES_1]], i32* [[ADDR_C_1]], align 4
72; CHECK-V8-NEXT:    [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
73; CHECK-V8-NEXT:    [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
74; CHECK-V8-NEXT:    br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
75; CHECK-V8:       exit:
76; CHECK-V8-NEXT:    ret void
77;
78entry:
79  br label %loop
80
81loop:
82  %iv = phi i32 [ 0, %entry ], [ %count, %loop ]
83  %addr.a = getelementptr i32, i32* %a, i32 %iv
84  %addr.b = getelementptr i32, i32* %b, i32 %iv
85  %data.a = load i32, i32* %addr.a
86  %data.b = load i32, i32* %addr.b
87  %res = add i32 %data.a, %data.b
88  %addr.c = getelementptr i32, i32* %c, i32 %iv
89  store i32 %res, i32* %addr.c
90  %count = add nuw i32 %iv, 1
91  %end = icmp ne i32 %count, 100
92  br i1 %end, label %loop, label %exit
93
94exit:
95  ret void
96}
97
98define void @test_i64_add_optsize(i64* %a, i64* %b, i64* %c) #0 {
99; CHECK-V8-LABEL: @test_i64_add_optsize(
100; CHECK-V8-NEXT:  entry:
101; CHECK-V8-NEXT:    br label [[LOOP:%.*]]
102; CHECK-V8:       loop:
103; CHECK-V8-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
104; CHECK-V8-NEXT:    [[ADDR_A:%.*]] = getelementptr i64, i64* [[A:%.*]], i32 [[IV]]
105; CHECK-V8-NEXT:    [[ADDR_B:%.*]] = getelementptr i64, i64* [[B:%.*]], i32 [[IV]]
106; CHECK-V8-NEXT:    [[DATA_A:%.*]] = load i64, i64* [[ADDR_A]], align 4
107; CHECK-V8-NEXT:    [[DATA_B:%.*]] = load i64, i64* [[ADDR_B]], align 4
108; CHECK-V8-NEXT:    [[RES:%.*]] = add i64 [[DATA_A]], [[DATA_B]]
109; CHECK-V8-NEXT:    [[ADDR_C:%.*]] = getelementptr i64, i64* [[C:%.*]], i32 [[IV]]
110; CHECK-V8-NEXT:    store i64 [[RES]], i64* [[ADDR_C]], align 4
111; CHECK-V8-NEXT:    [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
112; CHECK-V8-NEXT:    [[ADDR_A_1:%.*]] = getelementptr i64, i64* [[A]], i32 [[COUNT]]
113; CHECK-V8-NEXT:    [[ADDR_B_1:%.*]] = getelementptr i64, i64* [[B]], i32 [[COUNT]]
114; CHECK-V8-NEXT:    [[DATA_A_1:%.*]] = load i64, i64* [[ADDR_A_1]], align 4
115; CHECK-V8-NEXT:    [[DATA_B_1:%.*]] = load i64, i64* [[ADDR_B_1]], align 4
116; CHECK-V8-NEXT:    [[RES_1:%.*]] = add i64 [[DATA_A_1]], [[DATA_B_1]]
117; CHECK-V8-NEXT:    [[ADDR_C_1:%.*]] = getelementptr i64, i64* [[C]], i32 [[COUNT]]
118; CHECK-V8-NEXT:    store i64 [[RES_1]], i64* [[ADDR_C_1]], align 4
119; CHECK-V8-NEXT:    [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
120; CHECK-V8-NEXT:    [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
121; CHECK-V8-NEXT:    br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
122; CHECK-V8:       exit:
123; CHECK-V8-NEXT:    ret void
124;
125entry:
126  br label %loop
127
128loop:
129  %iv = phi i32 [ 0, %entry ], [ %count, %loop ]
130  %addr.a = getelementptr i64, i64* %a, i32 %iv
131  %addr.b = getelementptr i64, i64* %b, i32 %iv
132  %data.a = load i64, i64* %addr.a
133  %data.b = load i64, i64* %addr.b
134  %res = add i64 %data.a, %data.b
135  %addr.c = getelementptr i64, i64* %c, i32 %iv
136  store i64 %res, i64* %addr.c
137  %count = add nuw i32 %iv, 1
138  %end = icmp ne i32 %count, 100
139  br i1 %end, label %loop, label %exit
140
141exit:
142  ret void
143}
144
145define void @test_i64_add_minsize(i64* %a, i64* %b, i64* %c) #1 {
146; CHECK-V8-LABEL: @test_i64_add_minsize(
147; CHECK-V8-NEXT:  entry:
148; CHECK-V8-NEXT:    br label [[LOOP:%.*]]
149; CHECK-V8:       loop:
150; CHECK-V8-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
151; CHECK-V8-NEXT:    [[ADDR_A:%.*]] = getelementptr i64, i64* [[A:%.*]], i32 [[IV]]
152; CHECK-V8-NEXT:    [[ADDR_B:%.*]] = getelementptr i64, i64* [[B:%.*]], i32 [[IV]]
153; CHECK-V8-NEXT:    [[DATA_A:%.*]] = load i64, i64* [[ADDR_A]], align 4
154; CHECK-V8-NEXT:    [[DATA_B:%.*]] = load i64, i64* [[ADDR_B]], align 4
155; CHECK-V8-NEXT:    [[RES:%.*]] = add i64 [[DATA_A]], [[DATA_B]]
156; CHECK-V8-NEXT:    [[ADDR_C:%.*]] = getelementptr i64, i64* [[C:%.*]], i32 [[IV]]
157; CHECK-V8-NEXT:    store i64 [[RES]], i64* [[ADDR_C]], align 4
158; CHECK-V8-NEXT:    [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
159; CHECK-V8-NEXT:    [[ADDR_A_1:%.*]] = getelementptr i64, i64* [[A]], i32 [[COUNT]]
160; CHECK-V8-NEXT:    [[ADDR_B_1:%.*]] = getelementptr i64, i64* [[B]], i32 [[COUNT]]
161; CHECK-V8-NEXT:    [[DATA_A_1:%.*]] = load i64, i64* [[ADDR_A_1]], align 4
162; CHECK-V8-NEXT:    [[DATA_B_1:%.*]] = load i64, i64* [[ADDR_B_1]], align 4
163; CHECK-V8-NEXT:    [[RES_1:%.*]] = add i64 [[DATA_A_1]], [[DATA_B_1]]
164; CHECK-V8-NEXT:    [[ADDR_C_1:%.*]] = getelementptr i64, i64* [[C]], i32 [[COUNT]]
165; CHECK-V8-NEXT:    store i64 [[RES_1]], i64* [[ADDR_C_1]], align 4
166; CHECK-V8-NEXT:    [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
167; CHECK-V8-NEXT:    [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
168; CHECK-V8-NEXT:    br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
169; CHECK-V8:       exit:
170; CHECK-V8-NEXT:    ret void
171;
172entry:
173  br label %loop
174
175loop:
176  %iv = phi i32 [ 0, %entry ], [ %count, %loop ]
177  %addr.a = getelementptr i64, i64* %a, i32 %iv
178  %addr.b = getelementptr i64, i64* %b, i32 %iv
179  %data.a = load i64, i64* %addr.a
180  %data.b = load i64, i64* %addr.b
181  %res = add i64 %data.a, %data.b
182  %addr.c = getelementptr i64, i64* %c, i32 %iv
183  store i64 %res, i64* %addr.c
184  %count = add nuw i32 %iv, 1
185  %end = icmp ne i32 %count, 100
186  br i1 %end, label %loop, label %exit
187
188exit:
189  ret void
190}
191
192define i32 @test_i32_select_optsize(i32* %a, i32* %b, i32* %c) #0 {
193; CHECK-V8-LABEL: @test_i32_select_optsize(
194; CHECK-V8-NEXT:  entry:
195; CHECK-V8-NEXT:    br label [[LOOP:%.*]]
196; CHECK-V8:       loop:
197; CHECK-V8-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
198; CHECK-V8-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACC_NEXT_1:%.*]], [[LOOP]] ]
199; CHECK-V8-NEXT:    [[ADDR_A:%.*]] = getelementptr i32, i32* [[A:%.*]], i32 [[IV]]
200; CHECK-V8-NEXT:    [[ADDR_B:%.*]] = getelementptr i32, i32* [[B:%.*]], i32 [[IV]]
201; CHECK-V8-NEXT:    [[DATA_A:%.*]] = load i32, i32* [[ADDR_A]], align 4
202; CHECK-V8-NEXT:    [[DATA_B:%.*]] = load i32, i32* [[ADDR_B]], align 4
203; CHECK-V8-NEXT:    [[UGT:%.*]] = icmp ugt i32 [[DATA_A]], [[DATA_B]]
204; CHECK-V8-NEXT:    [[UMAX:%.*]] = select i1 [[UGT]], i32 [[DATA_A]], i32 [[DATA_B]]
205; CHECK-V8-NEXT:    [[ACC_NEXT:%.*]] = add i32 [[UMAX]], [[ACC]]
206; CHECK-V8-NEXT:    [[ADDR_C:%.*]] = getelementptr i32, i32* [[C:%.*]], i32 [[IV]]
207; CHECK-V8-NEXT:    store i32 [[UMAX]], i32* [[ADDR_C]], align 4
208; CHECK-V8-NEXT:    [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
209; CHECK-V8-NEXT:    [[ADDR_A_1:%.*]] = getelementptr i32, i32* [[A]], i32 [[COUNT]]
210; CHECK-V8-NEXT:    [[ADDR_B_1:%.*]] = getelementptr i32, i32* [[B]], i32 [[COUNT]]
211; CHECK-V8-NEXT:    [[DATA_A_1:%.*]] = load i32, i32* [[ADDR_A_1]], align 4
212; CHECK-V8-NEXT:    [[DATA_B_1:%.*]] = load i32, i32* [[ADDR_B_1]], align 4
213; CHECK-V8-NEXT:    [[UGT_1:%.*]] = icmp ugt i32 [[DATA_A_1]], [[DATA_B_1]]
214; CHECK-V8-NEXT:    [[UMAX_1:%.*]] = select i1 [[UGT_1]], i32 [[DATA_A_1]], i32 [[DATA_B_1]]
215; CHECK-V8-NEXT:    [[ACC_NEXT_1]] = add i32 [[UMAX_1]], [[ACC_NEXT]]
216; CHECK-V8-NEXT:    [[ADDR_C_1:%.*]] = getelementptr i32, i32* [[C]], i32 [[COUNT]]
217; CHECK-V8-NEXT:    store i32 [[UMAX_1]], i32* [[ADDR_C_1]], align 4
218; CHECK-V8-NEXT:    [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
219; CHECK-V8-NEXT:    [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
220; CHECK-V8-NEXT:    br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
221; CHECK-V8:       exit:
222; CHECK-V8-NEXT:    [[ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[ACC_NEXT_1]], [[LOOP]] ]
223; CHECK-V8-NEXT:    ret i32 [[ACC_NEXT_LCSSA]]
224;
225entry:
226  br label %loop
227
228loop:
229  %iv = phi i32 [ 0, %entry ], [ %count, %loop ]
230  %acc = phi i32 [ 0, %entry], [ %acc.next, %loop ]
231  %addr.a = getelementptr i32, i32* %a, i32 %iv
232  %addr.b = getelementptr i32, i32* %b, i32 %iv
233  %data.a = load i32, i32* %addr.a
234  %data.b = load i32, i32* %addr.b
235  %ugt = icmp ugt i32 %data.a, %data.b
236  %umax = select i1 %ugt, i32 %data.a, i32 %data.b
237  %acc.next = add i32 %umax, %acc
238  %addr.c = getelementptr i32, i32* %c, i32 %iv
239  store i32 %umax, i32* %addr.c
240  %count = add nuw i32 %iv, 1
241  %end = icmp ne i32 %count, 100
242  br i1 %end, label %loop, label %exit
243
244exit:
245  ret i32 %acc.next
246}
247
248define i32 @test_i32_select_minsize(i32* %a, i32* %b, i32* %c) #1 {
249; CHECK-V8-LABEL: @test_i32_select_minsize(
250; CHECK-V8-NEXT:  entry:
251; CHECK-V8-NEXT:    br label [[LOOP:%.*]]
252; CHECK-V8:       loop:
253; CHECK-V8-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT_1:%.*]], [[LOOP]] ]
254; CHECK-V8-NEXT:    [[ACC:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[ACC_NEXT_1:%.*]], [[LOOP]] ]
255; CHECK-V8-NEXT:    [[ADDR_A:%.*]] = getelementptr i32, i32* [[A:%.*]], i32 [[IV]]
256; CHECK-V8-NEXT:    [[ADDR_B:%.*]] = getelementptr i32, i32* [[B:%.*]], i32 [[IV]]
257; CHECK-V8-NEXT:    [[DATA_A:%.*]] = load i32, i32* [[ADDR_A]], align 4
258; CHECK-V8-NEXT:    [[DATA_B:%.*]] = load i32, i32* [[ADDR_B]], align 4
259; CHECK-V8-NEXT:    [[UGT:%.*]] = icmp ugt i32 [[DATA_A]], [[DATA_B]]
260; CHECK-V8-NEXT:    [[UMAX:%.*]] = select i1 [[UGT]], i32 [[DATA_A]], i32 [[DATA_B]]
261; CHECK-V8-NEXT:    [[ACC_NEXT:%.*]] = add i32 [[UMAX]], [[ACC]]
262; CHECK-V8-NEXT:    [[ADDR_C:%.*]] = getelementptr i32, i32* [[C:%.*]], i32 [[IV]]
263; CHECK-V8-NEXT:    store i32 [[UMAX]], i32* [[ADDR_C]], align 4
264; CHECK-V8-NEXT:    [[COUNT:%.*]] = add nuw nsw i32 [[IV]], 1
265; CHECK-V8-NEXT:    [[ADDR_A_1:%.*]] = getelementptr i32, i32* [[A]], i32 [[COUNT]]
266; CHECK-V8-NEXT:    [[ADDR_B_1:%.*]] = getelementptr i32, i32* [[B]], i32 [[COUNT]]
267; CHECK-V8-NEXT:    [[DATA_A_1:%.*]] = load i32, i32* [[ADDR_A_1]], align 4
268; CHECK-V8-NEXT:    [[DATA_B_1:%.*]] = load i32, i32* [[ADDR_B_1]], align 4
269; CHECK-V8-NEXT:    [[UGT_1:%.*]] = icmp ugt i32 [[DATA_A_1]], [[DATA_B_1]]
270; CHECK-V8-NEXT:    [[UMAX_1:%.*]] = select i1 [[UGT_1]], i32 [[DATA_A_1]], i32 [[DATA_B_1]]
271; CHECK-V8-NEXT:    [[ACC_NEXT_1]] = add i32 [[UMAX_1]], [[ACC_NEXT]]
272; CHECK-V8-NEXT:    [[ADDR_C_1:%.*]] = getelementptr i32, i32* [[C]], i32 [[COUNT]]
273; CHECK-V8-NEXT:    store i32 [[UMAX_1]], i32* [[ADDR_C_1]], align 4
274; CHECK-V8-NEXT:    [[COUNT_1]] = add nuw nsw i32 [[COUNT]], 1
275; CHECK-V8-NEXT:    [[END_1:%.*]] = icmp ne i32 [[COUNT_1]], 100
276; CHECK-V8-NEXT:    br i1 [[END_1]], label [[LOOP]], label [[EXIT:%.*]]
277; CHECK-V8:       exit:
278; CHECK-V8-NEXT:    [[ACC_NEXT_LCSSA:%.*]] = phi i32 [ [[ACC_NEXT_1]], [[LOOP]] ]
279; CHECK-V8-NEXT:    ret i32 [[ACC_NEXT_LCSSA]]
280;
281entry:
282  br label %loop
283
284loop:
285  %iv = phi i32 [ 0, %entry ], [ %count, %loop ]
286  %acc = phi i32 [ 0, %entry], [ %acc.next, %loop ]
287  %addr.a = getelementptr i32, i32* %a, i32 %iv
288  %addr.b = getelementptr i32, i32* %b, i32 %iv
289  %data.a = load i32, i32* %addr.a
290  %data.b = load i32, i32* %addr.b
291  %ugt = icmp ugt i32 %data.a, %data.b
292  %umax = select i1 %ugt, i32 %data.a, i32 %data.b
293  %acc.next = add i32 %umax, %acc
294  %addr.c = getelementptr i32, i32* %c, i32 %iv
295  store i32 %umax, i32* %addr.c
296  %count = add nuw i32 %iv, 1
297  %end = icmp ne i32 %count, 100
298  br i1 %end, label %loop, label %exit
299
300exit:
301  ret i32 %acc.next
302}
303
304define i64 @test_i64_select_optsize(i64* %a, i64* %b, i64* %c) #0 {
305; CHECK-V8-LABEL: @test_i64_select_optsize(
306; CHECK-V8-NEXT:  entry:
307; CHECK-V8-NEXT:    br label [[LOOP:%.*]]
308; CHECK-V8:       loop:
309; CHECK-V8-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT:%.*]], [[LOOP]] ]
310; CHECK-V8-NEXT:    [[ACC:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[ACC_NEXT:%.*]], [[LOOP]] ]
311; CHECK-V8-NEXT:    [[ADDR_A:%.*]] = getelementptr i64, i64* [[A:%.*]], i32 [[IV]]
312; CHECK-V8-NEXT:    [[ADDR_B:%.*]] = getelementptr i64, i64* [[B:%.*]], i32 [[IV]]
313; CHECK-V8-NEXT:    [[DATA_A:%.*]] = load i64, i64* [[ADDR_A]], align 4
314; CHECK-V8-NEXT:    [[DATA_B:%.*]] = load i64, i64* [[ADDR_B]], align 4
315; CHECK-V8-NEXT:    [[UGT:%.*]] = icmp ugt i64 [[DATA_A]], [[DATA_B]]
316; CHECK-V8-NEXT:    [[UMAX:%.*]] = select i1 [[UGT]], i64 [[DATA_A]], i64 [[DATA_B]]
317; CHECK-V8-NEXT:    [[ACC_NEXT]] = add i64 [[UMAX]], [[ACC]]
318; CHECK-V8-NEXT:    [[ADDR_C:%.*]] = getelementptr i64, i64* [[C:%.*]], i32 [[IV]]
319; CHECK-V8-NEXT:    store i64 [[UMAX]], i64* [[ADDR_C]], align 4
320; CHECK-V8-NEXT:    [[COUNT]] = add nuw i32 [[IV]], 1
321; CHECK-V8-NEXT:    [[END:%.*]] = icmp ne i32 [[COUNT]], 100
322; CHECK-V8-NEXT:    br i1 [[END]], label [[LOOP]], label [[EXIT:%.*]]
323; CHECK-V8:       exit:
324; CHECK-V8-NEXT:    [[ACC_NEXT_LCSSA:%.*]] = phi i64 [ [[ACC_NEXT]], [[LOOP]] ]
325; CHECK-V8-NEXT:    ret i64 [[ACC_NEXT_LCSSA]]
326;
327entry:
328  br label %loop
329
330loop:
331  %iv = phi i32 [ 0, %entry ], [ %count, %loop ]
332  %acc = phi i64 [ 0, %entry], [ %acc.next, %loop ]
333  %addr.a = getelementptr i64, i64* %a, i32 %iv
334  %addr.b = getelementptr i64, i64* %b, i32 %iv
335  %data.a = load i64, i64* %addr.a
336  %data.b = load i64, i64* %addr.b
337  %ugt = icmp ugt i64 %data.a, %data.b
338  %umax = select i1 %ugt, i64 %data.a, i64 %data.b
339  %acc.next = add i64 %umax, %acc
340  %addr.c = getelementptr i64, i64* %c, i32 %iv
341  store i64 %umax, i64* %addr.c
342  %count = add nuw i32 %iv, 1
343  %end = icmp ne i32 %count, 100
344  br i1 %end, label %loop, label %exit
345
346exit:
347  ret i64 %acc.next
348}
349
350define i64 @test_i64_select_minsize(i64* %a, i64* %b, i64* %c) #1 {
351; CHECK-V8-LABEL: @test_i64_select_minsize(
352; CHECK-V8-NEXT:  entry:
353; CHECK-V8-NEXT:    br label [[LOOP:%.*]]
354; CHECK-V8:       loop:
355; CHECK-V8-NEXT:    [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[COUNT:%.*]], [[LOOP]] ]
356; CHECK-V8-NEXT:    [[ACC:%.*]] = phi i64 [ 0, [[ENTRY]] ], [ [[ACC_NEXT:%.*]], [[LOOP]] ]
357; CHECK-V8-NEXT:    [[ADDR_A:%.*]] = getelementptr i64, i64* [[A:%.*]], i32 [[IV]]
358; CHECK-V8-NEXT:    [[ADDR_B:%.*]] = getelementptr i64, i64* [[B:%.*]], i32 [[IV]]
359; CHECK-V8-NEXT:    [[DATA_A:%.*]] = load i64, i64* [[ADDR_A]], align 4
360; CHECK-V8-NEXT:    [[DATA_B:%.*]] = load i64, i64* [[ADDR_B]], align 4
361; CHECK-V8-NEXT:    [[UGT:%.*]] = icmp ugt i64 [[DATA_A]], [[DATA_B]]
362; CHECK-V8-NEXT:    [[UMAX:%.*]] = select i1 [[UGT]], i64 [[DATA_A]], i64 [[DATA_B]]
363; CHECK-V8-NEXT:    [[ACC_NEXT]] = add i64 [[UMAX]], [[ACC]]
364; CHECK-V8-NEXT:    [[ADDR_C:%.*]] = getelementptr i64, i64* [[C:%.*]], i32 [[IV]]
365; CHECK-V8-NEXT:    store i64 [[UMAX]], i64* [[ADDR_C]], align 4
366; CHECK-V8-NEXT:    [[COUNT]] = add nuw i32 [[IV]], 1
367; CHECK-V8-NEXT:    [[END:%.*]] = icmp ne i32 [[COUNT]], 100
368; CHECK-V8-NEXT:    br i1 [[END]], label [[LOOP]], label [[EXIT:%.*]]
369; CHECK-V8:       exit:
370; CHECK-V8-NEXT:    [[ACC_NEXT_LCSSA:%.*]] = phi i64 [ [[ACC_NEXT]], [[LOOP]] ]
371; CHECK-V8-NEXT:    ret i64 [[ACC_NEXT_LCSSA]]
372;
373entry:
374  br label %loop
375
376loop:
377  %iv = phi i32 [ 0, %entry ], [ %count, %loop ]
378  %acc = phi i64 [ 0, %entry], [ %acc.next, %loop ]
379  %addr.a = getelementptr i64, i64* %a, i32 %iv
380  %addr.b = getelementptr i64, i64* %b, i32 %iv
381  %data.a = load i64, i64* %addr.a
382  %data.b = load i64, i64* %addr.b
383  %ugt = icmp ugt i64 %data.a, %data.b
384  %umax = select i1 %ugt, i64 %data.a, i64 %data.b
385  %acc.next = add i64 %umax, %acc
386  %addr.c = getelementptr i64, i64* %c, i32 %iv
387  store i64 %umax, i64* %addr.c
388  %count = add nuw i32 %iv, 1
389  %end = icmp ne i32 %count, 100
390  br i1 %end, label %loop, label %exit
391
392exit:
393  ret i64 %acc.next
394}
395
396attributes #0 = { optsize }
397attributes #1 = { minsize optsize }
398