[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / HardwareLoops / ARM / fp-emulation.ll
blob5de4e3be5a95b6e0912e5d40586ba8362b526a8e
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
7 ; CHECK: entry:
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) {
20 entry:
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
25 while.body.lr.ph:
26   %1 = load double*, double** %d, align 4
27   %2 = load i32*, i32** %g, align 4
28   br label %while.body
30 while.body:
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
36 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
42   br label %if.end4
44 if.end4:
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
49 cleanup.loopexit:
50   br label %cleanup
52 cleanup:
53   ret void
56 ; CHECK-LABEL: test_fptoui
57 ; CHECK: entry:
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) {
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 double*, double** %d, align 4
78   %2 = load i32*, i32** %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, 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
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 ; CHECK-LABEL: load_store_float
108 ; CHECK: entry:
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) {
120 entry:
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
125 while.body.lr.ph:
126   %1 = load double*, double** %d, align 4
127   %2 = load double*, double** %g, align 4
128   br label %while.body
130 while.body:
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
136 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
141   br label %if.end4
143 if.end4:
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
148 cleanup.loopexit:
149   br label %cleanup
151 cleanup:
152   ret void
155 ; CHECK-LABEL: fp_add
156 ; CHECK-SOFT-NOT: call i32 @llvm.start.loop.iterations
157 ; CHECK: entry:
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) {
171 entry:
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
176 while.body.lr.ph:
177   %1 = load float*, float** %d, align 4
178   %2 = load float*, float** %g, align 4
179   br label %while.body
181 while.body:
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
187 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
194   br label %if.end4
196 if.end4:
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
201 cleanup.loopexit:
202   br label %cleanup
204 cleanup:
205   ret void