Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / HardwareLoops / ARM / fp-emulation.ll
blob01adc37ba53185854ad226ba2e9780b51a592d9c
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
5 define 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
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
71 entry:
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
76 while.body.lr.ph:
77   %1 = load ptr, ptr %d, align 4
78   %2 = load ptr, ptr %g, align 4
79   br label %while.body
81 while.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
87 if.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
95 if.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
100 cleanup.loopexit:
101   br label %cleanup
103 cleanup:
104   ret void
107 define 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
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
173 entry:
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
178 while.body.lr.ph:
179   %1 = load ptr, ptr %d, align 4
180   %2 = load ptr, ptr %g, align 4
181   br label %while.body
183 while.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
189 if.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
197 if.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
202 cleanup.loopexit:
203   br label %cleanup
205 cleanup:
206   ret void
209 define 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
243 entry:
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
248 while.body.lr.ph:
249   %1 = load ptr, ptr %d, align 4
250   %2 = load ptr, ptr %g, align 4
251   br label %while.body
253 while.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
259 if.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
266 if.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
271 cleanup.loopexit:
272   br label %cleanup
274 cleanup:
275   ret void
278 define 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
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
346 entry:
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
351 while.body.lr.ph:
352   %1 = load ptr, ptr %d, align 4
353   %2 = load ptr, ptr %g, align 4
354   br label %while.body
356 while.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
362 if.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
371 if.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
376 cleanup.loopexit:
377   br label %cleanup
379 cleanup:
380   ret void