xref: /llvm-project/llvm/test/Transforms/HardwareLoops/ARM/fp-emulation.ll (revision a7f35d54eef95e308ed13af5f46dbfc6c559cb9b)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
2; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+fp-armv8 -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefixes=CHECK,CHECK-FP
3; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+soft-float -passes=hardware-loops %s -S -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SOFT
4
5define void @test_fptosi(i32 %n, ptr %g, ptr %d) {
6; CHECK-FP-LABEL: define void @test_fptosi(
7; CHECK-FP-SAME: i32 [[N:%.*]], ptr [[G:%.*]], ptr [[D:%.*]]) #[[ATTR0:[0-9]+]] {
8; CHECK-FP-NEXT:  entry:
9; CHECK-FP-NEXT:    [[N_OFF:%.*]] = add i32 [[N]], -1
10; CHECK-FP-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500
11; CHECK-FP-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]]
12; CHECK-FP:       while.body.lr.ph:
13; CHECK-FP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[D]], align 4
14; CHECK-FP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[G]], align 4
15; CHECK-FP-NEXT:    [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
16; CHECK-FP-NEXT:    br label [[WHILE_BODY:%.*]]
17; CHECK-FP:       while.body:
18; CHECK-FP-NEXT:    [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ]
19; CHECK-FP-NEXT:    [[TMP4:%.*]] = phi i32 [ [[TMP3]], [[WHILE_BODY_LR_PH]] ], [ [[TMP6:%.*]], [[IF_END4]] ]
20; CHECK-FP-NEXT:    [[REM:%.*]] = urem i32 [[I_012]], 10
21; CHECK-FP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0
22; CHECK-FP-NEXT:    br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]]
23; CHECK-FP:       if.then2:
24; CHECK-FP-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]]
25; CHECK-FP-NEXT:    [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8
26; CHECK-FP-NEXT:    [[CONV:%.*]] = fptosi double [[TMP5]] to i32
27; CHECK-FP-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 [[I_012]]
28; CHECK-FP-NEXT:    store i32 [[CONV]], ptr [[ARRAYIDX3]], align 4
29; CHECK-FP-NEXT:    br label [[IF_END4]]
30; CHECK-FP:       if.end4:
31; CHECK-FP-NEXT:    [[INC]] = add nuw i32 [[I_012]], 1
32; CHECK-FP-NEXT:    [[TMP6]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP4]], i32 1)
33; CHECK-FP-NEXT:    [[TMP7:%.*]] = icmp ne i32 [[TMP6]], 0
34; CHECK-FP-NEXT:    br i1 [[TMP7]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]]
35; CHECK-FP:       cleanup.loopexit:
36; CHECK-FP-NEXT:    br label [[CLEANUP]]
37; CHECK-FP:       cleanup:
38; CHECK-FP-NEXT:    ret void
39;
40; CHECK-SOFT-LABEL: define void @test_fptosi(
41; CHECK-SOFT-SAME: i32 [[N:%.*]], ptr [[G:%.*]], ptr [[D:%.*]]) #[[ATTR0:[0-9]+]] {
42; CHECK-SOFT-NEXT:  entry:
43; CHECK-SOFT-NEXT:    [[N_OFF:%.*]] = add i32 [[N]], -1
44; CHECK-SOFT-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500
45; CHECK-SOFT-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]]
46; CHECK-SOFT:       while.body.lr.ph:
47; CHECK-SOFT-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[D]], align 4
48; CHECK-SOFT-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[G]], align 4
49; CHECK-SOFT-NEXT:    br label [[WHILE_BODY:%.*]]
50; CHECK-SOFT:       while.body:
51; CHECK-SOFT-NEXT:    [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ]
52; CHECK-SOFT-NEXT:    [[REM:%.*]] = urem i32 [[I_012]], 10
53; CHECK-SOFT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0
54; CHECK-SOFT-NEXT:    br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]]
55; CHECK-SOFT:       if.then2:
56; CHECK-SOFT-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]]
57; CHECK-SOFT-NEXT:    [[TMP3:%.*]] = load double, ptr [[ARRAYIDX]], align 8
58; CHECK-SOFT-NEXT:    [[CONV:%.*]] = fptosi double [[TMP3]] to i32
59; CHECK-SOFT-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 [[I_012]]
60; CHECK-SOFT-NEXT:    store i32 [[CONV]], ptr [[ARRAYIDX3]], align 4
61; CHECK-SOFT-NEXT:    br label [[IF_END4]]
62; CHECK-SOFT:       if.end4:
63; CHECK-SOFT-NEXT:    [[INC]] = add nuw i32 [[I_012]], 1
64; CHECK-SOFT-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[INC]], [[N]]
65; CHECK-SOFT-NEXT:    br i1 [[CMP1]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]]
66; CHECK-SOFT:       cleanup.loopexit:
67; CHECK-SOFT-NEXT:    br label [[CLEANUP]]
68; CHECK-SOFT:       cleanup:
69; CHECK-SOFT-NEXT:    ret void
70;
71entry:
72  %n.off = add i32 %n, -1
73  %0 = icmp ult i32 %n.off, 500
74  br i1 %0, label %while.body.lr.ph, label %cleanup
75
76while.body.lr.ph:
77  %1 = load ptr, ptr %d, align 4
78  %2 = load ptr, ptr %g, align 4
79  br label %while.body
80
81while.body:
82  %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
83  %rem = urem i32 %i.012, 10
84  %tobool = icmp eq i32 %rem, 0
85  br i1 %tobool, label %if.end4, label %if.then2
86
87if.then2:
88  %arrayidx = getelementptr inbounds double, ptr %1, i32 %i.012
89  %3 = load double, ptr %arrayidx, align 8
90  %conv = fptosi double %3 to i32
91  %arrayidx3 = getelementptr inbounds i32, ptr %2, i32 %i.012
92  store i32 %conv, ptr %arrayidx3, align 4
93  br label %if.end4
94
95if.end4:
96  %inc = add nuw i32 %i.012, 1
97  %cmp1 = icmp ult i32 %inc, %n
98  br i1 %cmp1, label %while.body, label %cleanup.loopexit
99
100cleanup.loopexit:
101  br label %cleanup
102
103cleanup:
104  ret void
105}
106
107define void @test_fptoui(i32 %n, ptr %g, ptr %d) {
108; CHECK-FP-LABEL: define void @test_fptoui(
109; CHECK-FP-SAME: i32 [[N:%.*]], ptr [[G:%.*]], ptr [[D:%.*]]) #[[ATTR0]] {
110; CHECK-FP-NEXT:  entry:
111; CHECK-FP-NEXT:    [[N_OFF:%.*]] = add i32 [[N]], -1
112; CHECK-FP-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500
113; CHECK-FP-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]]
114; CHECK-FP:       while.body.lr.ph:
115; CHECK-FP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[D]], align 4
116; CHECK-FP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[G]], align 4
117; CHECK-FP-NEXT:    [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
118; CHECK-FP-NEXT:    br label [[WHILE_BODY:%.*]]
119; CHECK-FP:       while.body:
120; CHECK-FP-NEXT:    [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ]
121; CHECK-FP-NEXT:    [[TMP4:%.*]] = phi i32 [ [[TMP3]], [[WHILE_BODY_LR_PH]] ], [ [[TMP6:%.*]], [[IF_END4]] ]
122; CHECK-FP-NEXT:    [[REM:%.*]] = urem i32 [[I_012]], 10
123; CHECK-FP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0
124; CHECK-FP-NEXT:    br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]]
125; CHECK-FP:       if.then2:
126; CHECK-FP-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]]
127; CHECK-FP-NEXT:    [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8
128; CHECK-FP-NEXT:    [[CONV:%.*]] = fptoui double [[TMP5]] to i32
129; CHECK-FP-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 [[I_012]]
130; CHECK-FP-NEXT:    store i32 [[CONV]], ptr [[ARRAYIDX3]], align 4
131; CHECK-FP-NEXT:    br label [[IF_END4]]
132; CHECK-FP:       if.end4:
133; CHECK-FP-NEXT:    [[INC]] = add nuw i32 [[I_012]], 1
134; CHECK-FP-NEXT:    [[TMP6]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP4]], i32 1)
135; CHECK-FP-NEXT:    [[TMP7:%.*]] = icmp ne i32 [[TMP6]], 0
136; CHECK-FP-NEXT:    br i1 [[TMP7]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]]
137; CHECK-FP:       cleanup.loopexit:
138; CHECK-FP-NEXT:    br label [[CLEANUP]]
139; CHECK-FP:       cleanup:
140; CHECK-FP-NEXT:    ret void
141;
142; CHECK-SOFT-LABEL: define void @test_fptoui(
143; CHECK-SOFT-SAME: i32 [[N:%.*]], ptr [[G:%.*]], ptr [[D:%.*]]) #[[ATTR0]] {
144; CHECK-SOFT-NEXT:  entry:
145; CHECK-SOFT-NEXT:    [[N_OFF:%.*]] = add i32 [[N]], -1
146; CHECK-SOFT-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500
147; CHECK-SOFT-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]]
148; CHECK-SOFT:       while.body.lr.ph:
149; CHECK-SOFT-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[D]], align 4
150; CHECK-SOFT-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[G]], align 4
151; CHECK-SOFT-NEXT:    br label [[WHILE_BODY:%.*]]
152; CHECK-SOFT:       while.body:
153; CHECK-SOFT-NEXT:    [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ]
154; CHECK-SOFT-NEXT:    [[REM:%.*]] = urem i32 [[I_012]], 10
155; CHECK-SOFT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0
156; CHECK-SOFT-NEXT:    br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]]
157; CHECK-SOFT:       if.then2:
158; CHECK-SOFT-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]]
159; CHECK-SOFT-NEXT:    [[TMP3:%.*]] = load double, ptr [[ARRAYIDX]], align 8
160; CHECK-SOFT-NEXT:    [[CONV:%.*]] = fptoui double [[TMP3]] to i32
161; CHECK-SOFT-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 [[I_012]]
162; CHECK-SOFT-NEXT:    store i32 [[CONV]], ptr [[ARRAYIDX3]], align 4
163; CHECK-SOFT-NEXT:    br label [[IF_END4]]
164; CHECK-SOFT:       if.end4:
165; CHECK-SOFT-NEXT:    [[INC]] = add nuw i32 [[I_012]], 1
166; CHECK-SOFT-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[INC]], [[N]]
167; CHECK-SOFT-NEXT:    br i1 [[CMP1]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]]
168; CHECK-SOFT:       cleanup.loopexit:
169; CHECK-SOFT-NEXT:    br label [[CLEANUP]]
170; CHECK-SOFT:       cleanup:
171; CHECK-SOFT-NEXT:    ret void
172;
173entry:
174  %n.off = add i32 %n, -1
175  %0 = icmp ult i32 %n.off, 500
176  br i1 %0, label %while.body.lr.ph, label %cleanup
177
178while.body.lr.ph:
179  %1 = load ptr, ptr %d, align 4
180  %2 = load ptr, ptr %g, align 4
181  br label %while.body
182
183while.body:
184  %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
185  %rem = urem i32 %i.012, 10
186  %tobool = icmp eq i32 %rem, 0
187  br i1 %tobool, label %if.end4, label %if.then2
188
189if.then2:
190  %arrayidx = getelementptr inbounds double, ptr %1, i32 %i.012
191  %3 = load double, ptr %arrayidx, align 8
192  %conv = fptoui double %3 to i32
193  %arrayidx3 = getelementptr inbounds i32, ptr %2, i32 %i.012
194  store i32 %conv, ptr %arrayidx3, align 4
195  br label %if.end4
196
197if.end4:
198  %inc = add nuw i32 %i.012, 1
199  %cmp1 = icmp ult i32 %inc, %n
200  br i1 %cmp1, label %while.body, label %cleanup.loopexit
201
202cleanup.loopexit:
203  br label %cleanup
204
205cleanup:
206  ret void
207}
208
209define void @load_store_float(i32 %n, ptr %d, ptr %g) {
210; CHECK-LABEL: define void @load_store_float(
211; CHECK-SAME: i32 [[N:%.*]], ptr [[D:%.*]], ptr [[G:%.*]]) #[[ATTR0:[0-9]+]] {
212; CHECK-NEXT:  entry:
213; CHECK-NEXT:    [[N_OFF:%.*]] = add i32 [[N]], -1
214; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500
215; CHECK-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]]
216; CHECK:       while.body.lr.ph:
217; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[D]], align 4
218; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[G]], align 4
219; CHECK-NEXT:    [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
220; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
221; CHECK:       while.body:
222; CHECK-NEXT:    [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ]
223; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ [[TMP3]], [[WHILE_BODY_LR_PH]] ], [ [[TMP6:%.*]], [[IF_END4]] ]
224; CHECK-NEXT:    [[REM:%.*]] = urem i32 [[I_012]], 10
225; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0
226; CHECK-NEXT:    br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]]
227; CHECK:       if.then2:
228; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[TMP1]], i32 [[I_012]]
229; CHECK-NEXT:    [[TMP5:%.*]] = load double, ptr [[ARRAYIDX]], align 8
230; CHECK-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds double, ptr [[TMP2]], i32 [[I_012]]
231; CHECK-NEXT:    store double [[TMP5]], ptr [[ARRAYIDX3]], align 8
232; CHECK-NEXT:    br label [[IF_END4]]
233; CHECK:       if.end4:
234; CHECK-NEXT:    [[INC]] = add nuw i32 [[I_012]], 1
235; CHECK-NEXT:    [[TMP6]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP4]], i32 1)
236; CHECK-NEXT:    [[TMP7:%.*]] = icmp ne i32 [[TMP6]], 0
237; CHECK-NEXT:    br i1 [[TMP7]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]]
238; CHECK:       cleanup.loopexit:
239; CHECK-NEXT:    br label [[CLEANUP]]
240; CHECK:       cleanup:
241; CHECK-NEXT:    ret void
242;
243entry:
244  %n.off = add i32 %n, -1
245  %0 = icmp ult i32 %n.off, 500
246  br i1 %0, label %while.body.lr.ph, label %cleanup
247
248while.body.lr.ph:
249  %1 = load ptr, ptr %d, align 4
250  %2 = load ptr, ptr %g, align 4
251  br label %while.body
252
253while.body:
254  %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
255  %rem = urem i32 %i.012, 10
256  %tobool = icmp eq i32 %rem, 0
257  br i1 %tobool, label %if.end4, label %if.then2
258
259if.then2:
260  %arrayidx = getelementptr inbounds double, ptr %1, i32 %i.012
261  %3 = load double, ptr %arrayidx, align 8
262  %arrayidx3 = getelementptr inbounds double, ptr %2, i32 %i.012
263  store double %3, ptr %arrayidx3, align 8
264  br label %if.end4
265
266if.end4:
267  %inc = add nuw i32 %i.012, 1
268  %cmp1 = icmp ult i32 %inc, %n
269  br i1 %cmp1, label %while.body, label %cleanup.loopexit
270
271cleanup.loopexit:
272  br label %cleanup
273
274cleanup:
275  ret void
276}
277
278define void @fp_add(i32 %n, ptr %d, ptr %g) {
279; CHECK-FP-LABEL: define void @fp_add(
280; CHECK-FP-SAME: i32 [[N:%.*]], ptr [[D:%.*]], ptr [[G:%.*]]) #[[ATTR0]] {
281; CHECK-FP-NEXT:  entry:
282; CHECK-FP-NEXT:    [[N_OFF:%.*]] = add i32 [[N]], -1
283; CHECK-FP-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500
284; CHECK-FP-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]]
285; CHECK-FP:       while.body.lr.ph:
286; CHECK-FP-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[D]], align 4
287; CHECK-FP-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[G]], align 4
288; CHECK-FP-NEXT:    [[TMP3:%.*]] = call i32 @llvm.start.loop.iterations.i32(i32 [[N]])
289; CHECK-FP-NEXT:    br label [[WHILE_BODY:%.*]]
290; CHECK-FP:       while.body:
291; CHECK-FP-NEXT:    [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ]
292; CHECK-FP-NEXT:    [[TMP4:%.*]] = phi i32 [ [[TMP3]], [[WHILE_BODY_LR_PH]] ], [ [[TMP7:%.*]], [[IF_END4]] ]
293; CHECK-FP-NEXT:    [[REM:%.*]] = urem i32 [[I_012]], 10
294; CHECK-FP-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0
295; CHECK-FP-NEXT:    br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]]
296; CHECK-FP:       if.then2:
297; CHECK-FP-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 [[I_012]]
298; CHECK-FP-NEXT:    [[TMP5:%.*]] = load float, ptr [[ARRAYIDX]], align 4
299; CHECK-FP-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i32 [[I_012]]
300; CHECK-FP-NEXT:    [[TMP6:%.*]] = load float, ptr [[ARRAYIDX3]], align 4
301; CHECK-FP-NEXT:    [[ADD:%.*]] = fadd float [[TMP5]], [[TMP6]]
302; CHECK-FP-NEXT:    store float [[ADD]], ptr [[ARRAYIDX3]], align 4
303; CHECK-FP-NEXT:    br label [[IF_END4]]
304; CHECK-FP:       if.end4:
305; CHECK-FP-NEXT:    [[INC]] = add nuw i32 [[I_012]], 1
306; CHECK-FP-NEXT:    [[TMP7]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[TMP4]], i32 1)
307; CHECK-FP-NEXT:    [[TMP8:%.*]] = icmp ne i32 [[TMP7]], 0
308; CHECK-FP-NEXT:    br i1 [[TMP8]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]]
309; CHECK-FP:       cleanup.loopexit:
310; CHECK-FP-NEXT:    br label [[CLEANUP]]
311; CHECK-FP:       cleanup:
312; CHECK-FP-NEXT:    ret void
313;
314; CHECK-SOFT-LABEL: define void @fp_add(
315; CHECK-SOFT-SAME: i32 [[N:%.*]], ptr [[D:%.*]], ptr [[G:%.*]]) #[[ATTR0]] {
316; CHECK-SOFT-NEXT:  entry:
317; CHECK-SOFT-NEXT:    [[N_OFF:%.*]] = add i32 [[N]], -1
318; CHECK-SOFT-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[N_OFF]], 500
319; CHECK-SOFT-NEXT:    br i1 [[TMP0]], label [[WHILE_BODY_LR_PH:%.*]], label [[CLEANUP:%.*]]
320; CHECK-SOFT:       while.body.lr.ph:
321; CHECK-SOFT-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[D]], align 4
322; CHECK-SOFT-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[G]], align 4
323; CHECK-SOFT-NEXT:    br label [[WHILE_BODY:%.*]]
324; CHECK-SOFT:       while.body:
325; CHECK-SOFT-NEXT:    [[I_012:%.*]] = phi i32 [ 0, [[WHILE_BODY_LR_PH]] ], [ [[INC:%.*]], [[IF_END4:%.*]] ]
326; CHECK-SOFT-NEXT:    [[REM:%.*]] = urem i32 [[I_012]], 10
327; CHECK-SOFT-NEXT:    [[TOBOOL:%.*]] = icmp eq i32 [[REM]], 0
328; CHECK-SOFT-NEXT:    br i1 [[TOBOOL]], label [[IF_END4]], label [[IF_THEN2:%.*]]
329; CHECK-SOFT:       if.then2:
330; CHECK-SOFT-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[TMP1]], i32 [[I_012]]
331; CHECK-SOFT-NEXT:    [[TMP3:%.*]] = load float, ptr [[ARRAYIDX]], align 4
332; CHECK-SOFT-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i32 [[I_012]]
333; CHECK-SOFT-NEXT:    [[TMP4:%.*]] = load float, ptr [[ARRAYIDX3]], align 4
334; CHECK-SOFT-NEXT:    [[ADD:%.*]] = fadd float [[TMP3]], [[TMP4]]
335; CHECK-SOFT-NEXT:    store float [[ADD]], ptr [[ARRAYIDX3]], align 4
336; CHECK-SOFT-NEXT:    br label [[IF_END4]]
337; CHECK-SOFT:       if.end4:
338; CHECK-SOFT-NEXT:    [[INC]] = add nuw i32 [[I_012]], 1
339; CHECK-SOFT-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[INC]], [[N]]
340; CHECK-SOFT-NEXT:    br i1 [[CMP1]], label [[WHILE_BODY]], label [[CLEANUP_LOOPEXIT:%.*]]
341; CHECK-SOFT:       cleanup.loopexit:
342; CHECK-SOFT-NEXT:    br label [[CLEANUP]]
343; CHECK-SOFT:       cleanup:
344; CHECK-SOFT-NEXT:    ret void
345;
346entry:
347  %n.off = add i32 %n, -1
348  %0 = icmp ult i32 %n.off, 500
349  br i1 %0, label %while.body.lr.ph, label %cleanup
350
351while.body.lr.ph:
352  %1 = load ptr, ptr %d, align 4
353  %2 = load ptr, ptr %g, align 4
354  br label %while.body
355
356while.body:
357  %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
358  %rem = urem i32 %i.012, 10
359  %tobool = icmp eq i32 %rem, 0
360  br i1 %tobool, label %if.end4, label %if.then2
361
362if.then2:
363  %arrayidx = getelementptr inbounds float, ptr %1, i32 %i.012
364  %3 = load float, ptr %arrayidx, align 4
365  %arrayidx3 = getelementptr inbounds float, ptr %2, i32 %i.012
366  %4 = load float, ptr %arrayidx3, align 4
367  %add = fadd float %3, %4
368  store float %add, ptr %arrayidx3, align 4
369  br label %if.end4
370
371if.end4:
372  %inc = add nuw i32 %i.012, 1
373  %cmp1 = icmp ult i32 %inc, %n
374  br i1 %cmp1, label %while.body, label %cleanup.loopexit
375
376cleanup.loopexit:
377  br label %cleanup
378
379cleanup:
380  ret void
381}
382