[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / Transforms / HardwareLoops / ARM / fp-emulation.ll
blobddb4c6a4cea69330be9adac917ab0fe49bb8a1c7
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
7 ; CHECK: entry:
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) {
21 entry:
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
26 while.body.lr.ph:
27   %1 = load double*, double** %d, align 4
28   %2 = load i32*, i32** %g, align 4
29   br label %while.body
31 while.body:
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
37 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
43   br label %if.end4
45 if.end4:
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
50 cleanup.loopexit:
51   br label %cleanup
53 cleanup:
54   ret void
57 ; CHECK-LABEL: test_fptoui
58 ; CHECK: entry:
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) {
73 entry:
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
78 while.body.lr.ph:
79   %1 = load double*, double** %d, align 4
80   %2 = load i32*, i32** %g, align 4
81   br label %while.body
83 while.body:
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
89 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
95   br label %if.end4
97 if.end4:
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
102 cleanup.loopexit:
103   br label %cleanup
105 cleanup:
106   ret void
109 ; CHECK-LABEL: load_store_float
110 ; CHECK: entry:
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) {
123 entry:
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
128 while.body.lr.ph:
129   %1 = load double*, double** %d, align 4
130   %2 = load double*, double** %g, align 4
131   br label %while.body
133 while.body:
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
139 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
144   br label %if.end4
146 if.end4:
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
151 cleanup.loopexit:
152   br label %cleanup
154 cleanup:
155   ret void
158 ; CHECK-LABEL: fp_add
159 ; CHECK-SOFT-NOT: call void @llvm.set.loop.iterations
160 ; CHECK: entry:
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) {
175 entry:
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
180 while.body.lr.ph:
181   %1 = load float*, float** %d, align 4
182   %2 = load float*, float** %g, align 4
183   br label %while.body
185 while.body:
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
191 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
198   br label %if.end4
200 if.end4:
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
205 cleanup.loopexit:
206   br label %cleanup
208 cleanup:
209   ret void