blob: f764f736bc62bb5a46e3b97cc5b7b0eecb47925d [file] [log] [blame]
xueliang.zhongd71f1dc2018-01-24 17:24:16 +00001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17public class Main {
18 // Based on Linpack.matgen
19 // Load-store elimination did not work when a function had SIMD code.
20 // In the test below loop B is vectorized.
21 // Check that a redundant ArrayGet is eliminated in loop A.
22
23 /// CHECK-START: double Main.$noinline$vecgen(double[], double[], int) load_store_elimination (before)
24 /// CHECK: Rem
25 /// CHECK-NEXT: TypeConversion
26 /// CHECK-NEXT: Sub
27 /// CHECK-NEXT: Mul
28 /// CHECK-NEXT: ArraySet
29 /// CHECK-NEXT: ArrayGet
30 /// CHECK-NEXT: LessThanOrEqual
31 /// CHECK-NEXT: Select
32 /// CHECK-NEXT: Add
33 /// CHECK-NEXT: Goto loop:{{B\d+}}
34
35 /// CHECK-START: double Main.$noinline$vecgen(double[], double[], int) load_store_elimination (after)
36 /// CHECK: Rem
37 /// CHECK-NEXT: TypeConversion
38 /// CHECK-NEXT: Sub
39 /// CHECK-NEXT: Mul
40 /// CHECK-NEXT: ArraySet
41 /// CHECK-NEXT: LessThanOrEqual
42 /// CHECK-NEXT: Select
43 /// CHECK-NEXT: Add
44 /// CHECK-NEXT: Goto loop:{{B\d+}}
45 static double $noinline$vecgen(double a[], double b[], int n) {
46 double norma = 0.0;
47 int init = 1325;
48 // Loop A
49 for (int i = 0; i < n; ++i) {
50 init = 3125*init % 65536;
51 a[i] = (init - 32768.0)/16384.0;
52 norma = (a[i] > norma) ? a[i] : norma; // ArrayGet should be removed by LSE.
53 }
54
55 // Loop B
56 for (int i = 0; i < n; ++i) {
57 b[i] += a[i];
58 }
59
60 return norma;
61 }
62
63
64 static void test01() {
65 double a[] = new double[1024];
66 double norma = $noinline$vecgen(a, a, a.length);
67 System.out.println((int)norma);
68 System.out.println((int)a[1023]);
69 }
70
71 // Check LSE works when a function has SIMD code.
72 //
73 /// CHECK-START: double Main.$noinline$test02(double[], int) load_store_elimination (before)
74 /// CHECK: BoundsCheck loop:none
75 /// CHECK-NEXT: ArrayGet
76 /// CHECK-NEXT: Mul
77 /// CHECK-NEXT: ArraySet
78 /// CHECK-NEXT: ArrayGet
79 /// CHECK-NEXT: ArrayLength
80 /// CHECK-NEXT: BelowOrEqual
81 //
82 /// CHECK: ArrayGet loop:none
83 /// CHECK-NEXT: Return
84
85 /// CHECK-START: double Main.$noinline$test02(double[], int) load_store_elimination (after)
86 /// CHECK: BoundsCheck loop:none
87 /// CHECK-NEXT: ArrayGet
88 /// CHECK-NEXT: Mul
89 /// CHECK-NEXT: ArraySet
90 /// CHECK-NEXT: ArrayLength
91 /// CHECK-NEXT: BelowOrEqual
92 //
Vladimir Marko3224f382020-06-23 14:19:53 +010093 /// CHECK: Return
xueliang.zhongd71f1dc2018-01-24 17:24:16 +000094 static double $noinline$test02(double a[], int n) {
95 double b[] = new double[n];
96 a[0] = a[0] / 2;
97
98 double norma = a[0]; // ArrayGet should be removed by LSE.
99
100 // The following loop is vectorized.
101 for (int i = 0; i < 128; ++i) {
102 b[i] += a[i];
103 }
104
Vladimir Marko3224f382020-06-23 14:19:53 +0100105 norma = a[0]; // ArrayGet should be removed by LSE.
xueliang.zhongd71f1dc2018-01-24 17:24:16 +0000106 return norma;
107 }
108
109 static void test02() {
110 double a[] = new double[128];
111 java.util.Arrays.fill(a, 2.0);
112 double norma = $noinline$test02(a, a.length);
113 System.out.println((int)norma);
114 }
115
116 // Check LSE works when a function has SIMD code.
117 //
118 /// CHECK-START: double Main.$noinline$test03(int) load_store_elimination (before)
119 /// CHECK: ArrayGet loop:none
120 /// CHECK-NEXT: Return
121
122 /// CHECK-START: double Main.$noinline$test03(int) load_store_elimination (after)
123 /// CHECK-NOT: ArrayGet loop:none
124 static double $noinline$test03(int n) {
125 double a[] = new double[n];
126 double b[] = new double[n];
127
128 a[0] = 2.0;
129
130 // The following loop is vectorized.
131 for (int i = 0; i < 128; ++i) {
132 b[i] += a[i];
133 }
134
135 a[0] = 2.0;
136 return a[0]; // ArrayGet should be removed by LSE.
137 }
138
139 static void test03() {
140 double norma = $noinline$test03(128);
141 System.out.println((int)norma);
142 }
143
144 // Check LSE eliminates VecLoad.
145 //
146 /// CHECK-START-ARM64: double[] Main.$noinline$test04(int) load_store_elimination (before)
147 /// CHECK: VecStore
148 /// CHECK-NEXT: VecLoad
149 /// CHECK-NEXT: VecAdd
150 /// CHECK-NEXT: VecStore
151 /// CHECK-NEXT: Add
152 /// CHECK-NEXT: Goto loop:{{B\d+}}
153
154 /// CHECK-START-ARM64: double[] Main.$noinline$test04(int) load_store_elimination (after)
155 /// CHECK: VecStore
156 /// CHECK-NEXT: VecAdd
157 /// CHECK-NEXT: VecStore
158 /// CHECK-NEXT: Add
159 /// CHECK-NEXT: Goto loop:{{B\d+}}
160 static double[] $noinline$test04(int n) {
161 double a[] = new double[n];
162 double b[] = new double[n];
163
164 // The following loop is vectorized.
165 for (int i = 0; i < n; ++i) {
166 a[i] = 1;
167 b[i] = a[i] + a[i]; // VecLoad should be removed by LSE.
168 }
169
170 return b;
171 }
172
173 static void test04() {
174 double norma = $noinline$test04(128)[0];
175 System.out.println((int)norma);
176 }
177
178 // Check LSE eliminates VecLoad.
179 //
180 /// CHECK-START-ARM64: double[] Main.$noinline$test05(int) load_store_elimination (before)
181 /// CHECK: VecStore
182 /// CHECK-NEXT: VecLoad
183 /// CHECK-NEXT: VecStore
184 /// CHECK-NEXT: VecStore
185 /// CHECK-NEXT: Add
186 /// CHECK-NEXT: Goto loop:{{B\d+}}
187
188 /// CHECK-START-ARM64: double[] Main.$noinline$test05(int) load_store_elimination (after)
189 /// CHECK: VecStore
190 /// CHECK-NEXT: VecStore
191 /// CHECK-NEXT: Add
192 /// CHECK-NEXT: Goto loop:{{B\d+}}
193 static double[] $noinline$test05(int n) {
194 double a[] = new double[n];
195 double b[] = new double[n];
196
197 // The following loop is vectorized.
198 for (int i = 0; i < n; ++i) {
199 a[i] = 1;
200 b[i] = a[i];
201 a[i] = 1;
202 }
203
204 return b;
205 }
206
207 static void test05() {
208 double norma = $noinline$test05(128)[0];
209 System.out.println((int)norma);
210 }
211
212 // Check LSE eliminates VecLoad and ArrayGet in case of singletons and default values.
213 //
214 /// CHECK-START-ARM64: double[] Main.$noinline$test06(int) load_store_elimination (before)
215 /// CHECK: BoundsCheck loop:none
216 /// CHECK-NEXT: ArrayGet
217 /// CHECK-NEXT: Add
218 /// CHECK-NEXT: ArrayLength
219 //
220 /// CHECK: VecLoad loop:{{B\d+}}
221 /// CHECK-NEXT: VecStore
222 /// CHECK-NEXT: VecLoad
223 /// CHECK-NEXT: VecLoad
224 /// CHECK-NEXT: VecAdd
225 /// CHECK-NEXT: VecAdd
226 /// CHECK-NEXT: VecStore
227
228 /// CHECK-START-ARM64: double[] Main.$noinline$test06(int) load_store_elimination (after)
229 /// CHECK: BoundsCheck loop:none
230 /// CHECK-NEXT: Add
231 /// CHECK-NEXT: ArrayLength
232 //
233 /// CHECK: VecLoad loop:{{B\d+}}
234 /// CHECK-NEXT: VecStore
235 /// CHECK-NEXT: VecAdd
236 /// CHECK-NEXT: VecAdd
237 /// CHECK-NEXT: VecStore
238 static double[] $noinline$test06(int n) {
239 double a[] = new double[n];
240 double b[] = new double[n];
241
242 double r = a[0] + 1.0; // ArrayGet:a[0] is eliminated and default 0.0 is used.
243 // The following loop is vectorized.
244 for (int i = 0; i < n; ++i) {
245 b[i] = a[i]; // VecLoad:a[i] is not eliminated.
246 b[i] += a[i] + r; // VecLoad:a[i] and VecLoad:b[i] are eliminated.
247 }
248
249 return b;
250 }
251
252 static void test06() {
253 double norma = $noinline$test06(128)[0];
254 System.out.println((int)norma);
255 }
256
257 public static void main(String[] args) {
258 test01();
259 test02();
260 test03();
261 test04();
262 test05();
263 test06();
264 }
265}
266