1 ; RUN: opt -mtriple=thumbv8.1m.main-arm-none-eabi -mattr=+fp-armv8 -hardware-loops -disable-arm-loloops=false %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP
2 ; RUN: opt -mtriple=thumbv8.1m.main-arm-none-eabi -mattr=+soft-float -hardware-loops -disable-arm-loloops=false %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SOFT
4 ; CHECK-LABEL: test_fptosi
5 ; CHECK-SOFT-NOT: call void @llvm.set.loop.iterations
8 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ugt i32 %n, 1
9 ; CHECK-FP: [[COUNT:%[^ ]+]] = select i1 [[CMP]], i32 %n, i32 1
11 ; CHECK: while.body.lr.ph:
12 ; CHECK-FP: call void @llvm.set.loop.iterations.i32(i32 [[COUNT]])
13 ; CHECK-FP-NEXT: br label %while.body
15 ; CHECK-FP: [[REM:%[^ ]+]] = phi i32 [ [[COUNT]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %if.end4 ]
16 ; CHECK-FP: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 [[REM]], i32 1)
17 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0
18 ; CHECK-FP: br i1 [[CMP]], label %while.body, label %cleanup.loopexit
20 define void @test_fptosi(i32 %n, i32** %g, double** %d) {
22 %n.off = add i32 %n, -1
23 %0 = icmp ult i32 %n.off, 500
24 br i1 %0, label %while.body.lr.ph, label %cleanup
27 %1 = load double*, double** %d, align 4
28 %2 = load i32*, i32** %g, align 4
32 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
33 %rem = urem i32 %i.012, 10
34 %tobool = icmp eq i32 %rem, 0
35 br i1 %tobool, label %if.end4, label %if.then2
38 %arrayidx = getelementptr inbounds double, double* %1, i32 %i.012
39 %3 = load double, double* %arrayidx, align 8
40 %conv = fptosi double %3 to i32
41 %arrayidx3 = getelementptr inbounds i32, i32* %2, i32 %i.012
42 store i32 %conv, i32* %arrayidx3, align 4
46 %inc = add nuw i32 %i.012, 1
47 %cmp1 = icmp ult i32 %inc, %n
48 br i1 %cmp1, label %while.body, label %cleanup.loopexit
57 ; CHECK-LABEL: test_fptoui
59 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ugt i32 %n, 1
60 ; CHECK-FP: [[COUNT:%[^ ]+]] = select i1 [[CMP]], i32 %n, i32 1
61 ; CHECK-FP: while.body.lr.ph:
62 ; CHECK-FP: call void @llvm.set.loop.iterations.i32(i32 [[COUNT]])
63 ; CHECK-FP-NEXT: br label %while.body
65 ; CHECK-FP: [[REM:%[^ ]+]] = phi i32 [ [[COUNT]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %if.end4 ]
66 ; CHECK-FP: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 [[REM]], i32 1)
67 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0
68 ; CHECK-FP: br i1 [[CMP]], label %while.body, label %cleanup.loopexit
70 ; CHECK-SOFT-NOT: call void @llvm.set.loop.iterations
72 define void @test_fptoui(i32 %n, i32** %g, double** %d) {
74 %n.off = add i32 %n, -1
75 %0 = icmp ult i32 %n.off, 500
76 br i1 %0, label %while.body.lr.ph, label %cleanup
79 %1 = load double*, double** %d, align 4
80 %2 = load i32*, i32** %g, align 4
84 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
85 %rem = urem i32 %i.012, 10
86 %tobool = icmp eq i32 %rem, 0
87 br i1 %tobool, label %if.end4, label %if.then2
90 %arrayidx = getelementptr inbounds double, double* %1, i32 %i.012
91 %3 = load double, double* %arrayidx, align 8
92 %conv = fptoui double %3 to i32
93 %arrayidx3 = getelementptr inbounds i32, i32* %2, i32 %i.012
94 store i32 %conv, i32* %arrayidx3, align 4
98 %inc = add nuw i32 %i.012, 1
99 %cmp1 = icmp ult i32 %inc, %n
100 br i1 %cmp1, label %while.body, label %cleanup.loopexit
109 ; CHECK-LABEL: load_store_float
111 ; CHECK: [[CMP:%[^ ]+]] = icmp ugt i32 %n, 1
112 ; CHECK: [[COUNT:%[^ ]+]] = select i1 [[CMP]], i32 %n, i32 1
113 ; CHECK: while.body.lr.ph:
114 ; CHECK: call void @llvm.set.loop.iterations.i32(i32 [[COUNT]])
115 ; CHECK-NEXT: br label %while.body
117 ; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[COUNT]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %if.end4 ]
118 ; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 [[REM]], i32 1)
119 ; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0
120 ; CHECK: br i1 [[CMP]], label %while.body, label %cleanup.loopexit
122 define void @load_store_float(i32 %n, double** %d, double** %g) {
124 %n.off = add i32 %n, -1
125 %0 = icmp ult i32 %n.off, 500
126 br i1 %0, label %while.body.lr.ph, label %cleanup
129 %1 = load double*, double** %d, align 4
130 %2 = load double*, double** %g, align 4
134 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
135 %rem = urem i32 %i.012, 10
136 %tobool = icmp eq i32 %rem, 0
137 br i1 %tobool, label %if.end4, label %if.then2
140 %arrayidx = getelementptr inbounds double, double* %1, i32 %i.012
141 %3 = load double, double* %arrayidx, align 8
142 %arrayidx3 = getelementptr inbounds double, double* %2, i32 %i.012
143 store double %3, double* %arrayidx3, align 8
147 %inc = add nuw i32 %i.012, 1
148 %cmp1 = icmp ult i32 %inc, %n
149 br i1 %cmp1, label %while.body, label %cleanup.loopexit
158 ; CHECK-LABEL: fp_add
159 ; CHECK-SOFT-NOT: call void @llvm.set.loop.iterations
161 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ugt i32 %n, 1
162 ; CHECK-FP: [[COUNT:%[^ ]+]] = select i1 [[CMP]], i32 %n, i32 1
163 ; CHECK: while.body.lr.ph:
164 ; CHECK-FP: call void @llvm.set.loop.iterations.i32(i32 [[COUNT]])
165 ; CHECK: br label %while.body
167 ; CHECK-SOFT-NOT: call i32 @llvm.loop.decrement
169 ; CHECK-FP: [[REM:%[^ ]+]] = phi i32 [ [[COUNT]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %if.end4 ]
170 ; CHECK-FP: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32.i32.i32(i32 [[REM]], i32 1)
171 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0
172 ; CHECK-FP: br i1 [[CMP]], label %while.body, label %cleanup.loopexit
174 define void @fp_add(i32 %n, float** %d, float** %g) {
176 %n.off = add i32 %n, -1
177 %0 = icmp ult i32 %n.off, 500
178 br i1 %0, label %while.body.lr.ph, label %cleanup
181 %1 = load float*, float** %d, align 4
182 %2 = load float*, float** %g, align 4
186 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
187 %rem = urem i32 %i.012, 10
188 %tobool = icmp eq i32 %rem, 0
189 br i1 %tobool, label %if.end4, label %if.then2
192 %arrayidx = getelementptr inbounds float, float* %1, i32 %i.012
193 %3 = load float, float* %arrayidx, align 4
194 %arrayidx3 = getelementptr inbounds float, float* %2, i32 %i.012
195 %4 = load float, float* %arrayidx3, align 4
196 %add = fadd float %3, %4
197 store float %add, float* %arrayidx3, align 4
201 %inc = add nuw i32 %i.012, 1
202 %cmp1 = icmp ult i32 %inc, %n
203 br i1 %cmp1, label %while.body, label %cleanup.loopexit