blob: 6151fc10f2510998b779314a2736f1459ae99113 [file] [log] [blame]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001/*
Roland Levillain6a92a032015-07-23 12:15:01 +01002 * Copyright (C) 2015 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 */
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000016
17public class Main {
18
David Brazdil0d13fee2015-04-17 14:52:19 +010019 public static void assertBooleanEquals(boolean expected, boolean result) {
20 if (expected != result) {
21 throw new Error("Expected: " + expected + ", found: " + result);
22 }
23 }
24
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000025 public static void assertIntEquals(int expected, int result) {
26 if (expected != result) {
27 throw new Error("Expected: " + expected + ", found: " + result);
28 }
29 }
30
31 public static void assertLongEquals(long expected, long result) {
32 if (expected != result) {
33 throw new Error("Expected: " + expected + ", found: " + result);
34 }
35 }
36
Nicolas Geoffray0d221842015-04-27 08:53:46 +000037 public static void assertFloatEquals(float expected, float result) {
38 if (expected != result) {
39 throw new Error("Expected: " + expected + ", found: " + result);
40 }
41 }
42
43 public static void assertDoubleEquals(double expected, double result) {
44 if (expected != result) {
45 throw new Error("Expected: " + expected + ", found: " + result);
46 }
47 }
48
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000049 /**
50 * Tiny programs exercising optimizations of arithmetic identities.
51 */
52
David Brazdila06d66a2015-05-28 11:14:54 +010053 /// CHECK-START: long Main.Add0(long) instruction_simplifier (before)
54 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
55 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
56 /// CHECK-DAG: <<Add:j\d+>> Add [<<Const0>>,<<Arg>>]
57 /// CHECK-DAG: Return [<<Add>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000058
David Brazdila06d66a2015-05-28 11:14:54 +010059 /// CHECK-START: long Main.Add0(long) instruction_simplifier (after)
60 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
61 /// CHECK-DAG: Return [<<Arg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +010062
David Brazdila06d66a2015-05-28 11:14:54 +010063 /// CHECK-START: long Main.Add0(long) instruction_simplifier (after)
64 /// CHECK-NOT: Add
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000065
66 public static long Add0(long arg) {
67 return 0 + arg;
68 }
69
David Brazdila06d66a2015-05-28 11:14:54 +010070 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before)
71 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
72 /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
73 /// CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<ConstF>>]
74 /// CHECK-DAG: Return [<<And>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000075
David Brazdila06d66a2015-05-28 11:14:54 +010076 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
77 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
78 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000079
David Brazdila06d66a2015-05-28 11:14:54 +010080 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
81 /// CHECK-NOT: And
Alexandre Rames74417692015-04-09 15:21:41 +010082
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +000083 public static int AndAllOnes(int arg) {
84 return arg & -1;
85 }
86
Vladimir Marko452c1b62015-09-25 14:44:17 +010087 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (before)
88 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
89 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28
90 /// CHECK-DAG: <<Const15:i\d+>> IntConstant 15
91 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>]
92 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const15>>]
93 /// CHECK-DAG: Return [<<And>>]
94
95 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (after)
96 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
97 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28
98 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>]
99 /// CHECK-DAG: Return [<<UShr>>]
100
101 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (after)
102 /// CHECK-NOT: And
103
104 public static int UShr28And15(int arg) {
105 return (arg >>> 28) & 15;
106 }
107
108 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (before)
109 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
110 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60
111 /// CHECK-DAG: <<Const15:j\d+>> LongConstant 15
112 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>]
113 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const15>>]
114 /// CHECK-DAG: Return [<<And>>]
115
116 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (after)
117 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
118 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60
119 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>]
120 /// CHECK-DAG: Return [<<UShr>>]
121
122 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (after)
123 /// CHECK-NOT: And
124
125 public static long UShr60And15(long arg) {
126 return (arg >>> 60) & 15;
127 }
128
129 /// CHECK-START: int Main.UShr28And7(int) instruction_simplifier (before)
130 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
131 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28
132 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
133 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>]
134 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const7>>]
135 /// CHECK-DAG: Return [<<And>>]
136
137 /// CHECK-START: int Main.UShr28And7(int) instruction_simplifier (after)
138 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
139 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28
140 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
141 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>]
142 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const7>>]
143 /// CHECK-DAG: Return [<<And>>]
144
145 public static int UShr28And7(int arg) {
146 return (arg >>> 28) & 7;
147 }
148
149 /// CHECK-START: long Main.UShr60And7(long) instruction_simplifier (before)
150 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
151 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60
152 /// CHECK-DAG: <<Const7:j\d+>> LongConstant 7
153 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>]
154 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const7>>]
155 /// CHECK-DAG: Return [<<And>>]
156
157 /// CHECK-START: long Main.UShr60And7(long) instruction_simplifier (after)
158 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
159 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60
160 /// CHECK-DAG: <<Const7:j\d+>> LongConstant 7
161 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>]
162 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const7>>]
163 /// CHECK-DAG: Return [<<And>>]
164
165 public static long UShr60And7(long arg) {
166 return (arg >>> 60) & 7;
167 }
168
169 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (before)
170 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
171 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24
172 /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255
173 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>]
174 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const255>>]
175 /// CHECK-DAG: Return [<<And>>]
176
177 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (after)
178 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
179 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24
180 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const24>>]
181 /// CHECK-DAG: Return [<<UShr>>]
182
183 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (after)
184 /// CHECK-NOT: Shr
185 /// CHECK-NOT: And
186
187 public static int Shr24And255(int arg) {
188 return (arg >> 24) & 255;
189 }
190
191 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (before)
192 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
193 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56
194 /// CHECK-DAG: <<Const255:j\d+>> LongConstant 255
195 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>]
196 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const255>>]
197 /// CHECK-DAG: Return [<<And>>]
198
199 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (after)
200 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
201 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56
202 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const56>>]
203 /// CHECK-DAG: Return [<<UShr>>]
204
205 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (after)
206 /// CHECK-NOT: Shr
207 /// CHECK-NOT: And
208
209 public static long Shr56And255(long arg) {
210 return (arg >> 56) & 255;
211 }
212
213 /// CHECK-START: int Main.Shr24And127(int) instruction_simplifier (before)
214 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
215 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24
216 /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127
217 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>]
218 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>]
219 /// CHECK-DAG: Return [<<And>>]
220
221 /// CHECK-START: int Main.Shr24And127(int) instruction_simplifier (after)
222 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
223 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24
224 /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127
225 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>]
226 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>]
227 /// CHECK-DAG: Return [<<And>>]
228
229 public static int Shr24And127(int arg) {
230 return (arg >> 24) & 127;
231 }
232
233 /// CHECK-START: long Main.Shr56And127(long) instruction_simplifier (before)
234 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
235 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56
236 /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127
237 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>]
238 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>]
239 /// CHECK-DAG: Return [<<And>>]
240
241 /// CHECK-START: long Main.Shr56And127(long) instruction_simplifier (after)
242 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
243 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56
244 /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127
245 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>]
246 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>]
247 /// CHECK-DAG: Return [<<And>>]
248
249 public static long Shr56And127(long arg) {
250 return (arg >> 56) & 127;
251 }
252
David Brazdila06d66a2015-05-28 11:14:54 +0100253 /// CHECK-START: long Main.Div1(long) instruction_simplifier (before)
254 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
255 /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1
256 /// CHECK-DAG: <<Div:j\d+>> Div [<<Arg>>,<<Const1>>]
257 /// CHECK-DAG: Return [<<Div>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000258
David Brazdila06d66a2015-05-28 11:14:54 +0100259 /// CHECK-START: long Main.Div1(long) instruction_simplifier (after)
260 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
261 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000262
David Brazdila06d66a2015-05-28 11:14:54 +0100263 /// CHECK-START: long Main.Div1(long) instruction_simplifier (after)
264 /// CHECK-NOT: Div
Alexandre Rames74417692015-04-09 15:21:41 +0100265
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000266 public static long Div1(long arg) {
267 return arg / 1;
268 }
269
David Brazdila06d66a2015-05-28 11:14:54 +0100270 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (before)
271 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
272 /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
273 /// CHECK-DAG: <<Div:i\d+>> Div [<<Arg>>,<<ConstN1>>]
274 /// CHECK-DAG: Return [<<Div>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000275
David Brazdila06d66a2015-05-28 11:14:54 +0100276 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
277 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
278 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
279 /// CHECK-DAG: Return [<<Neg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000280
David Brazdila06d66a2015-05-28 11:14:54 +0100281 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
282 /// CHECK-NOT: Div
Alexandre Rames74417692015-04-09 15:21:41 +0100283
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000284 public static int DivN1(int arg) {
285 return arg / -1;
286 }
287
David Brazdila06d66a2015-05-28 11:14:54 +0100288 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (before)
289 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
290 /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1
291 /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Arg>>,<<Const1>>]
292 /// CHECK-DAG: Return [<<Mul>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000293
David Brazdila06d66a2015-05-28 11:14:54 +0100294 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
295 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
296 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000297
David Brazdila06d66a2015-05-28 11:14:54 +0100298 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
299 /// CHECK-NOT: Mul
Alexandre Rames74417692015-04-09 15:21:41 +0100300
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000301 public static long Mul1(long arg) {
302 return arg * 1;
303 }
304
David Brazdila06d66a2015-05-28 11:14:54 +0100305 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (before)
306 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
307 /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1
308 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Arg>>,<<ConstN1>>]
309 /// CHECK-DAG: Return [<<Mul>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000310
David Brazdila06d66a2015-05-28 11:14:54 +0100311 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
312 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
313 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
314 /// CHECK-DAG: Return [<<Neg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000315
David Brazdila06d66a2015-05-28 11:14:54 +0100316 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
317 /// CHECK-NOT: Mul
Alexandre Rames74417692015-04-09 15:21:41 +0100318
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000319 public static int MulN1(int arg) {
320 return arg * -1;
321 }
322
David Brazdila06d66a2015-05-28 11:14:54 +0100323 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before)
324 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
325 /// CHECK-DAG: <<Const128:j\d+>> LongConstant 128
326 /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Arg>>,<<Const128>>]
327 /// CHECK-DAG: Return [<<Mul>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000328
David Brazdila06d66a2015-05-28 11:14:54 +0100329 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
330 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
331 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7
332 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<Arg>>,<<Const7>>]
333 /// CHECK-DAG: Return [<<Shl>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000334
David Brazdila06d66a2015-05-28 11:14:54 +0100335 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
336 /// CHECK-NOT: Mul
Alexandre Rames74417692015-04-09 15:21:41 +0100337
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000338 public static long MulPowerOfTwo128(long arg) {
339 return arg * 128;
340 }
341
David Brazdila06d66a2015-05-28 11:14:54 +0100342 /// CHECK-START: int Main.Or0(int) instruction_simplifier (before)
343 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
344 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
345 /// CHECK-DAG: <<Or:i\d+>> Or [<<Arg>>,<<Const0>>]
346 /// CHECK-DAG: Return [<<Or>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000347
David Brazdila06d66a2015-05-28 11:14:54 +0100348 /// CHECK-START: int Main.Or0(int) instruction_simplifier (after)
349 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
350 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000351
David Brazdila06d66a2015-05-28 11:14:54 +0100352 /// CHECK-START: int Main.Or0(int) instruction_simplifier (after)
353 /// CHECK-NOT: Or
Alexandre Rames74417692015-04-09 15:21:41 +0100354
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000355 public static int Or0(int arg) {
356 return arg | 0;
357 }
358
David Brazdila06d66a2015-05-28 11:14:54 +0100359 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (before)
360 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
361 /// CHECK-DAG: <<Or:j\d+>> Or [<<Arg>>,<<Arg>>]
362 /// CHECK-DAG: Return [<<Or>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000363
David Brazdila06d66a2015-05-28 11:14:54 +0100364 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
365 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
366 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000367
David Brazdila06d66a2015-05-28 11:14:54 +0100368 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
369 /// CHECK-NOT: Or
Alexandre Rames74417692015-04-09 15:21:41 +0100370
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000371 public static long OrSame(long arg) {
372 return arg | arg;
373 }
374
David Brazdila06d66a2015-05-28 11:14:54 +0100375 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (before)
376 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
377 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
378 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const0>>]
379 /// CHECK-DAG: Return [<<Shl>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000380
David Brazdila06d66a2015-05-28 11:14:54 +0100381 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
382 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
383 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000384
David Brazdila06d66a2015-05-28 11:14:54 +0100385 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
386 /// CHECK-NOT: Shl
Alexandre Rames74417692015-04-09 15:21:41 +0100387
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000388 public static int Shl0(int arg) {
389 return arg << 0;
390 }
391
David Brazdila06d66a2015-05-28 11:14:54 +0100392 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (before)
393 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
394 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
395 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const0>>]
396 /// CHECK-DAG: Return [<<Shr>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000397
David Brazdila06d66a2015-05-28 11:14:54 +0100398 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
399 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
400 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000401
David Brazdila06d66a2015-05-28 11:14:54 +0100402 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
403 /// CHECK-NOT: Shr
Alexandre Rames74417692015-04-09 15:21:41 +0100404
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000405 public static long Shr0(long arg) {
406 return arg >> 0;
407 }
408
David Brazdila06d66a2015-05-28 11:14:54 +0100409 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (before)
410 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
411 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
412 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg>>,<<Const0>>]
413 /// CHECK-DAG: Return [<<Sub>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000414
David Brazdila06d66a2015-05-28 11:14:54 +0100415 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
416 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
417 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000418
David Brazdila06d66a2015-05-28 11:14:54 +0100419 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
420 /// CHECK-NOT: Sub
Alexandre Rames74417692015-04-09 15:21:41 +0100421
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000422 public static long Sub0(long arg) {
423 return arg - 0;
424 }
425
David Brazdila06d66a2015-05-28 11:14:54 +0100426 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before)
427 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
428 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
429 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const0>>,<<Arg>>]
430 /// CHECK-DAG: Return [<<Sub>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000431
David Brazdila06d66a2015-05-28 11:14:54 +0100432 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
433 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
434 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>]
435 /// CHECK-DAG: Return [<<Neg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000436
David Brazdila06d66a2015-05-28 11:14:54 +0100437 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
438 /// CHECK-NOT: Sub
Alexandre Rames74417692015-04-09 15:21:41 +0100439
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000440 public static int SubAliasNeg(int arg) {
441 return 0 - arg;
442 }
443
David Brazdila06d66a2015-05-28 11:14:54 +0100444 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (before)
445 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
446 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
447 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const0>>]
448 /// CHECK-DAG: Return [<<UShr>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000449
David Brazdila06d66a2015-05-28 11:14:54 +0100450 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
451 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
452 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000453
David Brazdila06d66a2015-05-28 11:14:54 +0100454 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
455 /// CHECK-NOT: UShr
Alexandre Rames74417692015-04-09 15:21:41 +0100456
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000457 public static long UShr0(long arg) {
458 return arg >>> 0;
459 }
460
David Brazdila06d66a2015-05-28 11:14:54 +0100461 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (before)
462 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
463 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
464 /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<Const0>>]
465 /// CHECK-DAG: Return [<<Xor>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000466
David Brazdila06d66a2015-05-28 11:14:54 +0100467 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
468 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
469 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000470
David Brazdila06d66a2015-05-28 11:14:54 +0100471 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
472 /// CHECK-NOT: Xor
Alexandre Rames74417692015-04-09 15:21:41 +0100473
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000474 public static int Xor0(int arg) {
475 return arg ^ 0;
476 }
477
David Brazdila06d66a2015-05-28 11:14:54 +0100478 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before)
479 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
480 /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1
481 /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<ConstF>>]
482 /// CHECK-DAG: Return [<<Xor>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000483
David Brazdila06d66a2015-05-28 11:14:54 +0100484 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
485 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
486 /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>]
487 /// CHECK-DAG: Return [<<Not>>]
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000488
David Brazdila06d66a2015-05-28 11:14:54 +0100489 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
490 /// CHECK-NOT: Xor
Alexandre Rames74417692015-04-09 15:21:41 +0100491
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +0000492 public static int XorAllOnes(int arg) {
493 return arg ^ -1;
494 }
495
Alexandre Rames188d4312015-04-09 18:30:21 +0100496 /**
497 * Test that addition or subtraction operation with both inputs negated are
498 * optimized to use a single negation after the operation.
499 * The transformation tested is implemented in
500 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
501 */
502
David Brazdila06d66a2015-05-28 11:14:54 +0100503 /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before)
504 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
505 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
506 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
507 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
508 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
509 /// CHECK-DAG: Return [<<Add>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100510
David Brazdila06d66a2015-05-28 11:14:54 +0100511 /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after)
512 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
513 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
514 /// CHECK-NOT: Neg
515 /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>]
516 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>]
517 /// CHECK-DAG: Return [<<Neg>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100518
519 public static int AddNegs1(int arg1, int arg2) {
520 return -arg1 + -arg2;
521 }
522
523 /**
524 * This is similar to the test-case AddNegs1, but the negations have
525 * multiple uses.
526 * The transformation tested is implemented in
527 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
528 * The current code won't perform the previous optimization. The
529 * transformations do not look at other uses of their inputs. As they don't
530 * know what will happen with other uses, they do not take the risk of
531 * increasing the register pressure by creating or extending live ranges.
532 */
533
David Brazdila06d66a2015-05-28 11:14:54 +0100534 /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before)
535 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
536 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
537 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
538 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
539 /// CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>]
540 /// CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>]
541 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>]
542 /// CHECK-DAG: Return [<<Or>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100543
David Brazdila06d66a2015-05-28 11:14:54 +0100544 /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after)
545 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
546 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
547 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
548 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
549 /// CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>]
550 /// CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>]
551 /// CHECK-NOT: Neg
552 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>]
553 /// CHECK-DAG: Return [<<Or>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100554
David Brazdila06d66a2015-05-28 11:14:54 +0100555 /// CHECK-START: int Main.AddNegs2(int, int) GVN (after)
556 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
557 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
558 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>]
559 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>]
560 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
561 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add>>,<<Add>>]
562 /// CHECK-DAG: Return [<<Or>>]
Alexandre Ramesb2a58472015-04-17 14:35:18 +0100563
Alexandre Rames188d4312015-04-09 18:30:21 +0100564 public static int AddNegs2(int arg1, int arg2) {
565 int temp1 = -arg1;
566 int temp2 = -arg2;
567 return (temp1 + temp2) | (temp1 + temp2);
568 }
569
570 /**
571 * This follows test-cases AddNegs1 and AddNegs2.
572 * The transformation tested is implemented in
573 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
574 * The optimization should not happen if it moves an additional instruction in
575 * the loop.
576 */
577
David Brazdila06d66a2015-05-28 11:14:54 +0100578 /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
579 // -------------- Arguments and initial negation operations.
580 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
581 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
582 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>]
583 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>]
584 /// CHECK: Goto
585 // -------------- Loop
586 /// CHECK: SuspendCheck
587 /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>]
588 /// CHECK: Goto
Alexandre Rames188d4312015-04-09 18:30:21 +0100589
David Brazdila06d66a2015-05-28 11:14:54 +0100590 /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
591 // -------------- Arguments and initial negation operations.
592 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
593 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
594 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>]
595 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>]
596 /// CHECK: Goto
597 // -------------- Loop
598 /// CHECK: SuspendCheck
599 /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>]
600 /// CHECK-NOT: Neg
601 /// CHECK: Goto
Alexandre Rames188d4312015-04-09 18:30:21 +0100602
603 public static long AddNegs3(long arg1, long arg2) {
604 long res = 0;
605 long n_arg1 = -arg1;
606 long n_arg2 = -arg2;
607 for (long i = 0; i < 1; i++) {
608 res += n_arg1 + n_arg2 + i;
609 }
610 return res;
611 }
612
613 /**
614 * Test the simplification of an addition with a negated argument into a
615 * subtraction.
616 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
617 */
618
David Brazdila06d66a2015-05-28 11:14:54 +0100619 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before)
620 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
621 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
622 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
623 /// CHECK-DAG: <<Add:j\d+>> Add [<<Neg>>,<<Arg2>>]
624 /// CHECK-DAG: Return [<<Add>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100625
David Brazdila06d66a2015-05-28 11:14:54 +0100626 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
627 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
628 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
629 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg2>>,<<Arg1>>]
630 /// CHECK-DAG: Return [<<Sub>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100631
David Brazdila06d66a2015-05-28 11:14:54 +0100632 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
633 /// CHECK-NOT: Neg
634 /// CHECK-NOT: Add
Alexandre Rames188d4312015-04-09 18:30:21 +0100635
636 public static long AddNeg1(long arg1, long arg2) {
637 return -arg1 + arg2;
638 }
639
640 /**
641 * This is similar to the test-case AddNeg1, but the negation has two uses.
642 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
643 * The current code won't perform the previous optimization. The
644 * transformations do not look at other uses of their inputs. As they don't
645 * know what will happen with other uses, they do not take the risk of
646 * increasing the register pressure by creating or extending live ranges.
647 */
648
David Brazdila06d66a2015-05-28 11:14:54 +0100649 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
650 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
651 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
652 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>]
653 /// CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>]
654 /// CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>]
655 /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>]
656 /// CHECK-DAG: Return [<<Res>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100657
David Brazdila06d66a2015-05-28 11:14:54 +0100658 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
659 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
660 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
661 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>]
662 /// CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>]
663 /// CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>]
664 /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>]
665 /// CHECK-DAG: Return [<<Res>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100666
David Brazdila06d66a2015-05-28 11:14:54 +0100667 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
668 /// CHECK-NOT: Sub
Alexandre Rames188d4312015-04-09 18:30:21 +0100669
670 public static long AddNeg2(long arg1, long arg2) {
671 long temp = -arg2;
672 return (arg1 + temp) | (arg1 + temp);
673 }
674
675 /**
676 * Test simplification of the `-(-var)` pattern.
677 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
678 */
679
David Brazdila06d66a2015-05-28 11:14:54 +0100680 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
681 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
682 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg>>]
683 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Neg1>>]
684 /// CHECK-DAG: Return [<<Neg2>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100685
David Brazdila06d66a2015-05-28 11:14:54 +0100686 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
687 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
688 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100689
David Brazdila06d66a2015-05-28 11:14:54 +0100690 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
691 /// CHECK-NOT: Neg
Alexandre Rames188d4312015-04-09 18:30:21 +0100692
693 public static long NegNeg1(long arg) {
694 return -(-arg);
695 }
696
697 /**
698 * Test 'multi-step' simplification, where a first transformation yields a
699 * new simplification possibility for the current instruction.
700 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
701 * and in `InstructionSimplifierVisitor::VisitAdd`.
702 */
703
David Brazdila06d66a2015-05-28 11:14:54 +0100704 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
705 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
706 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg>>]
707 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Neg1>>]
708 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>]
709 /// CHECK-DAG: Return [<<Add>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100710
David Brazdila06d66a2015-05-28 11:14:54 +0100711 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
712 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
713 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg>>,<<Arg>>]
714 /// CHECK-DAG: Return [<<Sub>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100715
David Brazdila06d66a2015-05-28 11:14:54 +0100716 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
717 /// CHECK-NOT: Neg
718 /// CHECK-NOT: Add
Alexandre Rames188d4312015-04-09 18:30:21 +0100719
David Brazdila06d66a2015-05-28 11:14:54 +0100720 /// CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after)
721 /// CHECK: <<Const0:i\d+>> IntConstant 0
722 /// CHECK-NOT: Neg
723 /// CHECK-NOT: Add
724 /// CHECK: Return [<<Const0>>]
Alexandre Ramesb2a58472015-04-17 14:35:18 +0100725
Alexandre Rames188d4312015-04-09 18:30:21 +0100726 public static int NegNeg2(int arg) {
727 int temp = -arg;
728 return temp + -temp;
729 }
730
731 /**
732 * Test another 'multi-step' simplification, where a first transformation
733 * yields a new simplification possibility for the current instruction.
734 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
735 * and in `InstructionSimplifierVisitor::VisitSub`.
736 */
737
David Brazdila06d66a2015-05-28 11:14:54 +0100738 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
739 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
740 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0
741 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg>>]
742 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Const0>>,<<Neg>>]
743 /// CHECK-DAG: Return [<<Sub>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100744
David Brazdila06d66a2015-05-28 11:14:54 +0100745 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
746 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
747 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100748
David Brazdila06d66a2015-05-28 11:14:54 +0100749 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
750 /// CHECK-NOT: Neg
751 /// CHECK-NOT: Sub
Alexandre Rames188d4312015-04-09 18:30:21 +0100752
753 public static long NegNeg3(long arg) {
754 return 0 - -arg;
755 }
756
757 /**
758 * Test that a negated subtraction is simplified to a subtraction with its
759 * arguments reversed.
760 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
761 */
762
David Brazdila06d66a2015-05-28 11:14:54 +0100763 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before)
764 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
765 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
766 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
767 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Sub>>]
768 /// CHECK-DAG: Return [<<Neg>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100769
David Brazdila06d66a2015-05-28 11:14:54 +0100770 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
771 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
772 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
773 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg2>>,<<Arg1>>]
774 /// CHECK-DAG: Return [<<Sub>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100775
David Brazdila06d66a2015-05-28 11:14:54 +0100776 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
777 /// CHECK-NOT: Neg
Alexandre Rames188d4312015-04-09 18:30:21 +0100778
779 public static int NegSub1(int arg1, int arg2) {
780 return -(arg1 - arg2);
781 }
782
783 /**
784 * This is similar to the test-case NegSub1, but the subtraction has
785 * multiple uses.
786 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
787 * The current code won't perform the previous optimization. The
788 * transformations do not look at other uses of their inputs. As they don't
789 * know what will happen with other uses, they do not take the risk of
790 * increasing the register pressure by creating or extending live ranges.
791 */
792
David Brazdila06d66a2015-05-28 11:14:54 +0100793 /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
794 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
795 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
796 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
797 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>]
798 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>]
799 /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>]
800 /// CHECK-DAG: Return [<<Or>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100801
David Brazdila06d66a2015-05-28 11:14:54 +0100802 /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
803 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
804 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
805 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>]
806 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>]
807 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>]
808 /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>]
809 /// CHECK-DAG: Return [<<Or>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100810
811 public static int NegSub2(int arg1, int arg2) {
812 int temp = arg1 - arg2;
813 return -temp | -temp;
814 }
815
816 /**
817 * Test simplification of the `~~var` pattern.
818 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
819 */
820
David Brazdila06d66a2015-05-28 11:14:54 +0100821 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
822 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
823 /// CHECK-DAG: <<ConstF1:j\d+>> LongConstant -1
824 /// CHECK-DAG: <<Xor1:j\d+>> Xor [<<Arg>>,<<ConstF1>>]
825 /// CHECK-DAG: <<Xor2:j\d+>> Xor [<<Xor1>>,<<ConstF1>>]
826 /// CHECK-DAG: Return [<<Xor2>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100827
David Brazdila06d66a2015-05-28 11:14:54 +0100828 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
829 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
830 /// CHECK-DAG: Return [<<Arg>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100831
David Brazdila06d66a2015-05-28 11:14:54 +0100832 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
833 /// CHECK-NOT: Xor
Alexandre Rames188d4312015-04-09 18:30:21 +0100834
835 public static long NotNot1(long arg) {
836 return ~~arg;
837 }
838
David Brazdila06d66a2015-05-28 11:14:54 +0100839 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
840 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
841 /// CHECK-DAG: <<ConstF1:i\d+>> IntConstant -1
842 /// CHECK-DAG: <<Xor1:i\d+>> Xor [<<Arg>>,<<ConstF1>>]
843 /// CHECK-DAG: <<Xor2:i\d+>> Xor [<<Xor1>>,<<ConstF1>>]
844 /// CHECK-DAG: <<Add:i\d+>> Add [<<Xor1>>,<<Xor2>>]
845 /// CHECK-DAG: Return [<<Add>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100846
David Brazdila06d66a2015-05-28 11:14:54 +0100847 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
848 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
849 /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>]
850 /// CHECK-DAG: <<Add:i\d+>> Add [<<Not>>,<<Arg>>]
851 /// CHECK-DAG: Return [<<Add>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100852
David Brazdila06d66a2015-05-28 11:14:54 +0100853 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
854 /// CHECK-NOT: Xor
Alexandre Rames188d4312015-04-09 18:30:21 +0100855
856 public static int NotNot2(int arg) {
857 int temp = ~arg;
858 return temp + ~temp;
859 }
860
861 /**
862 * Test the simplification of a subtraction with a negated argument.
863 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
864 */
865
David Brazdila06d66a2015-05-28 11:14:54 +0100866 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
867 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
868 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
869 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
870 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Neg>>,<<Arg2>>]
871 /// CHECK-DAG: Return [<<Sub>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100872
David Brazdila06d66a2015-05-28 11:14:54 +0100873 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
874 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
875 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
876 /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>]
877 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>]
878 /// CHECK-DAG: Return [<<Neg>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100879
David Brazdila06d66a2015-05-28 11:14:54 +0100880 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
881 /// CHECK-NOT: Sub
Alexandre Rames188d4312015-04-09 18:30:21 +0100882
883 public static int SubNeg1(int arg1, int arg2) {
884 return -arg1 - arg2;
885 }
886
887 /**
888 * This is similar to the test-case SubNeg1, but the negation has
889 * multiple uses.
890 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
891 * The current code won't perform the previous optimization. The
892 * transformations do not look at other uses of their inputs. As they don't
893 * know what will happen with other uses, they do not take the risk of
894 * increasing the register pressure by creating or extending live ranges.
895 */
896
David Brazdila06d66a2015-05-28 11:14:54 +0100897 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
898 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
899 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
900 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
901 /// CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>]
902 /// CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>]
903 /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>]
904 /// CHECK-DAG: Return [<<Or>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100905
David Brazdila06d66a2015-05-28 11:14:54 +0100906 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
907 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue
908 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue
909 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>]
910 /// CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>]
911 /// CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>]
912 /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>]
913 /// CHECK-DAG: Return [<<Or>>]
Alexandre Rames188d4312015-04-09 18:30:21 +0100914
David Brazdila06d66a2015-05-28 11:14:54 +0100915 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
916 /// CHECK-NOT: Add
Alexandre Rames188d4312015-04-09 18:30:21 +0100917
918 public static int SubNeg2(int arg1, int arg2) {
919 int temp = -arg1;
920 return (temp - arg2) | (temp - arg2);
921 }
922
923 /**
924 * This follows test-cases SubNeg1 and SubNeg2.
925 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
926 * The optimization should not happen if it moves an additional instruction in
927 * the loop.
928 */
929
David Brazdila06d66a2015-05-28 11:14:54 +0100930 /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
931 // -------------- Arguments and initial negation operation.
932 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
933 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
934 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
935 /// CHECK: Goto
936 // -------------- Loop
937 /// CHECK: SuspendCheck
938 /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>]
939 /// CHECK: Goto
Alexandre Rames188d4312015-04-09 18:30:21 +0100940
David Brazdila06d66a2015-05-28 11:14:54 +0100941 /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
942 // -------------- Arguments and initial negation operation.
943 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue
944 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue
945 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>]
946 /// CHECK-DAG: Goto
947 // -------------- Loop
948 /// CHECK: SuspendCheck
949 /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>]
950 /// CHECK-NOT: Neg
951 /// CHECK: Goto
Alexandre Rames188d4312015-04-09 18:30:21 +0100952
953 public static long SubNeg3(long arg1, long arg2) {
954 long res = 0;
955 long temp = -arg1;
956 for (long i = 0; i < 1; i++) {
957 res += temp - arg2 - i;
958 }
959 return res;
960 }
961
David Brazdila06d66a2015-05-28 11:14:54 +0100962 /// CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before)
963 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
964 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
965 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Arg>>,<<Const1>>]
966 /// CHECK-DAG: If [<<Cond>>]
David Brazdil0d13fee2015-04-17 14:52:19 +0100967
David Brazdila06d66a2015-05-28 11:14:54 +0100968 /// CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after)
969 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
970 /// CHECK-DAG: If [<<Arg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +0100971
972 public static int EqualTrueRhs(boolean arg) {
973 return (arg != true) ? 3 : 5;
974 }
975
David Brazdila06d66a2015-05-28 11:14:54 +0100976 /// CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before)
977 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
978 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
979 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Const1>>,<<Arg>>]
980 /// CHECK-DAG: If [<<Cond>>]
David Brazdil0d13fee2015-04-17 14:52:19 +0100981
David Brazdila06d66a2015-05-28 11:14:54 +0100982 /// CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after)
983 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
984 /// CHECK-DAG: If [<<Arg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +0100985
986 public static int EqualTrueLhs(boolean arg) {
987 return (true != arg) ? 3 : 5;
988 }
989
David Brazdila06d66a2015-05-28 11:14:54 +0100990 /// CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (before)
991 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
992 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
993 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Arg>>,<<Const0>>]
994 /// CHECK-DAG: If [<<Cond>>]
David Brazdil0d13fee2015-04-17 14:52:19 +0100995
David Brazdila06d66a2015-05-28 11:14:54 +0100996 /// CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (after)
997 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
998 /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
999 /// CHECK-DAG: If [<<NotArg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001000
1001 public static int EqualFalseRhs(boolean arg) {
1002 return (arg != false) ? 3 : 5;
1003 }
1004
David Brazdila06d66a2015-05-28 11:14:54 +01001005 /// CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before)
1006 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1007 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1008 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<Const0>>,<<Arg>>]
1009 /// CHECK-DAG: If [<<Cond>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001010
David Brazdila06d66a2015-05-28 11:14:54 +01001011 /// CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (after)
1012 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1013 /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
1014 /// CHECK-DAG: If [<<NotArg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001015
1016 public static int EqualFalseLhs(boolean arg) {
1017 return (false != arg) ? 3 : 5;
1018 }
1019
David Brazdila06d66a2015-05-28 11:14:54 +01001020 /// CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (before)
1021 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1022 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1023 /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Arg>>,<<Const1>>]
1024 /// CHECK-DAG: If [<<Cond>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001025
David Brazdila06d66a2015-05-28 11:14:54 +01001026 /// CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (after)
1027 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1028 /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
1029 /// CHECK-DAG: If [<<NotArg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001030
1031 public static int NotEqualTrueRhs(boolean arg) {
1032 return (arg == true) ? 3 : 5;
1033 }
1034
David Brazdila06d66a2015-05-28 11:14:54 +01001035 /// CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before)
1036 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1037 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1038 /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Const1>>,<<Arg>>]
1039 /// CHECK-DAG: If [<<Cond>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001040
David Brazdila06d66a2015-05-28 11:14:54 +01001041 /// CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after)
1042 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1043 /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
1044 /// CHECK-DAG: If [<<NotArg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001045
1046 public static int NotEqualTrueLhs(boolean arg) {
1047 return (true == arg) ? 3 : 5;
1048 }
1049
David Brazdila06d66a2015-05-28 11:14:54 +01001050 /// CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before)
1051 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1052 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1053 /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Arg>>,<<Const0>>]
1054 /// CHECK-DAG: If [<<Cond>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001055
David Brazdila06d66a2015-05-28 11:14:54 +01001056 /// CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after)
1057 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1058 /// CHECK-DAG: If [<<Arg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001059
1060 public static int NotEqualFalseRhs(boolean arg) {
1061 return (arg == false) ? 3 : 5;
1062 }
1063
David Brazdila06d66a2015-05-28 11:14:54 +01001064 /// CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before)
1065 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1066 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1067 /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<Const0>>,<<Arg>>]
1068 /// CHECK-DAG: If [<<Cond>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001069
David Brazdila06d66a2015-05-28 11:14:54 +01001070 /// CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after)
1071 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1072 /// CHECK-DAG: If [<<Arg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001073
1074 public static int NotEqualFalseLhs(boolean arg) {
1075 return (false == arg) ? 3 : 5;
1076 }
1077
David Brazdil1e9ec052015-06-22 10:26:45 +01001078 /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before)
1079 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1080 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
1081 /// CHECK-DAG: <<BoolNot:z\d+>> BooleanNot [<<Arg>>]
1082 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<BoolNot>>,<<Const2>>]
1083 /// CHECK-DAG: Return [<<Cond>>]
1084
1085 /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after)
1086 /// CHECK-DAG: <<False:i\d+>> IntConstant 0
1087 /// CHECK-DAG: Return [<<False>>]
1088
1089 public static boolean EqualBoolVsIntConst(boolean arg) {
1090 return (arg ? 0 : 1) == 2;
1091 }
1092
1093 /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before)
1094 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1095 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
1096 /// CHECK-DAG: <<BoolNot:z\d+>> BooleanNot [<<Arg>>]
1097 /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<BoolNot>>,<<Const2>>]
1098 /// CHECK-DAG: Return [<<Cond>>]
1099
1100 /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after)
1101 /// CHECK-DAG: <<True:i\d+>> IntConstant 1
1102 /// CHECK-DAG: Return [<<True>>]
1103
1104 public static boolean NotEqualBoolVsIntConst(boolean arg) {
1105 return (arg ? 0 : 1) != 2;
1106 }
1107
David Brazdil0d13fee2015-04-17 14:52:19 +01001108 /*
1109 * Test simplification of double Boolean negation. Note that sometimes
1110 * both negations can be removed but we only expect the simplifier to
1111 * remove the second.
1112 */
1113
Nicolas Geoffrayb2bdfce2015-06-18 15:46:47 +01001114 /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (before)
David Brazdila06d66a2015-05-28 11:14:54 +01001115 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1116 /// CHECK-DAG: <<NotArg:z\d+>> BooleanNot [<<Arg>>]
1117 /// CHECK-DAG: <<NotNotArg:z\d+>> BooleanNot [<<NotArg>>]
1118 /// CHECK-DAG: Return [<<NotNotArg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001119
Nicolas Geoffrayb2bdfce2015-06-18 15:46:47 +01001120 /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001121 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue
1122 /// CHECK-DAG: BooleanNot [<<Arg>>]
1123 /// CHECK-DAG: Return [<<Arg>>]
David Brazdil0d13fee2015-04-17 14:52:19 +01001124
Nicolas Geoffrayb2bdfce2015-06-18 15:46:47 +01001125 /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (after)
David Brazdila06d66a2015-05-28 11:14:54 +01001126 /// CHECK: BooleanNot
1127 /// CHECK-NOT: BooleanNot
David Brazdil0d13fee2015-04-17 14:52:19 +01001128
David Brazdil769c9e52015-04-27 13:54:09 +01001129 public static boolean NegateValue(boolean arg) {
1130 return !arg;
1131 }
1132
David Brazdil0d13fee2015-04-17 14:52:19 +01001133 public static boolean NotNotBool(boolean arg) {
David Brazdil769c9e52015-04-27 13:54:09 +01001134 return !(NegateValue(arg));
David Brazdil0d13fee2015-04-17 14:52:19 +01001135 }
1136
David Brazdila06d66a2015-05-28 11:14:54 +01001137 /// CHECK-START: float Main.Div2(float) instruction_simplifier (before)
1138 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1139 /// CHECK-DAG: <<Const2:f\d+>> FloatConstant 2
1140 /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<Const2>>]
1141 /// CHECK-DAG: Return [<<Div>>]
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001142
David Brazdila06d66a2015-05-28 11:14:54 +01001143 /// CHECK-START: float Main.Div2(float) instruction_simplifier (after)
1144 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1145 /// CHECK-DAG: <<ConstP5:f\d+>> FloatConstant 0.5
1146 /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstP5>>]
1147 /// CHECK-DAG: Return [<<Mul>>]
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001148
David Brazdila06d66a2015-05-28 11:14:54 +01001149 /// CHECK-START: float Main.Div2(float) instruction_simplifier (after)
1150 /// CHECK-NOT: Div
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001151
1152 public static float Div2(float arg) {
1153 return arg / 2.0f;
1154 }
1155
David Brazdila06d66a2015-05-28 11:14:54 +01001156 /// CHECK-START: double Main.Div2(double) instruction_simplifier (before)
1157 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1158 /// CHECK-DAG: <<Const2:d\d+>> DoubleConstant 2
1159 /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<Const2>>]
1160 /// CHECK-DAG: Return [<<Div>>]
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001161
David Brazdila06d66a2015-05-28 11:14:54 +01001162 /// CHECK-START: double Main.Div2(double) instruction_simplifier (after)
1163 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1164 /// CHECK-DAG: <<ConstP5:d\d+>> DoubleConstant 0.5
1165 /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstP5>>]
1166 /// CHECK-DAG: Return [<<Mul>>]
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001167
David Brazdila06d66a2015-05-28 11:14:54 +01001168 /// CHECK-START: double Main.Div2(double) instruction_simplifier (after)
1169 /// CHECK-NOT: Div
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001170 public static double Div2(double arg) {
1171 return arg / 2.0;
1172 }
1173
David Brazdila06d66a2015-05-28 11:14:54 +01001174 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (before)
1175 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1176 /// CHECK-DAG: <<ConstMP25:f\d+>> FloatConstant -0.25
1177 /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<ConstMP25>>]
1178 /// CHECK-DAG: Return [<<Div>>]
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001179
David Brazdila06d66a2015-05-28 11:14:54 +01001180 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
1181 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue
1182 /// CHECK-DAG: <<ConstM4:f\d+>> FloatConstant -4
1183 /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstM4>>]
1184 /// CHECK-DAG: Return [<<Mul>>]
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001185
David Brazdila06d66a2015-05-28 11:14:54 +01001186 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
1187 /// CHECK-NOT: Div
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001188
1189 public static float DivMP25(float arg) {
1190 return arg / -0.25f;
1191 }
1192
David Brazdila06d66a2015-05-28 11:14:54 +01001193 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (before)
1194 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1195 /// CHECK-DAG: <<ConstMP25:d\d+>> DoubleConstant -0.25
1196 /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<ConstMP25>>]
1197 /// CHECK-DAG: Return [<<Div>>]
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001198
David Brazdila06d66a2015-05-28 11:14:54 +01001199 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1200 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue
1201 /// CHECK-DAG: <<ConstM4:d\d+>> DoubleConstant -4
1202 /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstM4>>]
1203 /// CHECK-DAG: Return [<<Mul>>]
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001204
David Brazdila06d66a2015-05-28 11:14:54 +01001205 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1206 /// CHECK-NOT: Div
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001207 public static double DivMP25(double arg) {
1208 return arg / -0.25f;
1209 }
1210
Alexandre Rames38db7852015-11-20 15:02:45 +00001211 /**
1212 * Test strength reduction of factors of the form (2^n + 1).
1213 */
1214
1215 /// CHECK-START: int Main.mulPow2Plus1(int) instruction_simplifier (before)
1216 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1217 /// CHECK-DAG: <<Const9:i\d+>> IntConstant 9
1218 /// CHECK: Mul [<<Arg>>,<<Const9>>]
1219
1220 /// CHECK-START: int Main.mulPow2Plus1(int) instruction_simplifier (after)
1221 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1222 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
1223 /// CHECK: <<Shift:i\d+>> Shl [<<Arg>>,<<Const3>>]
1224 /// CHECK-NEXT: Add [<<Arg>>,<<Shift>>]
1225
1226 public static int mulPow2Plus1(int arg) {
1227 return arg * 9;
1228 }
1229
Alexandre Rames38db7852015-11-20 15:02:45 +00001230 /**
1231 * Test strength reduction of factors of the form (2^n - 1).
1232 */
1233
1234 /// CHECK-START: long Main.mulPow2Minus1(long) instruction_simplifier (before)
1235 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1236 /// CHECK-DAG: <<Const31:j\d+>> LongConstant 31
1237 /// CHECK: Mul [<<Arg>>,<<Const31>>]
1238
1239 /// CHECK-START: long Main.mulPow2Minus1(long) instruction_simplifier (after)
1240 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue
1241 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
1242 /// CHECK: <<Shift:j\d+>> Shl [<<Arg>>,<<Const5>>]
1243 /// CHECK-NEXT: Sub [<<Shift>>,<<Arg>>]
1244
1245 public static long mulPow2Minus1(long arg) {
1246 return arg * 31;
1247 }
1248
Mark Mendellf6529172015-11-17 11:16:56 -05001249 /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier (before)
1250 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1251 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet
1252 /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<Field>>,<<Const1>>]
1253 /// CHECK-DAG: If [<<NE>>]
1254
1255 /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier (after)
1256 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet
1257 /// CHECK-DAG: <<Not:z\d+>> BooleanNot [<<Field>>]
1258 /// CHECK-DAG: If [<<Not>>]
1259
1260 public static int booleanFieldNotEqualOne() {
1261 return (booleanField == true) ? 13 : 54;
1262 }
1263
1264 /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier (before)
1265 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1266 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet
1267 /// CHECK-DAG: <<EQ:z\d+>> Equal [<<Field>>,<<Const0>>]
1268 /// CHECK-DAG: If [<<EQ>>]
1269
1270 /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier (after)
1271 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet
1272 /// CHECK-DAG: <<Not:z\d+>> BooleanNot [<<Field>>]
1273 /// CHECK-DAG: If [<<Not>>]
1274
1275 public static int booleanFieldEqualZero() {
1276 return (booleanField != false) ? 13 : 54;
1277 }
1278
1279 /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (before)
1280 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1281 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1282 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1283 /// CHECK-DAG: <<GT:z\d+>> GreaterThan [<<Arg>>,<<Const42>>]
1284 /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<GT>>,<<Const1>>]
1285 /// CHECK-DAG: If [<<NE>>]
1286
1287 /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (after)
1288 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1289 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1290 /// CHECK-DAG: If [<<LE:z\d+>>]
1291 /// CHECK-DAG: <<LE>> LessThanOrEqual [<<Arg>>,<<Const42>>]
1292 // Note that we match `LE` from If because there are two identical LessThanOrEqual instructions.
1293
1294 public static int intConditionNotEqualOne(int i) {
1295 return ((i > 42) == true) ? 13 : 54;
1296 }
1297
1298 /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (before)
1299 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1300 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1301 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1302 /// CHECK-DAG: <<GT:z\d+>> GreaterThan [<<Arg>>,<<Const42>>]
1303 /// CHECK-DAG: <<EQ:z\d+>> Equal [<<GT>>,<<Const0>>]
1304 /// CHECK-DAG: If [<<EQ>>]
1305
1306 /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (after)
1307 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue
1308 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
1309 /// CHECK-DAG: If [<<LE:z\d+>>]
1310 /// CHECK-DAG: <<LE>> LessThanOrEqual [<<Arg>>,<<Const42>>]
1311 // Note that we match `LE` from If because there are two identical LessThanOrEqual instructions.
1312
1313 public static int intConditionEqualZero(int i) {
1314 return ((i > 42) != false) ? 13 : 54;
1315 }
1316
1317 // Test that conditions on float/double are not flipped.
1318
1319 /// CHECK-START: int Main.floatConditionNotEqualOne(float) register (before)
1320 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1321 /// CHECK-DAG: NotEqual [{{i\d+}},<<Const1>>]
1322
1323 public static int floatConditionNotEqualOne(float f) {
1324 return ((f > 42.0f) == true) ? 13 : 54;
1325 }
1326
1327 /// CHECK-START: int Main.doubleConditionEqualZero(double) register (before)
1328 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1329 /// CHECK-DAG: Equal [{{i\d+}},<<Const0>>]
1330
1331 public static int doubleConditionEqualZero(double d) {
1332 return ((d > 42.0) != false) ? 13 : 54;
1333 }
Alexandre Rames38db7852015-11-20 15:02:45 +00001334
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001335 public static void main(String[] args) {
1336 int arg = 123456;
1337
1338 assertLongEquals(Add0(arg), arg);
1339 assertIntEquals(AndAllOnes(arg), arg);
1340 assertLongEquals(Div1(arg), arg);
1341 assertIntEquals(DivN1(arg), -arg);
1342 assertLongEquals(Mul1(arg), arg);
1343 assertIntEquals(MulN1(arg), -arg);
1344 assertLongEquals(MulPowerOfTwo128(arg), (128 * arg));
1345 assertIntEquals(Or0(arg), arg);
1346 assertLongEquals(OrSame(arg), arg);
1347 assertIntEquals(Shl0(arg), arg);
1348 assertLongEquals(Shr0(arg), arg);
1349 assertLongEquals(Sub0(arg), arg);
1350 assertIntEquals(SubAliasNeg(arg), -arg);
1351 assertLongEquals(UShr0(arg), arg);
1352 assertIntEquals(Xor0(arg), arg);
1353 assertIntEquals(XorAllOnes(arg), ~arg);
Alexandre Rames188d4312015-04-09 18:30:21 +01001354 assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1));
1355 assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1));
1356 assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1));
1357 assertLongEquals(AddNeg1(arg, arg + 1), 1);
1358 assertLongEquals(AddNeg2(arg, arg + 1), -1);
1359 assertLongEquals(NegNeg1(arg), arg);
1360 assertIntEquals(NegNeg2(arg), 0);
1361 assertLongEquals(NegNeg3(arg), arg);
1362 assertIntEquals(NegSub1(arg, arg + 1), 1);
1363 assertIntEquals(NegSub2(arg, arg + 1), 1);
1364 assertLongEquals(NotNot1(arg), arg);
1365 assertIntEquals(NotNot2(arg), -1);
1366 assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1));
1367 assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1));
1368 assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1));
David Brazdil0d13fee2015-04-17 14:52:19 +01001369 assertIntEquals(EqualTrueRhs(true), 5);
1370 assertIntEquals(EqualTrueLhs(true), 5);
1371 assertIntEquals(EqualFalseRhs(true), 3);
1372 assertIntEquals(EqualFalseLhs(true), 3);
1373 assertIntEquals(NotEqualTrueRhs(true), 3);
1374 assertIntEquals(NotEqualTrueLhs(true), 3);
1375 assertIntEquals(NotEqualFalseRhs(true), 5);
1376 assertIntEquals(NotEqualFalseLhs(true), 5);
1377 assertBooleanEquals(NotNotBool(true), true);
1378 assertBooleanEquals(NotNotBool(false), false);
Nicolas Geoffray0d221842015-04-27 08:53:46 +00001379 assertFloatEquals(Div2(100.0f), 50.0f);
1380 assertDoubleEquals(Div2(150.0), 75.0);
1381 assertFloatEquals(DivMP25(100.0f), -400.0f);
1382 assertDoubleEquals(DivMP25(150.0), -600.0);
Vladimir Marko452c1b62015-09-25 14:44:17 +01001383 assertIntEquals(UShr28And15(0xc1234567), 0xc);
1384 assertLongEquals(UShr60And15(0xc123456787654321L), 0xcL);
1385 assertIntEquals(UShr28And7(0xc1234567), 0x4);
1386 assertLongEquals(UShr60And7(0xc123456787654321L), 0x4L);
1387 assertIntEquals(Shr24And255(0xc1234567), 0xc1);
1388 assertLongEquals(Shr56And255(0xc123456787654321L), 0xc1L);
1389 assertIntEquals(Shr24And127(0xc1234567), 0x41);
1390 assertLongEquals(Shr56And127(0xc123456787654321L), 0x41L);
Alexandre Rames38db7852015-11-20 15:02:45 +00001391 assertIntEquals(0, mulPow2Plus1(0));
1392 assertIntEquals(9, mulPow2Plus1(1));
1393 assertIntEquals(18, mulPow2Plus1(2));
1394 assertIntEquals(900, mulPow2Plus1(100));
1395 assertIntEquals(111105, mulPow2Plus1(12345));
1396 assertLongEquals(0, mulPow2Minus1(0));
1397 assertLongEquals(31, mulPow2Minus1(1));
1398 assertLongEquals(62, mulPow2Minus1(2));
1399 assertLongEquals(3100, mulPow2Minus1(100));
1400 assertLongEquals(382695, mulPow2Minus1(12345));
Mark Mendellf6529172015-11-17 11:16:56 -05001401
1402 booleanField = false;
1403 assertIntEquals(booleanFieldNotEqualOne(), 54);
1404 assertIntEquals(booleanFieldEqualZero(), 54);
1405 booleanField = true;
1406 assertIntEquals(booleanFieldNotEqualOne(), 13);
1407 assertIntEquals(booleanFieldEqualZero(), 13);
1408 assertIntEquals(intConditionNotEqualOne(6), 54);
1409 assertIntEquals(intConditionNotEqualOne(43), 13);
1410 assertIntEquals(intConditionEqualZero(6), 54);
1411 assertIntEquals(intConditionEqualZero(43), 13);
1412 assertIntEquals(floatConditionNotEqualOne(6.0f), 54);
1413 assertIntEquals(floatConditionNotEqualOne(43.0f), 13);
1414 assertIntEquals(doubleConditionEqualZero(6.0), 54);
1415 assertIntEquals(doubleConditionEqualZero(43.0), 13);
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001416 }
Mark Mendellf6529172015-11-17 11:16:56 -05001417
1418 public static boolean booleanField;
Alexandre Ramesb2fd7bc2015-03-11 16:48:16 +00001419}