1 ; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+fp-armv8 -hardware-loops %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-FP
2 ; RUN: opt -mtriple=thumbv8.1m.main-none-none-eabi -mattr=+soft-float -hardware-loops %s -S -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SOFT
4 ; CHECK-LABEL: test_fptosi
5 ; CHECK-SOFT-NOT: call i32 @llvm.start.loop.iterations
8 ; CHECK-FP: [[COUNT:%[^ ]+]] = call i32 @llvm.umax.i32(i32 %n, i32 1)
10 ; CHECK: while.body.lr.ph:
11 ; CHECK-FP: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 [[COUNT]])
12 ; CHECK-FP-NEXT: br label %while.body
14 ; CHECK-FP: [[REM:%[^ ]+]] = phi i32 [ [[START]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %if.end4 ]
15 ; CHECK-FP: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1)
16 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0
17 ; CHECK-FP: br i1 [[CMP]], label %while.body, label %cleanup.loopexit
19 define void @test_fptosi(i32 %n, i32** %g, double** %d) {
21 %n.off = add i32 %n, -1
22 %0 = icmp ult i32 %n.off, 500
23 br i1 %0, label %while.body.lr.ph, label %cleanup
26 %1 = load double*, double** %d, align 4
27 %2 = load i32*, i32** %g, align 4
31 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
32 %rem = urem i32 %i.012, 10
33 %tobool = icmp eq i32 %rem, 0
34 br i1 %tobool, label %if.end4, label %if.then2
37 %arrayidx = getelementptr inbounds double, double* %1, i32 %i.012
38 %3 = load double, double* %arrayidx, align 8
39 %conv = fptosi double %3 to i32
40 %arrayidx3 = getelementptr inbounds i32, i32* %2, i32 %i.012
41 store i32 %conv, i32* %arrayidx3, align 4
45 %inc = add nuw i32 %i.012, 1
46 %cmp1 = icmp ult i32 %inc, %n
47 br i1 %cmp1, label %while.body, label %cleanup.loopexit
56 ; CHECK-LABEL: test_fptoui
58 ; CHECK-FP: [[COUNT:%[^ ]+]] = call i32 @llvm.umax.i32(i32 %n, i32 1)
59 ; CHECK-FP: while.body.lr.ph:
60 ; CHECK-FP: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 [[COUNT]])
61 ; CHECK-FP-NEXT: br label %while.body
63 ; CHECK-FP: [[REM:%[^ ]+]] = phi i32 [ [[START]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %if.end4 ]
64 ; CHECK-FP: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1)
65 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0
66 ; CHECK-FP: br i1 [[CMP]], label %while.body, label %cleanup.loopexit
68 ; CHECK-SOFT-NOT: call i32 @llvm.start.loop.iterations
70 define void @test_fptoui(i32 %n, i32** %g, double** %d) {
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
77 %1 = load double*, double** %d, align 4
78 %2 = load i32*, i32** %g, align 4
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
88 %arrayidx = getelementptr inbounds double, double* %1, i32 %i.012
89 %3 = load double, double* %arrayidx, align 8
90 %conv = fptoui double %3 to i32
91 %arrayidx3 = getelementptr inbounds i32, i32* %2, i32 %i.012
92 store i32 %conv, i32* %arrayidx3, align 4
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
107 ; CHECK-LABEL: load_store_float
109 ; CHECK: [[COUNT:%[^ ]+]] = call i32 @llvm.umax.i32(i32 %n, i32 1)
110 ; CHECK: while.body.lr.ph:
111 ; CHECK: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 [[COUNT]])
112 ; CHECK-NEXT: br label %while.body
114 ; CHECK: [[REM:%[^ ]+]] = phi i32 [ [[START]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %if.end4 ]
115 ; CHECK: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1)
116 ; CHECK: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0
117 ; CHECK: br i1 [[CMP]], label %while.body, label %cleanup.loopexit
119 define void @load_store_float(i32 %n, double** %d, double** %g) {
121 %n.off = add i32 %n, -1
122 %0 = icmp ult i32 %n.off, 500
123 br i1 %0, label %while.body.lr.ph, label %cleanup
126 %1 = load double*, double** %d, align 4
127 %2 = load double*, double** %g, align 4
131 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
132 %rem = urem i32 %i.012, 10
133 %tobool = icmp eq i32 %rem, 0
134 br i1 %tobool, label %if.end4, label %if.then2
137 %arrayidx = getelementptr inbounds double, double* %1, i32 %i.012
138 %3 = load double, double* %arrayidx, align 8
139 %arrayidx3 = getelementptr inbounds double, double* %2, i32 %i.012
140 store double %3, double* %arrayidx3, align 8
144 %inc = add nuw i32 %i.012, 1
145 %cmp1 = icmp ult i32 %inc, %n
146 br i1 %cmp1, label %while.body, label %cleanup.loopexit
155 ; CHECK-LABEL: fp_add
156 ; CHECK-SOFT-NOT: call i32 @llvm.start.loop.iterations
158 ; CHECK-FP: [[COUNT:%[^ ]+]] = call i32 @llvm.umax.i32(i32 %n, i32 1)
159 ; CHECK: while.body.lr.ph:
160 ; CHECK-FP: [[START:%[^ ]+]] = call i32 @llvm.start.loop.iterations.i32(i32 [[COUNT]])
161 ; CHECK: br label %while.body
163 ; CHECK-SOFT-NOT: call i32 @llvm.loop.decrement
165 ; CHECK-FP: [[REM:%[^ ]+]] = phi i32 [ [[START]], %while.body.lr.ph ], [ [[LOOP_DEC:%[^ ]+]], %if.end4 ]
166 ; CHECK-FP: [[LOOP_DEC]] = call i32 @llvm.loop.decrement.reg.i32(i32 [[REM]], i32 1)
167 ; CHECK-FP: [[CMP:%[^ ]+]] = icmp ne i32 [[LOOP_DEC]], 0
168 ; CHECK-FP: br i1 [[CMP]], label %while.body, label %cleanup.loopexit
170 define void @fp_add(i32 %n, float** %d, float** %g) {
172 %n.off = add i32 %n, -1
173 %0 = icmp ult i32 %n.off, 500
174 br i1 %0, label %while.body.lr.ph, label %cleanup
177 %1 = load float*, float** %d, align 4
178 %2 = load float*, float** %g, align 4
182 %i.012 = phi i32 [ 0, %while.body.lr.ph ], [ %inc, %if.end4 ]
183 %rem = urem i32 %i.012, 10
184 %tobool = icmp eq i32 %rem, 0
185 br i1 %tobool, label %if.end4, label %if.then2
188 %arrayidx = getelementptr inbounds float, float* %1, i32 %i.012
189 %3 = load float, float* %arrayidx, align 4
190 %arrayidx3 = getelementptr inbounds float, float* %2, i32 %i.012
191 %4 = load float, float* %arrayidx3, align 4
192 %add = fadd float %3, %4
193 store float %add, float* %arrayidx3, align 4
197 %inc = add nuw i32 %i.012, 1
198 %cmp1 = icmp ult i32 %inc, %n
199 br i1 %cmp1, label %while.body, label %cleanup.loopexit