1 /*
2  * 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  */
16 
17 import java.lang.reflect.Method;
18 
19 public class Main {
20 
assertBooleanEquals(boolean expected, boolean result)21   public static void assertBooleanEquals(boolean expected, boolean result) {
22     if (expected != result) {
23       throw new Error("Expected: " + expected + ", found: " + result);
24     }
25   }
26 
assertIntEquals(int expected, int result)27   public static void assertIntEquals(int expected, int result) {
28     if (expected != result) {
29       throw new Error("Expected: " + expected + ", found: " + result);
30     }
31   }
32 
assertLongEquals(long expected, long result)33   public static void assertLongEquals(long expected, long result) {
34     if (expected != result) {
35       throw new Error("Expected: " + expected + ", found: " + result);
36     }
37   }
38 
assertFloatEquals(float expected, float result)39   public static void assertFloatEquals(float expected, float result) {
40     if (expected != result) {
41       throw new Error("Expected: " + expected + ", found: " + result);
42     }
43   }
44 
assertDoubleEquals(double expected, double result)45   public static void assertDoubleEquals(double expected, double result) {
46     if (expected != result) {
47       throw new Error("Expected: " + expected + ", found: " + result);
48     }
49   }
50 
assertStringEquals(String expected, String result)51   public static void assertStringEquals(String expected, String result) {
52     if (expected == null ? result != null : !expected.equals(result)) {
53       throw new Error("Expected: " + expected + ", found: " + result);
54     }
55   }
56 
57   /**
58    * Tiny programs exercising optimizations of arithmetic identities.
59    */
60 
61   /// CHECK-START: long Main.$noinline$Add0(long) instruction_simplifier (before)
62   /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
63   /// CHECK-DAG:     <<Const0:j\d+>>  LongConstant 0
64   /// CHECK-DAG:     <<Add:j\d+>>     Add [<<Const0>>,<<Arg>>]
65   /// CHECK-DAG:                      Return [<<Add>>]
66 
67   /// CHECK-START: long Main.$noinline$Add0(long) instruction_simplifier (after)
68   /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
69   /// CHECK-DAG:                      Return [<<Arg>>]
70 
71   /// CHECK-START: long Main.$noinline$Add0(long) instruction_simplifier (after)
72   /// CHECK-NOT:                        Add
73 
$noinline$Add0(long arg)74   public static long $noinline$Add0(long arg) {
75     return 0 + arg;
76   }
77 
78   /// CHECK-START: int Main.$noinline$AddAddSubAddConst(int) instruction_simplifier (before)
79   /// CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
80   /// CHECK-DAG:     <<Const1:i\d+>>    IntConstant 1
81   /// CHECK-DAG:     <<Const2:i\d+>>    IntConstant 2
82   /// CHECK-DAG:     <<ConstM3:i\d+>>   IntConstant -3
83   /// CHECK-DAG:     <<Const4:i\d+>>    IntConstant 4
84   /// CHECK-DAG:     <<Add1:i\d+>>      Add [<<ArgValue>>,<<Const1>>]
85   /// CHECK-DAG:     <<Add2:i\d+>>      Add [<<Add1>>,<<Const2>>]
86   /// CHECK-DAG:     <<Add3:i\d+>>      Add [<<Add2>>,<<ConstM3>>]
87   /// CHECK-DAG:     <<Add4:i\d+>>      Add [<<Add3>>,<<Const4>>]
88   /// CHECK-DAG:                        Return [<<Add4>>]
89 
90   /// CHECK-START: int Main.$noinline$AddAddSubAddConst(int) instruction_simplifier (after)
91   /// CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
92   /// CHECK-DAG:     <<Const4:i\d+>>    IntConstant 4
93   /// CHECK-DAG:     <<Add:i\d+>>       Add [<<ArgValue>>,<<Const4>>]
94   /// CHECK-DAG:                        Return [<<Add>>]
95 
$noinline$AddAddSubAddConst(int arg)96   public static int $noinline$AddAddSubAddConst(int arg) {
97     return arg + 1 + 2 - 3 + 4;
98   }
99 
100   /// CHECK-START: int Main.$noinline$AndAllOnes(int) instruction_simplifier (before)
101   /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
102   /// CHECK-DAG:     <<ConstF:i\d+>>  IntConstant -1
103   /// CHECK-DAG:     <<And:i\d+>>     And [<<Arg>>,<<ConstF>>]
104   /// CHECK-DAG:                      Return [<<And>>]
105 
106   /// CHECK-START: int Main.$noinline$AndAllOnes(int) instruction_simplifier (after)
107   /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
108   /// CHECK-DAG:                      Return [<<Arg>>]
109 
110   /// CHECK-START: int Main.$noinline$AndAllOnes(int) instruction_simplifier (after)
111   /// CHECK-NOT:                      And
112 
$noinline$AndAllOnes(int arg)113   public static int $noinline$AndAllOnes(int arg) {
114     return arg & -1;
115   }
116 
117   /// CHECK-START: int Main.$noinline$UShr28And15(int) instruction_simplifier (before)
118   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
119   /// CHECK-DAG:     <<Const28:i\d+>>  IntConstant 28
120   /// CHECK-DAG:     <<Const15:i\d+>>  IntConstant 15
121   /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<Arg>>,<<Const28>>]
122   /// CHECK-DAG:     <<And:i\d+>>      And [<<UShr>>,<<Const15>>]
123   /// CHECK-DAG:                       Return [<<And>>]
124 
125   /// CHECK-START: int Main.$noinline$UShr28And15(int) instruction_simplifier (after)
126   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
127   /// CHECK-DAG:     <<Const28:i\d+>>  IntConstant 28
128   /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<Arg>>,<<Const28>>]
129   /// CHECK-DAG:                       Return [<<UShr>>]
130 
131   /// CHECK-START: int Main.$noinline$UShr28And15(int) instruction_simplifier (after)
132   /// CHECK-NOT:                       And
133 
$noinline$UShr28And15(int arg)134   public static int $noinline$UShr28And15(int arg) {
135     return (arg >>> 28) & 15;
136   }
137 
138   /// CHECK-START: long Main.$noinline$UShr60And15(long) instruction_simplifier (before)
139   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
140   /// CHECK-DAG:     <<Const60:i\d+>>  IntConstant 60
141   /// CHECK-DAG:     <<Const15:j\d+>>  LongConstant 15
142   /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<Arg>>,<<Const60>>]
143   /// CHECK-DAG:     <<And:j\d+>>      And [<<UShr>>,<<Const15>>]
144   /// CHECK-DAG:                       Return [<<And>>]
145 
146   /// CHECK-START: long Main.$noinline$UShr60And15(long) instruction_simplifier (after)
147   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
148   /// CHECK-DAG:     <<Const60:i\d+>>  IntConstant 60
149   /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<Arg>>,<<Const60>>]
150   /// CHECK-DAG:                       Return [<<UShr>>]
151 
152   /// CHECK-START: long Main.$noinline$UShr60And15(long) instruction_simplifier (after)
153   /// CHECK-NOT:                       And
154 
$noinline$UShr60And15(long arg)155   public static long $noinline$UShr60And15(long arg) {
156     return (arg >>> 60) & 15;
157   }
158 
159   /// CHECK-START: int Main.$noinline$UShr28And7(int) instruction_simplifier (before)
160   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
161   /// CHECK-DAG:     <<Const28:i\d+>>  IntConstant 28
162   /// CHECK-DAG:     <<Const7:i\d+>>   IntConstant 7
163   /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<Arg>>,<<Const28>>]
164   /// CHECK-DAG:     <<And:i\d+>>      And [<<UShr>>,<<Const7>>]
165   /// CHECK-DAG:                       Return [<<And>>]
166 
167   /// CHECK-START: int Main.$noinline$UShr28And7(int) instruction_simplifier (after)
168   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
169   /// CHECK-DAG:     <<Const28:i\d+>>  IntConstant 28
170   /// CHECK-DAG:     <<Const7:i\d+>>   IntConstant 7
171   /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<Arg>>,<<Const28>>]
172   /// CHECK-DAG:     <<And:i\d+>>      And [<<UShr>>,<<Const7>>]
173   /// CHECK-DAG:                       Return [<<And>>]
174 
$noinline$UShr28And7(int arg)175   public static int $noinline$UShr28And7(int arg) {
176     return (arg >>> 28) & 7;
177   }
178 
179   /// CHECK-START: long Main.$noinline$UShr60And7(long) instruction_simplifier (before)
180   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
181   /// CHECK-DAG:     <<Const60:i\d+>>  IntConstant 60
182   /// CHECK-DAG:     <<Const7:j\d+>>   LongConstant 7
183   /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<Arg>>,<<Const60>>]
184   /// CHECK-DAG:     <<And:j\d+>>      And [<<UShr>>,<<Const7>>]
185   /// CHECK-DAG:                       Return [<<And>>]
186 
187   /// CHECK-START: long Main.$noinline$UShr60And7(long) instruction_simplifier (after)
188   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
189   /// CHECK-DAG:     <<Const60:i\d+>>  IntConstant 60
190   /// CHECK-DAG:     <<Const7:j\d+>>   LongConstant 7
191   /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<Arg>>,<<Const60>>]
192   /// CHECK-DAG:     <<And:j\d+>>      And [<<UShr>>,<<Const7>>]
193   /// CHECK-DAG:                       Return [<<And>>]
194 
$noinline$UShr60And7(long arg)195   public static long $noinline$UShr60And7(long arg) {
196     return (arg >>> 60) & 7;
197   }
198 
199   /// CHECK-START: int Main.$noinline$Shr24And255(int) instruction_simplifier (before)
200   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
201   /// CHECK-DAG:     <<Const24:i\d+>>  IntConstant 24
202   /// CHECK-DAG:     <<Const255:i\d+>> IntConstant 255
203   /// CHECK-DAG:     <<Shr:i\d+>>      Shr [<<Arg>>,<<Const24>>]
204   /// CHECK-DAG:     <<And:i\d+>>      And [<<Shr>>,<<Const255>>]
205   /// CHECK-DAG:                       Return [<<And>>]
206 
207   /// CHECK-START: int Main.$noinline$Shr24And255(int) instruction_simplifier (after)
208   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
209   /// CHECK-DAG:     <<Const24:i\d+>>  IntConstant 24
210   /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<Arg>>,<<Const24>>]
211   /// CHECK-DAG:                       Return [<<UShr>>]
212 
213   /// CHECK-START: int Main.$noinline$Shr24And255(int) instruction_simplifier (after)
214   /// CHECK-NOT:                       Shr
215   /// CHECK-NOT:                       And
216 
$noinline$Shr24And255(int arg)217   public static int $noinline$Shr24And255(int arg) {
218     return (arg >> 24) & 255;
219   }
220 
221   /// CHECK-START: int Main.$noinline$Shr25And127(int) instruction_simplifier (before)
222   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
223   /// CHECK-DAG:     <<Const25:i\d+>>  IntConstant 25
224   /// CHECK-DAG:     <<Const127:i\d+>> IntConstant 127
225   /// CHECK-DAG:     <<Shr:i\d+>>      Shr [<<Arg>>,<<Const25>>]
226   /// CHECK-DAG:     <<And:i\d+>>      And [<<Shr>>,<<Const127>>]
227   /// CHECK-DAG:                       Return [<<And>>]
228 
229   /// CHECK-START: int Main.$noinline$Shr25And127(int) instruction_simplifier (after)
230   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
231   /// CHECK-DAG:     <<Const25:i\d+>>  IntConstant 25
232   /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<Arg>>,<<Const25>>]
233   /// CHECK-DAG:                       Return [<<UShr>>]
234 
235   /// CHECK-START: int Main.$noinline$Shr25And127(int) instruction_simplifier (after)
236   /// CHECK-NOT:                       Shr
237   /// CHECK-NOT:                       And
238 
$noinline$Shr25And127(int arg)239   public static int $noinline$Shr25And127(int arg) {
240     return (arg >> 25) & 127;
241   }
242 
243   /// CHECK-START: long Main.$noinline$Shr56And255(long) instruction_simplifier (before)
244   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
245   /// CHECK-DAG:     <<Const56:i\d+>>  IntConstant 56
246   /// CHECK-DAG:     <<Const255:j\d+>> LongConstant 255
247   /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Arg>>,<<Const56>>]
248   /// CHECK-DAG:     <<And:j\d+>>      And [<<Shr>>,<<Const255>>]
249   /// CHECK-DAG:                       Return [<<And>>]
250 
251   /// CHECK-START: long Main.$noinline$Shr56And255(long) instruction_simplifier (after)
252   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
253   /// CHECK-DAG:     <<Const56:i\d+>>  IntConstant 56
254   /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<Arg>>,<<Const56>>]
255   /// CHECK-DAG:                       Return [<<UShr>>]
256 
257   /// CHECK-START: long Main.$noinline$Shr56And255(long) instruction_simplifier (after)
258   /// CHECK-NOT:                       Shr
259   /// CHECK-NOT:                       And
260 
$noinline$Shr56And255(long arg)261   public static long $noinline$Shr56And255(long arg) {
262     return (arg >> 56) & 255;
263   }
264 
265   /// CHECK-START: long Main.$noinline$Shr57And127(long) instruction_simplifier (before)
266   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
267   /// CHECK-DAG:     <<Const57:i\d+>>  IntConstant 57
268   /// CHECK-DAG:     <<Const127:j\d+>> LongConstant 127
269   /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Arg>>,<<Const57>>]
270   /// CHECK-DAG:     <<And:j\d+>>      And [<<Shr>>,<<Const127>>]
271   /// CHECK-DAG:                       Return [<<And>>]
272 
273   /// CHECK-START: long Main.$noinline$Shr57And127(long) instruction_simplifier (after)
274   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
275   /// CHECK-DAG:     <<Const57:i\d+>>  IntConstant 57
276   /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<Arg>>,<<Const57>>]
277   /// CHECK-DAG:                       Return [<<UShr>>]
278 
279   /// CHECK-START: long Main.$noinline$Shr57And127(long) instruction_simplifier (after)
280   /// CHECK-NOT:                       Shr
281   /// CHECK-NOT:                       And
282 
$noinline$Shr57And127(long arg)283   public static long $noinline$Shr57And127(long arg) {
284     return (arg >> 57) & 127;
285   }
286 
287   /// CHECK-START: int Main.$noinline$Shr24And127(int) instruction_simplifier (before)
288   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
289   /// CHECK-DAG:     <<Const24:i\d+>>  IntConstant 24
290   /// CHECK-DAG:     <<Const127:i\d+>> IntConstant 127
291   /// CHECK-DAG:     <<Shr:i\d+>>      Shr [<<Arg>>,<<Const24>>]
292   /// CHECK-DAG:     <<And:i\d+>>      And [<<Shr>>,<<Const127>>]
293   /// CHECK-DAG:                       Return [<<And>>]
294 
295   /// CHECK-START: int Main.$noinline$Shr24And127(int) instruction_simplifier (after)
296   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
297   /// CHECK-DAG:     <<Const24:i\d+>>  IntConstant 24
298   /// CHECK-DAG:     <<Const127:i\d+>> IntConstant 127
299   /// CHECK-DAG:     <<Shr:i\d+>>      Shr [<<Arg>>,<<Const24>>]
300   /// CHECK-DAG:     <<And:i\d+>>      And [<<Shr>>,<<Const127>>]
301   /// CHECK-DAG:                       Return [<<And>>]
302 
$noinline$Shr24And127(int arg)303   public static int $noinline$Shr24And127(int arg) {
304     return (arg >> 24) & 127;
305   }
306 
307   /// CHECK-START: long Main.$noinline$Shr56And127(long) instruction_simplifier (before)
308   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
309   /// CHECK-DAG:     <<Const56:i\d+>>  IntConstant 56
310   /// CHECK-DAG:     <<Const127:j\d+>> LongConstant 127
311   /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Arg>>,<<Const56>>]
312   /// CHECK-DAG:     <<And:j\d+>>      And [<<Shr>>,<<Const127>>]
313   /// CHECK-DAG:                       Return [<<And>>]
314 
315   /// CHECK-START: long Main.$noinline$Shr56And127(long) instruction_simplifier (after)
316   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
317   /// CHECK-DAG:     <<Const56:i\d+>>  IntConstant 56
318   /// CHECK-DAG:     <<Const127:j\d+>> LongConstant 127
319   /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Arg>>,<<Const56>>]
320   /// CHECK-DAG:     <<And:j\d+>>      And [<<Shr>>,<<Const127>>]
321   /// CHECK-DAG:                       Return [<<And>>]
322 
$noinline$Shr56And127(long arg)323   public static long $noinline$Shr56And127(long arg) {
324     return (arg >> 56) & 127;
325   }
326 
327   /// CHECK-START: long Main.$noinline$Div1(long) instruction_simplifier (before)
328   /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
329   /// CHECK-DAG:     <<Const1:j\d+>>  LongConstant 1
330   /// CHECK-DAG:     <<Div:j\d+>>     Div [<<Arg>>,<<Const1>>]
331   /// CHECK-DAG:                      Return [<<Div>>]
332 
333   /// CHECK-START: long Main.$noinline$Div1(long) instruction_simplifier (after)
334   /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
335   /// CHECK-DAG:                      Return [<<Arg>>]
336 
337   /// CHECK-START: long Main.$noinline$Div1(long) instruction_simplifier (after)
338   /// CHECK-NOT:                      Div
339 
$noinline$Div1(long arg)340   public static long $noinline$Div1(long arg) {
341     return arg / 1;
342   }
343 
344   /// CHECK-START: int Main.$noinline$DivN1(int) instruction_simplifier (before)
345   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
346   /// CHECK-DAG:     <<ConstN1:i\d+>>  IntConstant -1
347   /// CHECK-DAG:     <<Div:i\d+>>      Div [<<Arg>>,<<ConstN1>>]
348   /// CHECK-DAG:                       Return [<<Div>>]
349 
350   /// CHECK-START: int Main.$noinline$DivN1(int) instruction_simplifier (after)
351   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
352   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Arg>>]
353   /// CHECK-DAG:                       Return [<<Neg>>]
354 
355   /// CHECK-START: int Main.$noinline$DivN1(int) instruction_simplifier (after)
356   /// CHECK-NOT:                       Div
357 
$noinline$DivN1(int arg)358   public static int $noinline$DivN1(int arg) {
359     return arg / -1;
360   }
361 
362   /// CHECK-START: long Main.$noinline$Mul1(long) instruction_simplifier (before)
363   /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
364   /// CHECK-DAG:     <<Const1:j\d+>>  LongConstant 1
365   /// CHECK-DAG:     <<Mul:j\d+>>     Mul [<<Const1>>,<<Arg>>]
366   /// CHECK-DAG:                      Return [<<Mul>>]
367 
368   /// CHECK-START: long Main.$noinline$Mul1(long) instruction_simplifier (after)
369   /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
370   /// CHECK-DAG:                      Return [<<Arg>>]
371 
372   /// CHECK-START: long Main.$noinline$Mul1(long) instruction_simplifier (after)
373   /// CHECK-NOT:                       Mul
374 
$noinline$Mul1(long arg)375   public static long $noinline$Mul1(long arg) {
376     return arg * 1;
377   }
378 
379   /// CHECK-START: int Main.$noinline$MulN1(int) instruction_simplifier (before)
380   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
381   /// CHECK-DAG:     <<ConstN1:i\d+>>  IntConstant -1
382   /// CHECK-DAG:     <<Mul:i\d+>>      Mul [<<Arg>>,<<ConstN1>>]
383   /// CHECK-DAG:                       Return [<<Mul>>]
384 
385   /// CHECK-START: int Main.$noinline$MulN1(int) instruction_simplifier (after)
386   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
387   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Arg>>]
388   /// CHECK-DAG:                       Return [<<Neg>>]
389 
390   /// CHECK-START: int Main.$noinline$MulN1(int) instruction_simplifier (after)
391   /// CHECK-NOT:                       Mul
392 
$noinline$MulN1(int arg)393   public static int $noinline$MulN1(int arg) {
394     return arg * -1;
395   }
396 
397   /// CHECK-START: long Main.$noinline$MulPowerOfTwo128(long) instruction_simplifier (before)
398   /// CHECK-DAG:     <<Arg:j\d+>>       ParameterValue
399   /// CHECK-DAG:     <<Const128:j\d+>>  LongConstant 128
400   /// CHECK-DAG:     <<Mul:j\d+>>       Mul [<<Const128>>,<<Arg>>]
401   /// CHECK-DAG:                        Return [<<Mul>>]
402 
403   /// CHECK-START: long Main.$noinline$MulPowerOfTwo128(long) instruction_simplifier (after)
404   /// CHECK-DAG:     <<Arg:j\d+>>       ParameterValue
405   /// CHECK-DAG:     <<Const7:i\d+>>    IntConstant 7
406   /// CHECK-DAG:     <<Shl:j\d+>>       Shl [<<Arg>>,<<Const7>>]
407   /// CHECK-DAG:                        Return [<<Shl>>]
408 
409   /// CHECK-START: long Main.$noinline$MulPowerOfTwo128(long) instruction_simplifier (after)
410   /// CHECK-NOT:                        Mul
411 
$noinline$MulPowerOfTwo128(long arg)412   public static long $noinline$MulPowerOfTwo128(long arg) {
413     return arg * 128;
414   }
415 
416   /// CHECK-START: long Main.$noinline$MulMulMulConst(long) instruction_simplifier (before)
417   /// CHECK-DAG:     <<ArgValue:j\d+>>  ParameterValue
418   /// CHECK-DAG:     <<Const10:j\d+>>   LongConstant 10
419   /// CHECK-DAG:     <<Const11:j\d+>>   LongConstant 11
420   /// CHECK-DAG:     <<Const12:j\d+>>   LongConstant 12
421   /// CHECK-DAG:     <<Mul1:j\d+>>      Mul [<<Const10>>,<<ArgValue>>]
422   /// CHECK-DAG:     <<Mul2:j\d+>>      Mul [<<Mul1>>,<<Const11>>]
423   /// CHECK-DAG:     <<Mul3:j\d+>>      Mul [<<Mul2>>,<<Const12>>]
424   /// CHECK-DAG:                        Return [<<Mul3>>]
425 
426   /// CHECK-START: long Main.$noinline$MulMulMulConst(long) instruction_simplifier (after)
427   /// CHECK-DAG:     <<ArgValue:j\d+>>   ParameterValue
428   /// CHECK-DAG:     <<Const1320:j\d+>>  LongConstant 1320
429   /// CHECK-DAG:     <<Mul:j\d+>>        Mul [<<ArgValue>>,<<Const1320>>]
430   /// CHECK-DAG:                         Return [<<Mul>>]
431 
$noinline$MulMulMulConst(long arg)432   public static long $noinline$MulMulMulConst(long arg) {
433     return 10 * arg * 11 * 12;
434   }
435 
436   /// CHECK-START: int Main.$noinline$Or0(int) instruction_simplifier (before)
437   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
438   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
439   /// CHECK-DAG:     <<Or:i\d+>>       Or [<<Arg>>,<<Const0>>]
440   /// CHECK-DAG:                       Return [<<Or>>]
441 
442   /// CHECK-START: int Main.$noinline$Or0(int) instruction_simplifier (after)
443   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
444   /// CHECK-DAG:                       Return [<<Arg>>]
445 
446   /// CHECK-START: int Main.$noinline$Or0(int) instruction_simplifier (after)
447   /// CHECK-NOT:                       Or
448 
$noinline$Or0(int arg)449   public static int $noinline$Or0(int arg) {
450     return arg | 0;
451   }
452 
453   /// CHECK-START: long Main.$noinline$OrSame(long) instruction_simplifier (before)
454   /// CHECK-DAG:     <<Arg:j\d+>>       ParameterValue
455   /// CHECK-DAG:     <<Or:j\d+>>        Or [<<Arg>>,<<Arg>>]
456   /// CHECK-DAG:                        Return [<<Or>>]
457 
458   /// CHECK-START: long Main.$noinline$OrSame(long) instruction_simplifier (after)
459   /// CHECK-DAG:     <<Arg:j\d+>>       ParameterValue
460   /// CHECK-DAG:                        Return [<<Arg>>]
461 
462   /// CHECK-START: long Main.$noinline$OrSame(long) instruction_simplifier (after)
463   /// CHECK-NOT:                        Or
464 
$noinline$OrSame(long arg)465   public static long $noinline$OrSame(long arg) {
466     return arg | arg;
467   }
468 
469   /// CHECK-START: int Main.$noinline$Shl0(int) instruction_simplifier (before)
470   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
471   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
472   /// CHECK-DAG:     <<Shl:i\d+>>      Shl [<<Arg>>,<<Const0>>]
473   /// CHECK-DAG:                       Return [<<Shl>>]
474 
475   /// CHECK-START: int Main.$noinline$Shl0(int) instruction_simplifier (after)
476   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
477   /// CHECK-DAG:                       Return [<<Arg>>]
478 
479   /// CHECK-START: int Main.$noinline$Shl0(int) instruction_simplifier (after)
480   /// CHECK-NOT:                       Shl
481 
$noinline$Shl0(int arg)482   public static int $noinline$Shl0(int arg) {
483     return arg << 0;
484   }
485 
486   /// CHECK-START: long Main.$noinline$Shr0(long) instruction_simplifier (before)
487   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
488   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
489   /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Arg>>,<<Const0>>]
490   /// CHECK-DAG:                       Return [<<Shr>>]
491 
492   /// CHECK-START: long Main.$noinline$Shr0(long) instruction_simplifier (after)
493   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
494   /// CHECK-DAG:                       Return [<<Arg>>]
495 
496   /// CHECK-START: long Main.$noinline$Shr0(long) instruction_simplifier (after)
497   /// CHECK-NOT:                       Shr
498 
$noinline$Shr0(long arg)499   public static long $noinline$Shr0(long arg) {
500     return arg >> 0;
501   }
502 
503   /// CHECK-START: long Main.$noinline$Shr64(long) instruction_simplifier (before)
504   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
505   /// CHECK-DAG:     <<Const64:i\d+>>  IntConstant 64
506   /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Arg>>,<<Const64>>]
507   /// CHECK-DAG:                       Return [<<Shr>>]
508 
509   /// CHECK-START: long Main.$noinline$Shr64(long) instruction_simplifier (after)
510   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
511   /// CHECK-DAG:                       Return [<<Arg>>]
512 
513   /// CHECK-START: long Main.$noinline$Shr64(long) instruction_simplifier (after)
514   /// CHECK-NOT:                       Shr
515 
$noinline$Shr64(long arg)516   public static long $noinline$Shr64(long arg) {
517     return arg >> 64;
518   }
519 
520   /// CHECK-START: long Main.$noinline$Sub0(long) instruction_simplifier (before)
521   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
522   /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
523   /// CHECK-DAG:     <<Sub:j\d+>>      Sub [<<Arg>>,<<Const0>>]
524   /// CHECK-DAG:                       Return [<<Sub>>]
525 
526   /// CHECK-START: long Main.$noinline$Sub0(long) instruction_simplifier (after)
527   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
528   /// CHECK-DAG:                       Return [<<Arg>>]
529 
530   /// CHECK-START: long Main.$noinline$Sub0(long) instruction_simplifier (after)
531   /// CHECK-NOT:                       Sub
532 
$noinline$Sub0(long arg)533   public static long $noinline$Sub0(long arg) {
534     return arg - 0;
535   }
536 
537   /// CHECK-START: int Main.$noinline$SubAliasNeg(int) instruction_simplifier (before)
538   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
539   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
540   /// CHECK-DAG:     <<Sub:i\d+>>      Sub [<<Const0>>,<<Arg>>]
541   /// CHECK-DAG:                       Return [<<Sub>>]
542 
543   /// CHECK-START: int Main.$noinline$SubAliasNeg(int) instruction_simplifier (after)
544   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
545   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Arg>>]
546   /// CHECK-DAG:                       Return [<<Neg>>]
547 
548   /// CHECK-START: int Main.$noinline$SubAliasNeg(int) instruction_simplifier (after)
549   /// CHECK-NOT:                       Sub
550 
$noinline$SubAliasNeg(int arg)551   public static int $noinline$SubAliasNeg(int arg) {
552     return 0 - arg;
553   }
554 
555   /// CHECK-START: int Main.$noinline$SubAddConst1(int) instruction_simplifier (before)
556   /// CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
557   /// CHECK-DAG:     <<Const5:i\d+>>    IntConstant 5
558   /// CHECK-DAG:     <<Const6:i\d+>>    IntConstant 6
559   /// CHECK-DAG:     <<Sub:i\d+>>       Sub [<<Const5>>,<<ArgValue>>]
560   /// CHECK-DAG:     <<Add:i\d+>>       Add [<<Sub>>,<<Const6>>]
561   /// CHECK-DAG:                        Return [<<Add>>]
562 
563   /// CHECK-START: int Main.$noinline$SubAddConst1(int) instruction_simplifier (after)
564   /// CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
565   /// CHECK-DAG:     <<Const11:i\d+>>   IntConstant 11
566   /// CHECK-DAG:     <<Sub:i\d+>>       Sub [<<Const11>>,<<ArgValue>>]
567   /// CHECK-DAG:                        Return [<<Sub>>]
568 
$noinline$SubAddConst1(int arg)569   public static int $noinline$SubAddConst1(int arg) {
570     return 5 - arg + 6;
571   }
572 
573   /// CHECK-START: int Main.$noinline$SubAddConst2(int) instruction_simplifier (before)
574   /// CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
575   /// CHECK-DAG:     <<Const14:i\d+>>   IntConstant 14
576   /// CHECK-DAG:     <<Const13:i\d+>>   IntConstant 13
577   /// CHECK-DAG:     <<Add:i\d+>>       Add [<<ArgValue>>,<<Const13>>]
578   /// CHECK-DAG:     <<Sub:i\d+>>       Sub [<<Const14>>,<<Add>>]
579   /// CHECK-DAG:                        Return [<<Sub>>]
580 
581   /// CHECK-START: int Main.$noinline$SubAddConst2(int) instruction_simplifier (after)
582   /// CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
583   /// CHECK-DAG:     <<Const1:i\d+>>    IntConstant 1
584   /// CHECK-DAG:     <<Sub:i\d+>>       Sub [<<Const1>>,<<ArgValue>>]
585   /// CHECK-DAG:                        Return [<<Sub>>]
586 
$noinline$SubAddConst2(int arg)587   public static int $noinline$SubAddConst2(int arg) {
588     return 14 - (arg + 13);
589   }
590 
591   /// CHECK-START: long Main.$noinline$SubSubConst(long) instruction_simplifier (before)
592   /// CHECK-DAG:     <<ArgValue:j\d+>>  ParameterValue
593   /// CHECK-DAG:     <<Const17:j\d+>>   LongConstant 17
594   /// CHECK-DAG:     <<Const18:j\d+>>   LongConstant 18
595   /// CHECK-DAG:     <<Sub1:j\d+>>      Sub [<<Const18>>,<<ArgValue>>]
596   /// CHECK-DAG:     <<Sub2:j\d+>>      Sub [<<Const17>>,<<Sub1>>]
597   /// CHECK-DAG:                        Return [<<Sub2>>]
598 
599   /// CHECK-START: long Main.$noinline$SubSubConst(long) instruction_simplifier (after)
600   /// CHECK-DAG:     <<ArgValue:j\d+>>  ParameterValue
601   /// CHECK-DAG:     <<ConstM1:j\d+>>   LongConstant -1
602   /// CHECK-DAG:     <<Add:j\d+>>       Add [<<ArgValue>>,<<ConstM1>>]
603   /// CHECK-DAG:                        Return [<<Add>>]
604 
$noinline$SubSubConst(long arg)605   public static long $noinline$SubSubConst(long arg) {
606     return 17 - (18 - arg);
607   }
608 
609   /// CHECK-START: long Main.$noinline$UShr0(long) instruction_simplifier (before)
610   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
611   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
612   /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<Arg>>,<<Const0>>]
613   /// CHECK-DAG:                       Return [<<UShr>>]
614 
615   /// CHECK-START: long Main.$noinline$UShr0(long) instruction_simplifier (after)
616   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
617   /// CHECK-DAG:                       Return [<<Arg>>]
618 
619   /// CHECK-START: long Main.$noinline$UShr0(long) instruction_simplifier (after)
620   /// CHECK-NOT:                       UShr
621 
$noinline$UShr0(long arg)622   public static long $noinline$UShr0(long arg) {
623     return arg >>> 0;
624   }
625 
626   /// CHECK-START: int Main.$noinline$Xor0(int) instruction_simplifier (before)
627   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
628   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
629   /// CHECK-DAG:     <<Xor:i\d+>>      Xor [<<Arg>>,<<Const0>>]
630   /// CHECK-DAG:                       Return [<<Xor>>]
631 
632   /// CHECK-START: int Main.$noinline$Xor0(int) instruction_simplifier (after)
633   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
634   /// CHECK-DAG:                       Return [<<Arg>>]
635 
636   /// CHECK-START: int Main.$noinline$Xor0(int) instruction_simplifier (after)
637   /// CHECK-NOT:                       Xor
638 
$noinline$Xor0(int arg)639   public static int $noinline$Xor0(int arg) {
640     return arg ^ 0;
641   }
642 
643   /**
644    * Test that addition or subtraction operation with both inputs negated are
645    * optimized to use a single negation after the operation.
646    * The transformation tested is implemented in
647    * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
648    */
649 
650   /// CHECK-START: int Main.$noinline$AddNegs1(int, int) instruction_simplifier (before)
651   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
652   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
653   /// CHECK-DAG:     <<Neg1:i\d+>>     Neg [<<Arg1>>]
654   /// CHECK-DAG:     <<Neg2:i\d+>>     Neg [<<Arg2>>]
655   /// CHECK-DAG:     <<Add:i\d+>>      Add [<<Neg1>>,<<Neg2>>]
656   /// CHECK-DAG:                       Return [<<Add>>]
657 
658   /// CHECK-START: int Main.$noinline$AddNegs1(int, int) instruction_simplifier (after)
659   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
660   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
661   /// CHECK-NOT:                       Neg
662   /// CHECK-DAG:     <<Add:i\d+>>      Add [<<Arg1>>,<<Arg2>>]
663   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Add>>]
664   /// CHECK-DAG:                       Return [<<Neg>>]
665 
$noinline$AddNegs1(int arg1, int arg2)666   public static int $noinline$AddNegs1(int arg1, int arg2) {
667     return -arg1 + -arg2;
668   }
669 
670   /**
671    * This is similar to the test-case AddNegs1, but the negations have
672    * multiple uses.
673    * The transformation tested is implemented in
674    * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
675    * The current code won't perform the previous optimization. The
676    * transformations do not look at other uses of their inputs. As they don't
677    * know what will happen with other uses, they do not take the risk of
678    * increasing the register pressure by creating or extending live ranges.
679    */
680 
681   /// CHECK-START: int Main.$noinline$AddNegs2(int, int) instruction_simplifier (before)
682   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
683   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
684   /// CHECK-DAG:     <<Neg1:i\d+>>     Neg [<<Arg1>>]
685   /// CHECK-DAG:     <<Neg2:i\d+>>     Neg [<<Arg2>>]
686   /// CHECK-DAG:     <<Add1:i\d+>>     Add [<<Neg1>>,<<Neg2>>]
687   /// CHECK-DAG:     <<Add2:i\d+>>     Add [<<Neg1>>,<<Neg2>>]
688   /// CHECK-DAG:     <<Or:i\d+>>       Or [<<Add1>>,<<Add2>>]
689   /// CHECK-DAG:                       Return [<<Or>>]
690 
691   /// CHECK-START: int Main.$noinline$AddNegs2(int, int) instruction_simplifier (after)
692   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
693   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
694   /// CHECK-DAG:     <<Neg1:i\d+>>     Neg [<<Arg1>>]
695   /// CHECK-DAG:     <<Neg2:i\d+>>     Neg [<<Arg2>>]
696   /// CHECK-DAG:     <<Add1:i\d+>>     Add [<<Neg1>>,<<Neg2>>]
697   /// CHECK-DAG:     <<Add2:i\d+>>     Add [<<Neg1>>,<<Neg2>>]
698   /// CHECK-NOT:                       Neg
699   /// CHECK-DAG:     <<Or:i\d+>>       Or [<<Add1>>,<<Add2>>]
700   /// CHECK-DAG:                       Return [<<Or>>]
701 
702   /// CHECK-START: int Main.$noinline$AddNegs2(int, int) GVN (after)
703   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
704   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
705   /// CHECK-DAG:     <<Neg1:i\d+>>     Neg [<<Arg1>>]
706   /// CHECK-DAG:     <<Neg2:i\d+>>     Neg [<<Arg2>>]
707   /// CHECK-DAG:     <<Add:i\d+>>      Add [<<Neg1>>,<<Neg2>>]
708   /// CHECK-DAG:     <<Or:i\d+>>       Or [<<Add>>,<<Add>>]
709   /// CHECK-DAG:                       Return [<<Or>>]
710 
$noinline$AddNegs2(int arg1, int arg2)711   public static int $noinline$AddNegs2(int arg1, int arg2) {
712     int temp1 = -arg1;
713     int temp2 = -arg2;
714     return (temp1 + temp2) | (temp1 + temp2);
715   }
716 
717   /**
718    * This follows test-cases AddNegs1 and AddNegs2.
719    * The transformation tested is implemented in
720    * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
721    * The optimization should not happen if it moves an additional instruction in
722    * the loop.
723    */
724 
725   /// CHECK-START: long Main.$noinline$AddNegs3(long, long) instruction_simplifier (before)
726   //  -------------- Arguments and initial negation operations.
727   /// CHECK-DAG:     <<Arg1:j\d+>>     ParameterValue
728   /// CHECK-DAG:     <<Arg2:j\d+>>     ParameterValue
729   /// CHECK-DAG:     <<Neg1:j\d+>>     Neg [<<Arg1>>]
730   /// CHECK-DAG:     <<Neg2:j\d+>>     Neg [<<Arg2>>]
731   /// CHECK:                           Goto
732   //  -------------- Loop
733   /// CHECK:                           SuspendCheck
734   /// CHECK:         <<Add:j\d+>>      Add [<<Neg1>>,<<Neg2>>]
735   /// CHECK:                           Goto
736 
737   /// CHECK-START: long Main.$noinline$AddNegs3(long, long) instruction_simplifier (after)
738   //  -------------- Arguments and initial negation operations.
739   /// CHECK-DAG:     <<Arg1:j\d+>>     ParameterValue
740   /// CHECK-DAG:     <<Arg2:j\d+>>     ParameterValue
741   /// CHECK-DAG:     <<Neg1:j\d+>>     Neg [<<Arg1>>]
742   /// CHECK-DAG:     <<Neg2:j\d+>>     Neg [<<Arg2>>]
743   /// CHECK:                           Goto
744   //  -------------- Loop
745   /// CHECK:                           SuspendCheck
746   /// CHECK:         <<Add:j\d+>>      Add [<<Neg1>>,<<Neg2>>]
747   /// CHECK-NOT:                       Neg
748   /// CHECK:                           Goto
749 
$noinline$AddNegs3(long arg1, long arg2)750   public static long $noinline$AddNegs3(long arg1, long arg2) {
751     long res = 0;
752     long n_arg1 = -arg1;
753     long n_arg2 = -arg2;
754     for (long i = 0; i < 1; i++) {
755       res += n_arg1 + n_arg2 + i;
756     }
757     return res;
758   }
759 
760   /**
761    * Test the simplification of an addition with a negated argument into a
762    * subtraction.
763    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
764    */
765 
766   /// CHECK-START: long Main.$noinline$AddNeg1(long, long) instruction_simplifier (before)
767   /// CHECK-DAG:     <<Arg1:j\d+>>     ParameterValue
768   /// CHECK-DAG:     <<Arg2:j\d+>>     ParameterValue
769   /// CHECK-DAG:     <<Neg:j\d+>>      Neg [<<Arg1>>]
770   /// CHECK-DAG:     <<Add:j\d+>>      Add [<<Neg>>,<<Arg2>>]
771   /// CHECK-DAG:                       Return [<<Add>>]
772 
773   /// CHECK-START: long Main.$noinline$AddNeg1(long, long) instruction_simplifier (after)
774   /// CHECK-DAG:     <<Arg1:j\d+>>     ParameterValue
775   /// CHECK-DAG:     <<Arg2:j\d+>>     ParameterValue
776   /// CHECK-DAG:     <<Sub:j\d+>>      Sub [<<Arg2>>,<<Arg1>>]
777   /// CHECK-DAG:                       Return [<<Sub>>]
778 
779   /// CHECK-START: long Main.$noinline$AddNeg1(long, long) instruction_simplifier (after)
780   /// CHECK-NOT:                       Neg
781   /// CHECK-NOT:                       Add
782 
$noinline$AddNeg1(long arg1, long arg2)783   public static long $noinline$AddNeg1(long arg1, long arg2) {
784     return -arg1 + arg2;
785   }
786 
787   /**
788    * This is similar to the test-case AddNeg1, but the negation has two uses.
789    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
790    * The current code won't perform the previous optimization. The
791    * transformations do not look at other uses of their inputs. As they don't
792    * know what will happen with other uses, they do not take the risk of
793    * increasing the register pressure by creating or extending live ranges.
794    */
795 
796   /// CHECK-START: long Main.$noinline$AddNeg2(long, long) instruction_simplifier (before)
797   /// CHECK-DAG:     <<Arg1:j\d+>>     ParameterValue
798   /// CHECK-DAG:     <<Arg2:j\d+>>     ParameterValue
799   /// CHECK-DAG:     <<Neg:j\d+>>      Neg [<<Arg2>>]
800   /// CHECK-DAG:     <<Add1:j\d+>>     Add [<<Arg1>>,<<Neg>>]
801   /// CHECK-DAG:     <<Add2:j\d+>>     Add [<<Arg1>>,<<Neg>>]
802   /// CHECK-DAG:     <<Res:j\d+>>      Or [<<Add1>>,<<Add2>>]
803   /// CHECK-DAG:                       Return [<<Res>>]
804 
805   /// CHECK-START: long Main.$noinline$AddNeg2(long, long) instruction_simplifier (after)
806   /// CHECK-DAG:     <<Arg1:j\d+>>     ParameterValue
807   /// CHECK-DAG:     <<Arg2:j\d+>>     ParameterValue
808   /// CHECK-DAG:     <<Neg:j\d+>>      Neg [<<Arg2>>]
809   /// CHECK-DAG:     <<Add1:j\d+>>     Add [<<Arg1>>,<<Neg>>]
810   /// CHECK-DAG:     <<Add2:j\d+>>     Add [<<Arg1>>,<<Neg>>]
811   /// CHECK-DAG:     <<Res:j\d+>>      Or [<<Add1>>,<<Add2>>]
812   /// CHECK-DAG:                       Return [<<Res>>]
813 
814   /// CHECK-START: long Main.$noinline$AddNeg2(long, long) instruction_simplifier (after)
815   /// CHECK-NOT:                       Sub
816 
$noinline$AddNeg2(long arg1, long arg2)817   public static long $noinline$AddNeg2(long arg1, long arg2) {
818     long temp = -arg2;
819     return (arg1 + temp) | (arg1 + temp);
820   }
821 
822   /**
823    * Test simplification of the `-(-var)` pattern.
824    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
825    */
826 
827   /// CHECK-START: long Main.$noinline$NegNeg1(long) instruction_simplifier (before)
828   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
829   /// CHECK-DAG:     <<Neg1:j\d+>>     Neg [<<Arg>>]
830   /// CHECK-DAG:     <<Neg2:j\d+>>     Neg [<<Neg1>>]
831   /// CHECK-DAG:                       Return [<<Neg2>>]
832 
833   /// CHECK-START: long Main.$noinline$NegNeg1(long) instruction_simplifier (after)
834   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
835   /// CHECK-DAG:                       Return [<<Arg>>]
836 
837   /// CHECK-START: long Main.$noinline$NegNeg1(long) instruction_simplifier (after)
838   /// CHECK-NOT:                       Neg
839 
$noinline$NegNeg1(long arg)840   public static long $noinline$NegNeg1(long arg) {
841     return -(-arg);
842   }
843 
844   /**
845    * Test 'multi-step' simplification, where a first transformation yields a
846    * new simplification possibility for the current instruction.
847    * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
848    * and in `InstructionSimplifierVisitor::VisitAdd`.
849    */
850 
851   /// CHECK-START: int Main.$noinline$NegNeg2(int) instruction_simplifier (before)
852   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
853   /// CHECK-DAG:     <<Neg1:i\d+>>     Neg [<<Arg>>]
854   /// CHECK-DAG:     <<Neg2:i\d+>>     Neg [<<Neg1>>]
855   /// CHECK-DAG:     <<Add:i\d+>>      Add [<<Neg2>>,<<Neg1>>]
856   /// CHECK-DAG:                       Return [<<Add>>]
857 
858   /// CHECK-START: int Main.$noinline$NegNeg2(int) instruction_simplifier (after)
859   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
860   /// CHECK-DAG:     <<Sub:i\d+>>      Sub [<<Arg>>,<<Arg>>]
861   /// CHECK-DAG:                       Return [<<Sub>>]
862 
863   /// CHECK-START: int Main.$noinline$NegNeg2(int) instruction_simplifier (after)
864   /// CHECK-NOT:                       Neg
865   /// CHECK-NOT:                       Add
866 
867   /// CHECK-START: int Main.$noinline$NegNeg2(int) constant_folding$after_gvn (after)
868   /// CHECK:         <<Const0:i\d+>>   IntConstant 0
869   /// CHECK-NOT:                       Neg
870   /// CHECK-NOT:                       Add
871   /// CHECK:                           Return [<<Const0>>]
872 
$noinline$NegNeg2(int arg)873   public static int $noinline$NegNeg2(int arg) {
874     int temp = -arg;
875     return temp + -temp;
876   }
877 
878   /**
879    * Test another 'multi-step' simplification, where a first transformation
880    * yields a new simplification possibility for the current instruction.
881    * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
882    * and in `InstructionSimplifierVisitor::VisitSub`.
883    */
884 
885   /// CHECK-START: long Main.$noinline$NegNeg3(long) instruction_simplifier (before)
886   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
887   /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
888   /// CHECK-DAG:     <<Neg:j\d+>>      Neg [<<Arg>>]
889   /// CHECK-DAG:     <<Sub:j\d+>>      Sub [<<Const0>>,<<Neg>>]
890   /// CHECK-DAG:                       Return [<<Sub>>]
891 
892   /// CHECK-START: long Main.$noinline$NegNeg3(long) instruction_simplifier (after)
893   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
894   /// CHECK-DAG:                       Return [<<Arg>>]
895 
896   /// CHECK-START: long Main.$noinline$NegNeg3(long) instruction_simplifier (after)
897   /// CHECK-NOT:                       Neg
898   /// CHECK-NOT:                       Sub
899 
$noinline$NegNeg3(long arg)900   public static long $noinline$NegNeg3(long arg) {
901     return 0 - -arg;
902   }
903 
904   /**
905    * Test that a negated subtraction is simplified to a subtraction with its
906    * arguments reversed.
907    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
908    */
909 
910   /// CHECK-START: int Main.$noinline$NegSub1(int, int) instruction_simplifier (before)
911   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
912   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
913   /// CHECK-DAG:     <<Sub:i\d+>>      Sub [<<Arg1>>,<<Arg2>>]
914   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Sub>>]
915   /// CHECK-DAG:                       Return [<<Neg>>]
916 
917   /// CHECK-START: int Main.$noinline$NegSub1(int, int) instruction_simplifier (after)
918   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
919   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
920   /// CHECK-DAG:     <<Sub:i\d+>>      Sub [<<Arg2>>,<<Arg1>>]
921   /// CHECK-DAG:                       Return [<<Sub>>]
922 
923   /// CHECK-START: int Main.$noinline$NegSub1(int, int) instruction_simplifier (after)
924   /// CHECK-NOT:                       Neg
925 
$noinline$NegSub1(int arg1, int arg2)926   public static int $noinline$NegSub1(int arg1, int arg2) {
927     return -(arg1 - arg2);
928   }
929 
930   /**
931    * This is similar to the test-case NegSub1, but the subtraction has
932    * multiple uses.
933    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
934    * The current code won't perform the previous optimization. The
935    * transformations do not look at other uses of their inputs. As they don't
936    * know what will happen with other uses, they do not take the risk of
937    * increasing the register pressure by creating or extending live ranges.
938    */
939 
940   /// CHECK-START: int Main.$noinline$NegSub2(int, int) instruction_simplifier (before)
941   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
942   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
943   /// CHECK-DAG:     <<Sub:i\d+>>      Sub [<<Arg1>>,<<Arg2>>]
944   /// CHECK-DAG:     <<Neg1:i\d+>>     Neg [<<Sub>>]
945   /// CHECK-DAG:     <<Neg2:i\d+>>     Neg [<<Sub>>]
946   /// CHECK-DAG:     <<Or:i\d+>>       Or [<<Neg1>>,<<Neg2>>]
947   /// CHECK-DAG:                       Return [<<Or>>]
948 
949   /// CHECK-START: int Main.$noinline$NegSub2(int, int) instruction_simplifier (after)
950   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
951   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
952   /// CHECK-DAG:     <<Sub:i\d+>>      Sub [<<Arg1>>,<<Arg2>>]
953   /// CHECK-DAG:     <<Neg1:i\d+>>     Neg [<<Sub>>]
954   /// CHECK-DAG:     <<Neg2:i\d+>>     Neg [<<Sub>>]
955   /// CHECK-DAG:     <<Or:i\d+>>       Or [<<Neg1>>,<<Neg2>>]
956   /// CHECK-DAG:                       Return [<<Or>>]
957 
$noinline$NegSub2(int arg1, int arg2)958   public static int $noinline$NegSub2(int arg1, int arg2) {
959     int temp = arg1 - arg2;
960     return -temp | -temp;
961   }
962 
963     /**
964    * Test the simplification of a subtraction with a negated argument.
965    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
966    */
967 
968   /// CHECK-START: int Main.$noinline$SubNeg1(int, int) instruction_simplifier (before)
969   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
970   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
971   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Arg1>>]
972   /// CHECK-DAG:     <<Sub:i\d+>>      Sub [<<Neg>>,<<Arg2>>]
973   /// CHECK-DAG:                       Return [<<Sub>>]
974 
975   /// CHECK-START: int Main.$noinline$SubNeg1(int, int) instruction_simplifier (after)
976   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
977   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
978   /// CHECK-DAG:     <<Add:i\d+>>      Add [<<Arg1>>,<<Arg2>>]
979   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Add>>]
980   /// CHECK-DAG:                       Return [<<Neg>>]
981 
982   /// CHECK-START: int Main.$noinline$SubNeg1(int, int) instruction_simplifier (after)
983   /// CHECK-NOT:                       Sub
984 
$noinline$SubNeg1(int arg1, int arg2)985   public static int $noinline$SubNeg1(int arg1, int arg2) {
986     return -arg1 - arg2;
987   }
988 
989   /**
990    * This is similar to the test-case SubNeg1, but the negation has
991    * multiple uses.
992    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
993    * The current code won't perform the previous optimization. The
994    * transformations do not look at other uses of their inputs. As they don't
995    * know what will happen with other uses, they do not take the risk of
996    * increasing the register pressure by creating or extending live ranges.
997    */
998 
999   /// CHECK-START: int Main.$noinline$SubNeg2(int, int) instruction_simplifier (before)
1000   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
1001   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
1002   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Arg1>>]
1003   /// CHECK-DAG:     <<Sub1:i\d+>>     Sub [<<Neg>>,<<Arg2>>]
1004   /// CHECK-DAG:     <<Sub2:i\d+>>     Sub [<<Neg>>,<<Arg2>>]
1005   /// CHECK-DAG:     <<Or:i\d+>>       Or [<<Sub1>>,<<Sub2>>]
1006   /// CHECK-DAG:                       Return [<<Or>>]
1007 
1008   /// CHECK-START: int Main.$noinline$SubNeg2(int, int) instruction_simplifier (after)
1009   /// CHECK-DAG:     <<Arg1:i\d+>>     ParameterValue
1010   /// CHECK-DAG:     <<Arg2:i\d+>>     ParameterValue
1011   /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Arg1>>]
1012   /// CHECK-DAG:     <<Sub1:i\d+>>     Sub [<<Neg>>,<<Arg2>>]
1013   /// CHECK-DAG:     <<Sub2:i\d+>>     Sub [<<Neg>>,<<Arg2>>]
1014   /// CHECK-DAG:     <<Or:i\d+>>       Or [<<Sub1>>,<<Sub2>>]
1015   /// CHECK-DAG:                       Return [<<Or>>]
1016 
1017   /// CHECK-START: int Main.$noinline$SubNeg2(int, int) instruction_simplifier (after)
1018   /// CHECK-NOT:                       Add
1019 
$noinline$SubNeg2(int arg1, int arg2)1020   public static int $noinline$SubNeg2(int arg1, int arg2) {
1021     int temp = -arg1;
1022     return (temp - arg2) | (temp - arg2);
1023   }
1024 
1025   /**
1026    * This follows test-cases SubNeg1 and SubNeg2.
1027    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
1028    * The optimization should not happen if it moves an additional instruction in
1029    * the loop.
1030    */
1031 
1032   /// CHECK-START: long Main.$noinline$SubNeg3(long, long) instruction_simplifier (before)
1033   //  -------------- Arguments and initial negation operation.
1034   /// CHECK-DAG:     <<Arg1:j\d+>>     ParameterValue
1035   /// CHECK-DAG:     <<Arg2:j\d+>>     ParameterValue
1036   /// CHECK-DAG:     <<Neg:j\d+>>      Neg [<<Arg1>>]
1037   /// CHECK:                           Goto
1038   //  -------------- Loop
1039   /// CHECK:                           SuspendCheck
1040   /// CHECK:         <<Sub:j\d+>>      Sub [<<Neg>>,<<Arg2>>]
1041   /// CHECK:                           Goto
1042 
1043   /// CHECK-START: long Main.$noinline$SubNeg3(long, long) instruction_simplifier (after)
1044   //  -------------- Arguments and initial negation operation.
1045   /// CHECK-DAG:     <<Arg1:j\d+>>     ParameterValue
1046   /// CHECK-DAG:     <<Arg2:j\d+>>     ParameterValue
1047   /// CHECK-DAG:     <<Neg:j\d+>>      Neg [<<Arg1>>]
1048   /// CHECK-DAG:                       Goto
1049   //  -------------- Loop
1050   /// CHECK:                           SuspendCheck
1051   /// CHECK:         <<Sub:j\d+>>      Sub [<<Neg>>,<<Arg2>>]
1052   /// CHECK-NOT:                       Neg
1053   /// CHECK:                           Goto
1054 
$noinline$SubNeg3(long arg1, long arg2)1055   public static long $noinline$SubNeg3(long arg1, long arg2) {
1056     long res = 0;
1057     long temp = -arg1;
1058     for (long i = 0; i < 1; i++) {
1059       res += temp - arg2 - i;
1060     }
1061     return res;
1062   }
1063 
1064   /// CHECK-START: boolean Main.$noinline$EqualBoolVsIntConst(boolean) dead_code_elimination$after_inlining (before)
1065   /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
1066   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
1067   /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
1068   /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
1069   /// CHECK-DAG:                       If [<<Arg>>]
1070   /// CHECK-DAG:     <<Phi1:i\d+>>     Phi [<<Const0>>,<<Const1>>]
1071   /// CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Phi1>>,<<Const2>>]
1072   /// CHECK-DAG:                       If [<<Cond>>]
1073   /// CHECK-DAG:     <<Phi2:i\d+>>     Phi [<<Const0>>,<<Const1>>]
1074   /// CHECK-DAG:                       Return [<<Phi2>>]
1075 
1076   /// CHECK-START: boolean Main.$noinline$EqualBoolVsIntConst(boolean) dead_code_elimination$after_inlining (after)
1077   /// CHECK-DAG:     <<True:i\d+>>     IntConstant 1
1078   /// CHECK-DAG:                       Return [<<True>>]
1079 
$noinline$EqualBoolVsIntConst(boolean arg)1080   public static boolean $noinline$EqualBoolVsIntConst(boolean arg) {
1081     // Make calls that will be inlined to make sure the instruction simplifier
1082     // sees the simplification (dead code elimination will also try to simplify it).
1083     return (arg ? $inline$ReturnArg(0) : $inline$ReturnArg(1)) != 2;
1084   }
1085 
$inline$ReturnArg(int arg)1086   public static int $inline$ReturnArg(int arg) {
1087     return arg;
1088   }
1089 
1090   /// CHECK-START: boolean Main.$noinline$NotEqualBoolVsIntConst(boolean) instruction_simplifier$after_inlining (before)
1091   /// CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
1092   /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
1093   /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
1094   /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
1095   /// CHECK-DAG:                       If [<<Arg>>]
1096   /// CHECK-DAG:     <<Phi1:i\d+>>     Phi [<<Const0>>,<<Const1>>]
1097   /// CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Phi1>>,<<Const2>>]
1098   /// CHECK-DAG:                       If [<<Cond>>]
1099   /// CHECK-DAG:     <<Phi2:i\d+>>     Phi [<<Const0>>,<<Const1>>]
1100   /// CHECK-DAG:                       Return [<<Phi2>>]
1101 
1102   /// CHECK-START: boolean Main.$noinline$NotEqualBoolVsIntConst(boolean) dead_code_elimination$after_inlining (after)
1103   /// CHECK-DAG:     <<False:i\d+>>    IntConstant 0
1104   /// CHECK-DAG:                       Return [<<False>>]
1105 
$noinline$NotEqualBoolVsIntConst(boolean arg)1106   public static boolean $noinline$NotEqualBoolVsIntConst(boolean arg) {
1107     // Make calls that will be inlined to make sure the instruction simplifier
1108     // sees the simplification (dead code elimination will also try to simplify it).
1109     return (arg ? $inline$ReturnArg(0) : $inline$ReturnArg(1)) == 2;
1110   }
1111 
1112   /// CHECK-START: float Main.$noinline$Div2(float) instruction_simplifier (before)
1113   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1114   /// CHECK-DAG:      <<Const2:f\d+>>   FloatConstant 2
1115   /// CHECK-DAG:      <<Div:f\d+>>      Div [<<Arg>>,<<Const2>>]
1116   /// CHECK-DAG:                        Return [<<Div>>]
1117 
1118   /// CHECK-START: float Main.$noinline$Div2(float) instruction_simplifier (after)
1119   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1120   /// CHECK-DAG:      <<ConstP5:f\d+>>  FloatConstant 0.5
1121   /// CHECK-DAG:      <<Mul:f\d+>>      Mul [<<Arg>>,<<ConstP5>>]
1122   /// CHECK-DAG:                        Return [<<Mul>>]
1123 
1124   /// CHECK-START: float Main.$noinline$Div2(float) instruction_simplifier (after)
1125   /// CHECK-NOT:                        Div
1126 
$noinline$Div2(float arg)1127   public static float $noinline$Div2(float arg) {
1128     return arg / 2.0f;
1129   }
1130 
1131   /// CHECK-START: double Main.$noinline$Div2(double) instruction_simplifier (before)
1132   /// CHECK-DAG:      <<Arg:d\d+>>      ParameterValue
1133   /// CHECK-DAG:      <<Const2:d\d+>>   DoubleConstant 2
1134   /// CHECK-DAG:      <<Div:d\d+>>      Div [<<Arg>>,<<Const2>>]
1135   /// CHECK-DAG:                        Return [<<Div>>]
1136 
1137   /// CHECK-START: double Main.$noinline$Div2(double) instruction_simplifier (after)
1138   /// CHECK-DAG:      <<Arg:d\d+>>      ParameterValue
1139   /// CHECK-DAG:      <<ConstP5:d\d+>>  DoubleConstant 0.5
1140   /// CHECK-DAG:      <<Mul:d\d+>>      Mul [<<Arg>>,<<ConstP5>>]
1141   /// CHECK-DAG:                        Return [<<Mul>>]
1142 
1143   /// CHECK-START: double Main.$noinline$Div2(double) instruction_simplifier (after)
1144   /// CHECK-NOT:                        Div
$noinline$Div2(double arg)1145   public static double $noinline$Div2(double arg) {
1146     return arg / 2.0;
1147   }
1148 
1149   /// CHECK-START: float Main.$noinline$DivMP25(float) instruction_simplifier (before)
1150   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1151   /// CHECK-DAG:      <<ConstMP25:f\d+>>   FloatConstant -0.25
1152   /// CHECK-DAG:      <<Div:f\d+>>      Div [<<Arg>>,<<ConstMP25>>]
1153   /// CHECK-DAG:                        Return [<<Div>>]
1154 
1155   /// CHECK-START: float Main.$noinline$DivMP25(float) instruction_simplifier (after)
1156   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1157   /// CHECK-DAG:      <<ConstM4:f\d+>>  FloatConstant -4
1158   /// CHECK-DAG:      <<Mul:f\d+>>      Mul [<<Arg>>,<<ConstM4>>]
1159   /// CHECK-DAG:                        Return [<<Mul>>]
1160 
1161   /// CHECK-START: float Main.$noinline$DivMP25(float) instruction_simplifier (after)
1162   /// CHECK-NOT:                        Div
1163 
$noinline$DivMP25(float arg)1164   public static float $noinline$DivMP25(float arg) {
1165     return arg / -0.25f;
1166   }
1167 
1168   /// CHECK-START: double Main.$noinline$DivMP25(double) instruction_simplifier (before)
1169   /// CHECK-DAG:      <<Arg:d\d+>>      ParameterValue
1170   /// CHECK-DAG:      <<ConstMP25:d\d+>>   DoubleConstant -0.25
1171   /// CHECK-DAG:      <<Div:d\d+>>      Div [<<Arg>>,<<ConstMP25>>]
1172   /// CHECK-DAG:                        Return [<<Div>>]
1173 
1174   /// CHECK-START: double Main.$noinline$DivMP25(double) instruction_simplifier (after)
1175   /// CHECK-DAG:      <<Arg:d\d+>>      ParameterValue
1176   /// CHECK-DAG:      <<ConstM4:d\d+>>  DoubleConstant -4
1177   /// CHECK-DAG:      <<Mul:d\d+>>      Mul [<<Arg>>,<<ConstM4>>]
1178   /// CHECK-DAG:                        Return [<<Mul>>]
1179 
1180   /// CHECK-START: double Main.$noinline$DivMP25(double) instruction_simplifier (after)
1181   /// CHECK-NOT:                        Div
$noinline$DivMP25(double arg)1182   public static double $noinline$DivMP25(double arg) {
1183     return arg / -0.25f;
1184   }
1185 
1186   /**
1187    * Test strength reduction of factors of the form (2^n + 1).
1188    */
1189 
1190   /// CHECK-START: int Main.$noinline$mulPow2Plus1(int) instruction_simplifier (before)
1191   /// CHECK-DAG:   <<Arg:i\d+>>         ParameterValue
1192   /// CHECK-DAG:   <<Const9:i\d+>>      IntConstant 9
1193   /// CHECK:                            Mul [<<Arg>>,<<Const9>>]
1194 
1195   /// CHECK-START: int Main.$noinline$mulPow2Plus1(int) instruction_simplifier (after)
1196   /// CHECK-DAG:   <<Arg:i\d+>>         ParameterValue
1197   /// CHECK-DAG:   <<Const3:i\d+>>      IntConstant 3
1198   /// CHECK:       <<Shift:i\d+>>       Shl [<<Arg>>,<<Const3>>]
1199   /// CHECK-NEXT:                       Add [<<Arg>>,<<Shift>>]
1200 
$noinline$mulPow2Plus1(int arg)1201   public static int $noinline$mulPow2Plus1(int arg) {
1202     return arg * 9;
1203   }
1204 
1205   /**
1206    * Test strength reduction of factors of the form (2^n - 1).
1207    */
1208 
1209   /// CHECK-START: long Main.$noinline$mulPow2Minus1(long) instruction_simplifier (before)
1210   /// CHECK-DAG:   <<Arg:j\d+>>         ParameterValue
1211   /// CHECK-DAG:   <<Const31:j\d+>>     LongConstant 31
1212   /// CHECK:                            Mul [<<Const31>>,<<Arg>>]
1213 
1214   /// CHECK-START: long Main.$noinline$mulPow2Minus1(long) instruction_simplifier (after)
1215   /// CHECK-DAG:   <<Arg:j\d+>>         ParameterValue
1216   /// CHECK-DAG:   <<Const5:i\d+>>      IntConstant 5
1217   /// CHECK:       <<Shift:j\d+>>       Shl [<<Arg>>,<<Const5>>]
1218   /// CHECK-NEXT:                       Sub [<<Shift>>,<<Arg>>]
1219 
$noinline$mulPow2Minus1(long arg)1220   public static long $noinline$mulPow2Minus1(long arg) {
1221     return arg * 31;
1222   }
1223 
1224   /// CHECK-START: int Main.$noinline$booleanFieldNotEqualOne() instruction_simplifier$after_inlining (before)
1225   /// CHECK-DAG:      <<Const1:i\d+>>   IntConstant 1
1226   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1227   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1228   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
1229   /// CHECK-DAG:      <<NE:z\d+>>       NotEqual [<<Field>>,<<Const1>>]
1230   /// CHECK-DAG:                        If [<<NE>>]
1231   /// CHECK-DAG:      <<Phi:i\d+>>      Phi [<<Const13>>,<<Const54>>]
1232   /// CHECK-DAG:                        Return [<<Phi>>]
1233 
1234   /// CHECK-START: int Main.$noinline$booleanFieldNotEqualOne() select_generator (after)
1235   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
1236   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1237   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1238   /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Const54>>,<<Const13>>,<<Field>>]
1239   /// CHECK-DAG:                        Return [<<Select>>]
1240 
$noinline$booleanFieldNotEqualOne()1241   public static int $noinline$booleanFieldNotEqualOne() {
1242     return (booleanField == $inline$true()) ? 13 : 54;
1243   }
1244 
1245   /// CHECK-START: int Main.$noinline$booleanFieldEqualZero() instruction_simplifier$after_inlining (before)
1246   /// CHECK-DAG:      <<Const0:i\d+>>   IntConstant 0
1247   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1248   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1249   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
1250   /// CHECK-DAG:      <<EQ:z\d+>>       Equal [<<Field>>,<<Const0>>]
1251   /// CHECK-DAG:                        If [<<EQ>>]
1252   /// CHECK-DAG:      <<Phi:i\d+>>      Phi [<<Const13>>,<<Const54>>]
1253   /// CHECK-DAG:                        Return [<<Phi>>]
1254 
1255   /// CHECK-START: int Main.$noinline$booleanFieldEqualZero() select_generator (after)
1256   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
1257   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1258   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1259   /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Const54>>,<<Const13>>,<<Field>>]
1260   /// CHECK-DAG:                        Return [<<Select>>]
1261 
$noinline$booleanFieldEqualZero()1262   public static int $noinline$booleanFieldEqualZero() {
1263     return (booleanField != $inline$false()) ? 13 : 54;
1264   }
1265 
1266   /// CHECK-START: int Main.$noinline$intConditionNotEqualOne(int) instruction_simplifier$after_inlining (before)
1267   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1268   /// CHECK-DAG:      <<Const0:i\d+>>   IntConstant 0
1269   /// CHECK-DAG:      <<Const1:i\d+>>   IntConstant 1
1270   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1271   /// CHECK-DAG:      <<Const42:i\d+>>  IntConstant 42
1272   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1273   /// CHECK-DAG:      <<LE:z\d+>>       LessThanOrEqual [<<Arg>>,<<Const42>>]
1274   /// CHECK-DAG:                        If [<<LE>>]
1275   /// CHECK-DAG:      <<Phi1:i\d+>>     Phi [<<Const1>>,<<Const0>>]
1276   /// CHECK-DAG:      <<NE:z\d+>>       NotEqual [<<Phi1>>,<<Const1>>]
1277   /// CHECK-DAG:                        If [<<NE>>]
1278   /// CHECK-DAG:      <<Phi2:i\d+>>     Phi [<<Const13>>,<<Const54>>]
1279   /// CHECK-DAG:                        Return [<<Phi2>>]
1280 
1281   /// CHECK-START: int Main.$noinline$intConditionNotEqualOne(int) select_generator (after)
1282   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1283   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1284   /// CHECK-DAG:      <<Const42:i\d+>>  IntConstant 42
1285   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1286   /// CHECK-DAG:      <<LE:z\d+>>       LessThanOrEqual [<<Arg>>,<<Const42>>]
1287   /// CHECK-DAG:      <<Result:i\d+>>   Select [<<Const13>>,<<Const54>>,<<LE>>]
1288   /// CHECK-DAG:                        Return [<<Result>>]
1289   // Note that we match `LE` from Select because there are two identical
1290   // LessThanOrEqual instructions.
1291 
$noinline$intConditionNotEqualOne(int i)1292   public static int $noinline$intConditionNotEqualOne(int i) {
1293     return ((i > 42) == $inline$true()) ? 13 : 54;
1294   }
1295 
1296   /// CHECK-START: int Main.$noinline$intConditionEqualZero(int) instruction_simplifier$after_inlining (before)
1297   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1298   /// CHECK-DAG:      <<Const0:i\d+>>   IntConstant 0
1299   /// CHECK-DAG:      <<Const1:i\d+>>   IntConstant 1
1300   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1301   /// CHECK-DAG:      <<Const42:i\d+>>  IntConstant 42
1302   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1303   /// CHECK-DAG:      <<LE:z\d+>>       LessThanOrEqual [<<Arg>>,<<Const42>>]
1304   /// CHECK-DAG:                        If [<<LE>>]
1305   /// CHECK-DAG:      <<Phi1:i\d+>>     Phi [<<Const1>>,<<Const0>>]
1306   /// CHECK-DAG:      <<EQ:z\d+>>       Equal [<<Phi1>>,<<Const0>>]
1307   /// CHECK-DAG:                        If [<<EQ>>]
1308   /// CHECK-DAG:      <<Phi2:i\d+>>     Phi [<<Const13>>,<<Const54>>]
1309   /// CHECK-DAG:                        Return [<<Phi2>>]
1310 
1311   /// CHECK-START: int Main.$noinline$intConditionEqualZero(int) select_generator (after)
1312   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1313   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1314   /// CHECK-DAG:      <<Const42:i\d+>>  IntConstant 42
1315   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1316   /// CHECK-DAG:      <<LE:z\d+>>       LessThanOrEqual [<<Arg>>,<<Const42>>]
1317   /// CHECK-DAG:      <<Result:i\d+>>   Select [<<Const13>>,<<Const54>>,<<LE>>]
1318   /// CHECK-DAG:                        Return [<<Result>>]
1319   // Note that we match `LE` from Select because there are two identical
1320   // LessThanOrEqual instructions.
1321 
$noinline$intConditionEqualZero(int i)1322   public static int $noinline$intConditionEqualZero(int i) {
1323     return ((i > 42) != $inline$false()) ? 13 : 54;
1324   }
1325 
1326   // Test that conditions on float/double are not flipped.
1327 
1328   /// CHECK-START: int Main.$noinline$floatConditionNotEqualOne(float) builder (after)
1329   /// CHECK:                            LessThanOrEqual
1330 
1331   /// CHECK-START: int Main.$noinline$floatConditionNotEqualOne(float) instruction_simplifier$before_codegen (after)
1332   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1333   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1334   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1335   /// CHECK-DAG:      <<Const42:f\d+>>  FloatConstant 42
1336   /// CHECK-DAG:      <<LE:z\d+>>       LessThanOrEqual [<<Arg>>,<<Const42>>]
1337   /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Const13>>,<<Const54>>,<<LE>>]
1338   /// CHECK-DAG:                        Return [<<Select>>]
1339 
$noinline$floatConditionNotEqualOne(float f)1340   public static int $noinline$floatConditionNotEqualOne(float f) {
1341     return ((f > 42.0f) == true) ? 13 : 54;
1342   }
1343 
1344   /// CHECK-START: int Main.$noinline$doubleConditionEqualZero(double) builder (after)
1345   /// CHECK:                            LessThanOrEqual
1346 
1347   /// CHECK-START: int Main.$noinline$doubleConditionEqualZero(double) instruction_simplifier$before_codegen (after)
1348   /// CHECK-DAG:      <<Arg:d\d+>>      ParameterValue
1349   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
1350   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
1351   /// CHECK-DAG:      <<Const42:d\d+>>  DoubleConstant 42
1352   /// CHECK-DAG:      <<LE:z\d+>>       LessThanOrEqual [<<Arg>>,<<Const42>>]
1353   /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Const13>>,<<Const54>>,<<LE>>]
1354   /// CHECK-DAG:                        Return [<<Select>>]
1355 
$noinline$doubleConditionEqualZero(double d)1356   public static int $noinline$doubleConditionEqualZero(double d) {
1357     return ((d > 42.0) != false) ? 13 : 54;
1358   }
1359 
1360   /// CHECK-START: int Main.$noinline$intToDoubleToInt(int) instruction_simplifier (before)
1361   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1362   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1363   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Double>>]
1364   /// CHECK-DAG:                        Return [<<Int>>]
1365 
1366   /// CHECK-START: int Main.$noinline$intToDoubleToInt(int) instruction_simplifier (after)
1367   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1368   /// CHECK-DAG:                        Return [<<Arg>>]
1369 
1370   /// CHECK-START: int Main.$noinline$intToDoubleToInt(int) instruction_simplifier (after)
1371   /// CHECK-NOT:                        TypeConversion
1372 
$noinline$intToDoubleToInt(int value)1373   public static int $noinline$intToDoubleToInt(int value) {
1374     // Lossless conversion followed by a conversion back.
1375     return (int) (double) value;
1376   }
1377 
1378   /// CHECK-START: java.lang.String Main.$noinline$intToDoubleToIntPrint(int) instruction_simplifier (before)
1379   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1380   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1381   /// CHECK-DAG:      {{i\d+}}          TypeConversion [<<Double>>]
1382 
1383   /// CHECK-START: java.lang.String Main.$noinline$intToDoubleToIntPrint(int) instruction_simplifier (after)
1384   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1385   /// CHECK-DAG:      {{d\d+}}          TypeConversion [<<Arg>>]
1386 
1387   /// CHECK-START: java.lang.String Main.$noinline$intToDoubleToIntPrint(int) instruction_simplifier (after)
1388   /// CHECK-DAG:                        TypeConversion
1389   /// CHECK-NOT:                        TypeConversion
1390 
$noinline$intToDoubleToIntPrint(int value)1391   public static String $noinline$intToDoubleToIntPrint(int value) {
1392     // Lossless conversion followed by a conversion back
1393     // with another use of the intermediate result.
1394     double d = (double) value;
1395     int i = (int) d;
1396     return "d=" + d + ", i=" + i;
1397   }
1398 
1399   /// CHECK-START: int Main.$noinline$byteToDoubleToInt(byte) instruction_simplifier (before)
1400   /// CHECK-DAG:      <<Arg:b\d+>>      ParameterValue
1401   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1402   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Double>>]
1403   /// CHECK-DAG:                        Return [<<Int>>]
1404 
1405   /// CHECK-START: int Main.$noinline$byteToDoubleToInt(byte) instruction_simplifier (after)
1406   /// CHECK-DAG:      <<Arg:b\d+>>      ParameterValue
1407   /// CHECK-DAG:                        Return [<<Arg>>]
1408 
1409   /// CHECK-START: int Main.$noinline$byteToDoubleToInt(byte) instruction_simplifier (after)
1410   /// CHECK-NOT:                        TypeConversion
1411 
$noinline$byteToDoubleToInt(byte value)1412   public static int $noinline$byteToDoubleToInt(byte value) {
1413     // Lossless conversion followed by another conversion, use implicit conversion.
1414     return (int) (double) value;
1415   }
1416 
1417   /// CHECK-START: int Main.$noinline$floatToDoubleToInt(float) instruction_simplifier (before)
1418   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1419   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1420   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Double>>]
1421   /// CHECK-DAG:                        Return [<<Int>>]
1422 
1423   /// CHECK-START: int Main.$noinline$floatToDoubleToInt(float) instruction_simplifier (after)
1424   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1425   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Arg>>]
1426   /// CHECK-DAG:                        Return [<<Int>>]
1427 
1428   /// CHECK-START: int Main.$noinline$floatToDoubleToInt(float) instruction_simplifier (after)
1429   /// CHECK-DAG:                        TypeConversion
1430   /// CHECK-NOT:                        TypeConversion
1431 
$noinline$floatToDoubleToInt(float value)1432   public static int $noinline$floatToDoubleToInt(float value) {
1433     // Lossless conversion followed by another conversion.
1434     return (int) (double) value;
1435   }
1436 
1437   /// CHECK-START: java.lang.String Main.$noinline$floatToDoubleToIntPrint(float) instruction_simplifier (before)
1438   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1439   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1440   /// CHECK-DAG:      {{i\d+}}          TypeConversion [<<Double>>]
1441 
1442   /// CHECK-START: java.lang.String Main.$noinline$floatToDoubleToIntPrint(float) instruction_simplifier (after)
1443   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1444   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1445   /// CHECK-DAG:      {{i\d+}}          TypeConversion [<<Double>>]
1446 
$noinline$floatToDoubleToIntPrint(float value)1447   public static String $noinline$floatToDoubleToIntPrint(float value) {
1448     // Lossless conversion followed by another conversion with
1449     // an extra use of the intermediate result.
1450     double d = (double) value;
1451     int i = (int) d;
1452     return "d=" + d + ", i=" + i;
1453   }
1454 
1455   /// CHECK-START: short Main.$noinline$byteToDoubleToShort(byte) instruction_simplifier (before)
1456   /// CHECK-DAG:      <<Arg:b\d+>>      ParameterValue
1457   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1458   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Double>>]
1459   /// CHECK-DAG:      <<Short:s\d+>>    TypeConversion [<<Int>>]
1460   /// CHECK-DAG:                        Return [<<Short>>]
1461 
1462   /// CHECK-START: short Main.$noinline$byteToDoubleToShort(byte) instruction_simplifier (after)
1463   /// CHECK-DAG:      <<Arg:b\d+>>      ParameterValue
1464   /// CHECK-DAG:                        Return [<<Arg>>]
1465 
1466   /// CHECK-START: short Main.$noinline$byteToDoubleToShort(byte) instruction_simplifier (after)
1467   /// CHECK-NOT:                        TypeConversion
1468 
$noinline$byteToDoubleToShort(byte value)1469   public static short $noinline$byteToDoubleToShort(byte value) {
1470     // Originally, this is byte->double->int->short. The first conversion is lossless,
1471     // so we merge this with the second one to byte->int which we omit as it's an implicit
1472     // conversion. Then we eliminate the resulting byte->short as an implicit conversion.
1473     return (short) (double) value;
1474   }
1475 
1476   /// CHECK-START: short Main.$noinline$charToDoubleToShort(char) instruction_simplifier (before)
1477   /// CHECK-DAG:      <<Arg:c\d+>>      ParameterValue
1478   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1479   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Double>>]
1480   /// CHECK-DAG:      <<Short:s\d+>>    TypeConversion [<<Int>>]
1481   /// CHECK-DAG:                        Return [<<Short>>]
1482 
1483   /// CHECK-START: short Main.$noinline$charToDoubleToShort(char) instruction_simplifier (after)
1484   /// CHECK-DAG:      <<Arg:c\d+>>      ParameterValue
1485   /// CHECK-DAG:      <<Short:s\d+>>    TypeConversion [<<Arg>>]
1486   /// CHECK-DAG:                        Return [<<Short>>]
1487 
1488   /// CHECK-START: short Main.$noinline$charToDoubleToShort(char) instruction_simplifier (after)
1489   /// CHECK-DAG:                        TypeConversion
1490   /// CHECK-NOT:                        TypeConversion
1491 
$noinline$charToDoubleToShort(char value)1492   public static short $noinline$charToDoubleToShort(char value) {
1493     // Originally, this is char->double->int->short. The first conversion is lossless,
1494     // so we merge this with the second one to char->int which we omit as it's an implicit
1495     // conversion. Then we are left with the resulting char->short conversion.
1496     return (short) (double) value;
1497   }
1498 
1499   /// CHECK-START: short Main.$noinline$floatToIntToShort(float) instruction_simplifier (before)
1500   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1501   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Arg>>]
1502   /// CHECK-DAG:      <<Short:s\d+>>    TypeConversion [<<Int>>]
1503   /// CHECK-DAG:                        Return [<<Short>>]
1504 
1505   /// CHECK-START: short Main.$noinline$floatToIntToShort(float) instruction_simplifier (after)
1506   /// CHECK-DAG:      <<Arg:f\d+>>      ParameterValue
1507   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Arg>>]
1508   /// CHECK-DAG:      <<Short:s\d+>>    TypeConversion [<<Int>>]
1509   /// CHECK-DAG:                        Return [<<Short>>]
1510 
$noinline$floatToIntToShort(float value)1511   public static short $noinline$floatToIntToShort(float value) {
1512     // Lossy FP to integral conversion followed by another conversion: no simplification.
1513     return (short) value;
1514   }
1515 
1516   /// CHECK-START: int Main.$noinline$intToFloatToInt(int) instruction_simplifier (before)
1517   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1518   /// CHECK-DAG:      <<Float:f\d+>>    TypeConversion [<<Arg>>]
1519   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Float>>]
1520   /// CHECK-DAG:                        Return [<<Int>>]
1521 
1522   /// CHECK-START: int Main.$noinline$intToFloatToInt(int) instruction_simplifier (after)
1523   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1524   /// CHECK-DAG:      <<Float:f\d+>>    TypeConversion [<<Arg>>]
1525   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Float>>]
1526   /// CHECK-DAG:                        Return [<<Int>>]
1527 
$noinline$intToFloatToInt(int value)1528   public static int $noinline$intToFloatToInt(int value) {
1529     // Lossy integral to FP conversion followed another conversion: no simplification.
1530     return (int) (float) value;
1531   }
1532 
1533   /// CHECK-START: double Main.$noinline$longToIntToDouble(long) instruction_simplifier (before)
1534   /// CHECK-DAG:      <<Arg:j\d+>>      ParameterValue
1535   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Arg>>]
1536   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Int>>]
1537   /// CHECK-DAG:                        Return [<<Double>>]
1538 
1539   /// CHECK-START: double Main.$noinline$longToIntToDouble(long) instruction_simplifier (after)
1540   /// CHECK-DAG:      <<Arg:j\d+>>      ParameterValue
1541   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Arg>>]
1542   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Int>>]
1543   /// CHECK-DAG:                        Return [<<Double>>]
1544 
$noinline$longToIntToDouble(long value)1545   public static double $noinline$longToIntToDouble(long value) {
1546     // Lossy long-to-int conversion followed an integral to FP conversion: no simplification.
1547     return (double) (int) value;
1548   }
1549 
1550   /// CHECK-START: long Main.$noinline$longToIntToLong(long) instruction_simplifier (before)
1551   /// CHECK-DAG:      <<Arg:j\d+>>      ParameterValue
1552   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Arg>>]
1553   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Int>>]
1554   /// CHECK-DAG:                        Return [<<Long>>]
1555 
1556   /// CHECK-START: long Main.$noinline$longToIntToLong(long) instruction_simplifier (after)
1557   /// CHECK-DAG:      <<Arg:j\d+>>      ParameterValue
1558   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Arg>>]
1559   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Int>>]
1560   /// CHECK-DAG:                        Return [<<Long>>]
1561 
$noinline$longToIntToLong(long value)1562   public static long $noinline$longToIntToLong(long value) {
1563     // Lossy long-to-int conversion followed an int-to-long conversion: no simplification.
1564     return (long) (int) value;
1565   }
1566 
1567   /// CHECK-START: short Main.$noinline$shortToCharToShort(short) instruction_simplifier (before)
1568   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1569   /// CHECK-DAG:      <<Char:c\d+>>     TypeConversion [<<Arg>>]
1570   /// CHECK-DAG:      <<Short:s\d+>>    TypeConversion [<<Char>>]
1571   /// CHECK-DAG:                        Return [<<Short>>]
1572 
1573   /// CHECK-START: short Main.$noinline$shortToCharToShort(short) instruction_simplifier (after)
1574   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1575   /// CHECK-DAG:                        Return [<<Arg>>]
1576 
$noinline$shortToCharToShort(short value)1577   public static short $noinline$shortToCharToShort(short value) {
1578     // Integral conversion followed by non-widening integral conversion to original type.
1579     return (short) (char) value;
1580   }
1581 
1582   /// CHECK-START: int Main.$noinline$shortToLongToInt(short) instruction_simplifier (before)
1583   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1584   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Arg>>]
1585   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<Long>>]
1586   /// CHECK-DAG:                        Return [<<Int>>]
1587 
1588   /// CHECK-START: int Main.$noinline$shortToLongToInt(short) instruction_simplifier (after)
1589   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1590   /// CHECK-DAG:                        Return [<<Arg>>]
1591 
$noinline$shortToLongToInt(short value)1592   public static int $noinline$shortToLongToInt(short value) {
1593     // Integral conversion followed by non-widening integral conversion, use implicit conversion.
1594     return (int) (long) value;
1595   }
1596 
1597   /// CHECK-START: byte Main.$noinline$shortToCharToByte(short) instruction_simplifier (before)
1598   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1599   /// CHECK-DAG:      <<Char:c\d+>>     TypeConversion [<<Arg>>]
1600   /// CHECK-DAG:      <<Byte:b\d+>>     TypeConversion [<<Char>>]
1601   /// CHECK-DAG:                        Return [<<Byte>>]
1602 
1603   /// CHECK-START: byte Main.$noinline$shortToCharToByte(short) instruction_simplifier (after)
1604   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1605   /// CHECK-DAG:      <<Byte:b\d+>>     TypeConversion [<<Arg>>]
1606   /// CHECK-DAG:                        Return [<<Byte>>]
1607 
$noinline$shortToCharToByte(short value)1608   public static byte $noinline$shortToCharToByte(short value) {
1609     // Integral conversion followed by non-widening integral conversion losing bits
1610     // from the original type. Simplify to use only one conversion.
1611     return (byte) (char) value;
1612   }
1613 
1614   /// CHECK-START: java.lang.String Main.$noinline$shortToCharToBytePrint(short) instruction_simplifier (before)
1615   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1616   /// CHECK-DAG:      <<Char:c\d+>>     TypeConversion [<<Arg>>]
1617   /// CHECK-DAG:      {{b\d+}}          TypeConversion [<<Char>>]
1618 
1619   /// CHECK-START: java.lang.String Main.$noinline$shortToCharToBytePrint(short) instruction_simplifier (after)
1620   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1621   /// CHECK-DAG:      <<Char:c\d+>>     TypeConversion [<<Arg>>]
1622   /// CHECK-DAG:      {{b\d+}}          TypeConversion [<<Char>>]
1623 
$noinline$shortToCharToBytePrint(short value)1624   public static String $noinline$shortToCharToBytePrint(short value) {
1625     // Integral conversion followed by non-widening integral conversion losing bits
1626     // from the original type with an extra use of the intermediate result.
1627     char c = (char) value;
1628     byte b = (byte) c;
1629     return "c=" + ((int) c) + ", b=" + ((int) b);  // implicit conversions.
1630   }
1631 
1632   /// CHECK-START: long Main.$noinline$intAndSmallLongConstant(int) instruction_simplifier (before)
1633   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1634   /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant -12345678
1635   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Arg>>]
1636   /// CHECK-DAG:      <<And:j\d+>>      And [<<Long>>,<<Mask>>]
1637   /// CHECK-DAG:                        Return [<<And>>]
1638 
1639   /// CHECK-START: long Main.$noinline$intAndSmallLongConstant(int) instruction_simplifier (after)
1640   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1641   /// CHECK-DAG:      <<Mask:i\d+>>     IntConstant -12345678
1642   /// CHECK-DAG:      <<And:i\d+>>      And [<<Arg>>,<<Mask>>]
1643   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<And>>]
1644   /// CHECK-DAG:                        Return [<<Long>>]
1645 
$noinline$intAndSmallLongConstant(int value)1646   public static long $noinline$intAndSmallLongConstant(int value) {
1647     return value & -12345678L;  // Shall be simplified (constant is 32-bit).
1648   }
1649 
1650   /// CHECK-START: long Main.$noinline$intAndLargeLongConstant(int) instruction_simplifier (before)
1651   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1652   /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant 9876543210
1653   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Arg>>]
1654   /// CHECK-DAG:      <<And:j\d+>>      And [<<Long>>,<<Mask>>]
1655   /// CHECK-DAG:                        Return [<<And>>]
1656 
1657   /// CHECK-START: long Main.$noinline$intAndLargeLongConstant(int) instruction_simplifier (after)
1658   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1659   /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant 9876543210
1660   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Arg>>]
1661   /// CHECK-DAG:      <<And:j\d+>>      And [<<Long>>,<<Mask>>]
1662   /// CHECK-DAG:                        Return [<<And>>]
1663 
$noinline$intAndLargeLongConstant(int value)1664   public static long $noinline$intAndLargeLongConstant(int value) {
1665     return value & 9876543210L;  // Shall not be simplified (constant is not 32-bit).
1666   }
1667 
1668   /// CHECK-START: long Main.$noinline$intShr28And15L(int) instruction_simplifier (before)
1669   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1670   /// CHECK-DAG:      <<Shift:i\d+>>    IntConstant 28
1671   /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant 15
1672   /// CHECK-DAG:      <<Shifted:i\d+>>  Shr [<<Arg>>,<<Shift>>]
1673   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Shifted>>]
1674   /// CHECK-DAG:      <<And:j\d+>>      And [<<Long>>,<<Mask>>]
1675   /// CHECK-DAG:                        Return [<<And>>]
1676 
1677   /// CHECK-START: long Main.$noinline$intShr28And15L(int) instruction_simplifier (after)
1678   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1679   /// CHECK-DAG:      <<Shift:i\d+>>    IntConstant 28
1680   /// CHECK-DAG:      <<Shifted:i\d+>>  UShr [<<Arg>>,<<Shift>>]
1681   /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Shifted>>]
1682   /// CHECK-DAG:                        Return [<<Long>>]
1683 
$noinline$intShr28And15L(int value)1684   public static long $noinline$intShr28And15L(int value) {
1685     return (value >> 28) & 15L;
1686   }
1687 
1688   /// CHECK-START: byte Main.$noinline$longAnd0xffToByte(long) instruction_simplifier (before)
1689   /// CHECK-DAG:      <<Arg:j\d+>>      ParameterValue
1690   /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant 255
1691   /// CHECK-DAG:      <<And:j\d+>>      And [<<Mask>>,<<Arg>>]
1692   /// CHECK-DAG:      <<Int:i\d+>>      TypeConversion [<<And>>]
1693   /// CHECK-DAG:      <<Byte:b\d+>>     TypeConversion [<<Int>>]
1694   /// CHECK-DAG:                        Return [<<Byte>>]
1695 
1696   /// CHECK-START: byte Main.$noinline$longAnd0xffToByte(long) instruction_simplifier (after)
1697   /// CHECK-DAG:      <<Arg:j\d+>>      ParameterValue
1698   /// CHECK-DAG:      <<Byte:b\d+>>     TypeConversion [<<Arg>>]
1699   /// CHECK-DAG:                        Return [<<Byte>>]
1700 
1701   /// CHECK-START: byte Main.$noinline$longAnd0xffToByte(long) instruction_simplifier (after)
1702   /// CHECK-NOT:                        And
1703 
$noinline$longAnd0xffToByte(long value)1704   public static byte $noinline$longAnd0xffToByte(long value) {
1705     return (byte) (value & 0xff);
1706   }
1707 
1708   /// CHECK-START: char Main.$noinline$intAnd0x1ffffToChar(int) instruction_simplifier (before)
1709   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1710   /// CHECK-DAG:      <<Mask:i\d+>>     IntConstant 131071
1711   /// CHECK-DAG:      <<And:i\d+>>      And [<<Mask>>,<<Arg>>]
1712   /// CHECK-DAG:      <<Char:c\d+>>     TypeConversion [<<And>>]
1713   /// CHECK-DAG:                        Return [<<Char>>]
1714 
1715   /// CHECK-START: char Main.$noinline$intAnd0x1ffffToChar(int) instruction_simplifier (after)
1716   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1717   /// CHECK-DAG:      <<Char:c\d+>>     TypeConversion [<<Arg>>]
1718   /// CHECK-DAG:                        Return [<<Char>>]
1719 
1720   /// CHECK-START: char Main.$noinline$intAnd0x1ffffToChar(int) instruction_simplifier (after)
1721   /// CHECK-NOT:                        And
1722 
$noinline$intAnd0x1ffffToChar(int value)1723   public static char $noinline$intAnd0x1ffffToChar(int value) {
1724     // Keeping all significant bits and one more.
1725     return (char) (value & 0x1ffff);
1726   }
1727 
1728   /// CHECK-START: short Main.$noinline$intAnd0x17fffToShort(int) instruction_simplifier (before)
1729   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1730   /// CHECK-DAG:      <<Mask:i\d+>>     IntConstant 98303
1731   /// CHECK-DAG:      <<And:i\d+>>      And [<<Mask>>,<<Arg>>]
1732   /// CHECK-DAG:      <<Short:s\d+>>    TypeConversion [<<And>>]
1733   /// CHECK-DAG:                        Return [<<Short>>]
1734 
1735   /// CHECK-START: short Main.$noinline$intAnd0x17fffToShort(int) instruction_simplifier (after)
1736   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1737   /// CHECK-DAG:      <<Mask:i\d+>>     IntConstant 98303
1738   /// CHECK-DAG:      <<And:i\d+>>      And [<<Mask>>,<<Arg>>]
1739   /// CHECK-DAG:      <<Short:s\d+>>    TypeConversion [<<And>>]
1740   /// CHECK-DAG:                        Return [<<Short>>]
1741 
$noinline$intAnd0x17fffToShort(int value)1742   public static short $noinline$intAnd0x17fffToShort(int value) {
1743     // No simplification: clearing a significant bit.
1744     return (short) (value & 0x17fff);
1745   }
1746 
1747   /// CHECK-START: double Main.$noinline$shortAnd0xffffToShortToDouble(short) instruction_simplifier (before)
1748   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1749   /// CHECK-DAG:      <<Mask:i\d+>>     IntConstant 65535
1750   /// CHECK-DAG:      <<And:i\d+>>      And [<<Mask>>,<<Arg>>]
1751   /// CHECK-DAG:      <<Same:s\d+>>     TypeConversion [<<And>>]
1752   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Same>>]
1753   /// CHECK-DAG:                        Return [<<Double>>]
1754 
1755   /// CHECK-START: double Main.$noinline$shortAnd0xffffToShortToDouble(short) instruction_simplifier (after)
1756   /// CHECK-DAG:      <<Arg:s\d+>>      ParameterValue
1757   /// CHECK-DAG:      <<Double:d\d+>>   TypeConversion [<<Arg>>]
1758   /// CHECK-DAG:                        Return [<<Double>>]
1759 
$noinline$shortAnd0xffffToShortToDouble(short value)1760   public static double $noinline$shortAnd0xffffToShortToDouble(short value) {
1761     short same = (short) (value & 0xffff);
1762     return (double) same;
1763   }
1764 
1765   /// CHECK-START: int Main.$noinline$intReverseCondition(int) instruction_simplifier (before)
1766   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1767   /// CHECK-DAG:      <<Const42:i\d+>>  IntConstant 42
1768   /// CHECK-DAG:      <<LE:z\d+>>       LessThanOrEqual [<<Const42>>,<<Arg>>]
1769 
1770   /// CHECK-START: int Main.$noinline$intReverseCondition(int) instruction_simplifier (after)
1771   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
1772   /// CHECK-DAG:      <<Const42:i\d+>>  IntConstant 42
1773   /// CHECK-DAG:      <<GE:z\d+>>       GreaterThanOrEqual [<<Arg>>,<<Const42>>]
1774 
$noinline$intReverseCondition(int i)1775   public static int $noinline$intReverseCondition(int i) {
1776     return (42 > i) ? 13 : 54;
1777   }
1778 
1779   /// CHECK-START: int Main.$noinline$intReverseConditionNaN(int) instruction_simplifier (before)
1780   /// CHECK-DAG:      <<Const42:d\d+>>  DoubleConstant 42
1781   /// CHECK-DAG:      <<Result:d\d+>>   InvokeStaticOrDirect
1782   /// CHECK-DAG:      <<CMP:i\d+>>      Compare [<<Const42>>,<<Result>>]
1783 
1784   /// CHECK-START: int Main.$noinline$intReverseConditionNaN(int) instruction_simplifier (after)
1785   /// CHECK-DAG:      <<Const42:d\d+>>  DoubleConstant 42
1786   /// CHECK-DAG:      <<Result:d\d+>>   InvokeStaticOrDirect
1787   /// CHECK-DAG:      <<EQ:z\d+>>       Equal [<<Result>>,<<Const42>>]
1788 
$noinline$intReverseConditionNaN(int i)1789   public static int $noinline$intReverseConditionNaN(int i) {
1790     return (42 != Math.sqrt(i)) ? 13 : 54;
1791   }
1792 
$noinline$runSmaliTest(String name, boolean input)1793   public static int $noinline$runSmaliTest(String name, boolean input) {
1794     try {
1795       Class<?> c = Class.forName("SmaliTests");
1796       Method m = c.getMethod(name, boolean.class);
1797       return (Integer) m.invoke(null, input);
1798     } catch (Exception ex) {
1799       throw new Error(ex);
1800     }
1801   }
1802 
$noinline$runSmaliTest2Boolean(String name, boolean input)1803   public static boolean $noinline$runSmaliTest2Boolean(String name, boolean input) {
1804     try {
1805       Class<?> c = Class.forName("SmaliTests2");
1806       Method m = c.getMethod(name, boolean.class);
1807       return (Boolean) m.invoke(null, input);
1808     } catch (Exception ex) {
1809       throw new Error(ex);
1810     }
1811   }
1812 
$noinline$runSmaliTestInt(String postfix, String name, int arg)1813   public static int $noinline$runSmaliTestInt(String postfix, String name, int arg) {
1814     try {
1815       Class<?> c = Class.forName("SmaliTests" + postfix);
1816       Method m = c.getMethod(name, int.class);
1817       return (Integer) m.invoke(null, arg);
1818     } catch (Exception ex) {
1819       throw new Error(ex);
1820     }
1821   }
1822 
$noinline$runSmaliTestInt(String name, int arg)1823   public static int $noinline$runSmaliTestInt(String name, int arg) {
1824     return $noinline$runSmaliTestInt("", name, arg);
1825   }
1826 
$noinline$runSmaliTest2Long(String name, long arg)1827   public static long $noinline$runSmaliTest2Long(String name, long arg) {
1828     try {
1829       Class<?> c = Class.forName("SmaliTests2");
1830       Method m = c.getMethod(name, long.class);
1831       return (Long) m.invoke(null, arg);
1832     } catch (Exception ex) {
1833       throw new Error(ex);
1834     }
1835   }
1836 
1837   /// CHECK-START: int Main.$noinline$intUnnecessaryShiftMasking(int, int) instruction_simplifier (before)
1838   /// CHECK:          <<Value:i\d+>>    ParameterValue
1839   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1840   /// CHECK-DAG:      <<Const31:i\d+>>  IntConstant 31
1841   /// CHECK-DAG:      <<And:i\d+>>      And [<<Shift>>,<<Const31>>]
1842   /// CHECK-DAG:      <<Shl:i\d+>>      Shl [<<Value>>,<<And>>]
1843   /// CHECK-DAG:                        Return [<<Shl>>]
1844 
1845   /// CHECK-START: int Main.$noinline$intUnnecessaryShiftMasking(int, int) instruction_simplifier (after)
1846   /// CHECK:          <<Value:i\d+>>    ParameterValue
1847   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1848   /// CHECK-DAG:      <<Shl:i\d+>>      Shl [<<Value>>,<<Shift>>]
1849   /// CHECK-DAG:                        Return [<<Shl>>]
1850 
$noinline$intUnnecessaryShiftMasking(int value, int shift)1851   public static int $noinline$intUnnecessaryShiftMasking(int value, int shift) {
1852     return value << (shift & 31);
1853   }
1854 
1855   /// CHECK-START: long Main.$noinline$longUnnecessaryShiftMasking(long, int) instruction_simplifier (before)
1856   /// CHECK:          <<Value:j\d+>>    ParameterValue
1857   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1858   /// CHECK-DAG:      <<Const63:i\d+>>  IntConstant 63
1859   /// CHECK-DAG:      <<And:i\d+>>      And [<<Shift>>,<<Const63>>]
1860   /// CHECK-DAG:      <<Shr:j\d+>>      Shr [<<Value>>,<<And>>]
1861   /// CHECK-DAG:                        Return [<<Shr>>]
1862 
1863   /// CHECK-START: long Main.$noinline$longUnnecessaryShiftMasking(long, int) instruction_simplifier (after)
1864   /// CHECK:          <<Value:j\d+>>    ParameterValue
1865   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1866   /// CHECK-DAG:      <<Shr:j\d+>>      Shr [<<Value>>,<<Shift>>]
1867   /// CHECK-DAG:                        Return [<<Shr>>]
1868 
$noinline$longUnnecessaryShiftMasking(long value, int shift)1869   public static long $noinline$longUnnecessaryShiftMasking(long value, int shift) {
1870     return value >> (shift & 63);
1871   }
1872 
1873   /// CHECK-START: int Main.$noinline$intUnnecessaryWiderShiftMasking(int, int) instruction_simplifier (before)
1874   /// CHECK:          <<Value:i\d+>>    ParameterValue
1875   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1876   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
1877   /// CHECK-DAG:      <<And:i\d+>>      And [<<Shift>>,<<Const255>>]
1878   /// CHECK-DAG:      <<UShr:i\d+>>     UShr [<<Value>>,<<And>>]
1879   /// CHECK-DAG:                        Return [<<UShr>>]
1880 
1881   /// CHECK-START: int Main.$noinline$intUnnecessaryWiderShiftMasking(int, int) instruction_simplifier (after)
1882   /// CHECK:          <<Value:i\d+>>    ParameterValue
1883   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1884   /// CHECK-DAG:      <<UShr:i\d+>>     UShr [<<Value>>,<<Shift>>]
1885   /// CHECK-DAG:                        Return [<<UShr>>]
1886 
$noinline$intUnnecessaryWiderShiftMasking(int value, int shift)1887   public static int $noinline$intUnnecessaryWiderShiftMasking(int value, int shift) {
1888     return value >>> (shift & 0xff);
1889   }
1890 
1891   /// CHECK-START: long Main.$noinline$longSmallerShiftMasking(long, int) instruction_simplifier (before)
1892   /// CHECK:          <<Value:j\d+>>    ParameterValue
1893   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1894   /// CHECK-DAG:      <<Const3:i\d+>>   IntConstant 3
1895   /// CHECK-DAG:      <<And:i\d+>>      And [<<Shift>>,<<Const3>>]
1896   /// CHECK-DAG:      <<Shl:j\d+>>      Shl [<<Value>>,<<And>>]
1897   /// CHECK-DAG:                        Return [<<Shl>>]
1898 
1899   /// CHECK-START: long Main.$noinline$longSmallerShiftMasking(long, int) instruction_simplifier (after)
1900   /// CHECK:          <<Value:j\d+>>    ParameterValue
1901   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1902   /// CHECK-DAG:      <<Const3:i\d+>>   IntConstant 3
1903   /// CHECK-DAG:      <<And:i\d+>>      And [<<Shift>>,<<Const3>>]
1904   /// CHECK-DAG:      <<Shl:j\d+>>      Shl [<<Value>>,<<And>>]
1905   /// CHECK-DAG:                        Return [<<Shl>>]
1906 
$noinline$longSmallerShiftMasking(long value, int shift)1907   public static long $noinline$longSmallerShiftMasking(long value, int shift) {
1908     return value << (shift & 3);
1909   }
1910 
1911   /// CHECK-START: int Main.$noinline$otherUseOfUnnecessaryShiftMasking(int, int) instruction_simplifier (before)
1912   /// CHECK:          <<Value:i\d+>>    ParameterValue
1913   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1914   /// CHECK-DAG:      <<Const31:i\d+>>  IntConstant 31
1915   /// CHECK-DAG:      <<And:i\d+>>      And [<<Shift>>,<<Const31>>]
1916   /// CHECK-DAG:      <<Shr:i\d+>>      Shr [<<Value>>,<<And>>]
1917   /// CHECK-DAG:      <<Add:i\d+>>      Add [<<Shr>>,<<And>>]
1918   /// CHECK-DAG:                        Return [<<Add>>]
1919 
1920   /// CHECK-START: int Main.$noinline$otherUseOfUnnecessaryShiftMasking(int, int) instruction_simplifier (after)
1921   /// CHECK:          <<Value:i\d+>>    ParameterValue
1922   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1923   /// CHECK-DAG:      <<Const31:i\d+>>  IntConstant 31
1924   /// CHECK-DAG:      <<And:i\d+>>      And [<<Shift>>,<<Const31>>]
1925   /// CHECK-DAG:      <<Shr:i\d+>>      Shr [<<Value>>,<<Shift>>]
1926   /// CHECK-DAG:      <<Add:i\d+>>      Add [<<Shr>>,<<And>>]
1927   /// CHECK-DAG:                        Return [<<Add>>]
1928 
$noinline$otherUseOfUnnecessaryShiftMasking(int value, int shift)1929   public static int $noinline$otherUseOfUnnecessaryShiftMasking(int value, int shift) {
1930     int temp = shift & 31;
1931     return (value >> temp) + temp;
1932   }
1933 
1934   /// CHECK-START: int Main.$noinline$intUnnecessaryShiftModifications(int, int) instruction_simplifier (before)
1935   /// CHECK:          <<Value:i\d+>>    ParameterValue
1936   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1937   /// CHECK-DAG:      <<Const32:i\d+>>  IntConstant 32
1938   /// CHECK-DAG:      <<Const64:i\d+>>  IntConstant 64
1939   /// CHECK-DAG:      <<Const96:i\d+>>  IntConstant 96
1940   /// CHECK-DAG:      <<Const128:i\d+>> IntConstant 128
1941   /// CHECK-DAG:      <<Or:i\d+>>       Or [<<Shift>>,<<Const32>>]
1942   /// CHECK-DAG:      <<Xor:i\d+>>      Xor [<<Shift>>,<<Const64>>]
1943   /// CHECK-DAG:      <<Add:i\d+>>      Add [<<Shift>>,<<Const96>>]
1944   /// CHECK-DAG:      <<Sub:i\d+>>      Sub [<<Shift>>,<<Const128>>]
1945   /// CHECK-DAG:      <<Conv:b\d+>>     TypeConversion [<<Shift>>]
1946   /// CHECK-DAG:                        Shl [<<Value>>,<<Or>>]
1947   /// CHECK-DAG:                        Shr [<<Value>>,<<Xor>>]
1948   /// CHECK-DAG:                        UShr [<<Value>>,<<Add>>]
1949   /// CHECK-DAG:                        Shl [<<Value>>,<<Sub>>]
1950   /// CHECK-DAG:                        Shr [<<Value>>,<<Conv>>]
1951 
1952   /// CHECK-START: int Main.$noinline$intUnnecessaryShiftModifications(int, int) instruction_simplifier (after)
1953   /// CHECK:          <<Value:i\d+>>    ParameterValue
1954   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1955   /// CHECK-DAG:                        Shl [<<Value>>,<<Shift>>]
1956   /// CHECK-DAG:                        Shr [<<Value>>,<<Shift>>]
1957   /// CHECK-DAG:                        UShr [<<Value>>,<<Shift>>]
1958   /// CHECK-DAG:                        Shl [<<Value>>,<<Shift>>]
1959   /// CHECK-DAG:                        Shr [<<Value>>,<<Shift>>]
1960 
$noinline$intUnnecessaryShiftModifications(int value, int shift)1961   public static int $noinline$intUnnecessaryShiftModifications(int value, int shift) {
1962     int c128 = 128;
1963     return (value << (shift | 32)) +
1964            (value >> (shift ^ 64)) +
1965            (value >>> (shift + 96)) +
1966            (value << (shift - c128)) +  // Needs a named constant to generate Sub.
1967            (value >> ((byte) shift));
1968   }
1969 
1970   /// CHECK-START: int Main.$noinline$intNecessaryShiftModifications(int, int) instruction_simplifier (before)
1971   /// CHECK:          <<Value:i\d+>>    ParameterValue
1972   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1973   /// CHECK-DAG:      <<Const33:i\d+>>  IntConstant 33
1974   /// CHECK-DAG:      <<Const65:i\d+>>  IntConstant 65
1975   /// CHECK-DAG:      <<Const97:i\d+>>  IntConstant 97
1976   /// CHECK-DAG:      <<Const129:i\d+>> IntConstant 129
1977   /// CHECK-DAG:      <<Or:i\d+>>       Or [<<Shift>>,<<Const33>>]
1978   /// CHECK-DAG:      <<Xor:i\d+>>      Xor [<<Shift>>,<<Const65>>]
1979   /// CHECK-DAG:      <<Add:i\d+>>      Add [<<Shift>>,<<Const97>>]
1980   /// CHECK-DAG:      <<Sub:i\d+>>      Sub [<<Shift>>,<<Const129>>]
1981   /// CHECK-DAG:                        Shl [<<Value>>,<<Or>>]
1982   /// CHECK-DAG:                        Shr [<<Value>>,<<Xor>>]
1983   /// CHECK-DAG:                        UShr [<<Value>>,<<Add>>]
1984   /// CHECK-DAG:                        Shl [<<Value>>,<<Sub>>]
1985 
1986   /// CHECK-START: int Main.$noinline$intNecessaryShiftModifications(int, int) instruction_simplifier (after)
1987   /// CHECK:          <<Value:i\d+>>    ParameterValue
1988   /// CHECK:          <<Shift:i\d+>>    ParameterValue
1989   /// CHECK-DAG:      <<Const33:i\d+>>  IntConstant 33
1990   /// CHECK-DAG:      <<Const65:i\d+>>  IntConstant 65
1991   /// CHECK-DAG:      <<Const97:i\d+>>  IntConstant 97
1992   /// CHECK-DAG:      <<Const129:i\d+>> IntConstant 129
1993   /// CHECK-DAG:      <<Or:i\d+>>       Or [<<Shift>>,<<Const33>>]
1994   /// CHECK-DAG:      <<Xor:i\d+>>      Xor [<<Shift>>,<<Const65>>]
1995   /// CHECK-DAG:      <<Add:i\d+>>      Add [<<Shift>>,<<Const97>>]
1996   /// CHECK-DAG:      <<Sub:i\d+>>      Sub [<<Shift>>,<<Const129>>]
1997   /// CHECK-DAG:                        Shl [<<Value>>,<<Or>>]
1998   /// CHECK-DAG:                        Shr [<<Value>>,<<Xor>>]
1999   /// CHECK-DAG:                        UShr [<<Value>>,<<Add>>]
2000   /// CHECK-DAG:                        Shl [<<Value>>,<<Sub>>]
2001 
$noinline$intNecessaryShiftModifications(int value, int shift)2002   public static int $noinline$intNecessaryShiftModifications(int value, int shift) {
2003     int c129 = 129;
2004     return (value << (shift | 33)) +
2005            (value >> (shift ^ 65)) +
2006            (value >>> (shift + 97)) +
2007            (value << (shift - c129));  // Needs a named constant to generate Sub.
2008   }
2009 
2010   /// CHECK-START: int Main.$noinline$intAddSubSimplifyArg1(int, int) instruction_simplifier (before)
2011   /// CHECK:          <<X:i\d+>>        ParameterValue
2012   /// CHECK:          <<Y:i\d+>>        ParameterValue
2013   /// CHECK-DAG:      <<Sum:i\d+>>      Add [<<X>>,<<Y>>]
2014   /// CHECK-DAG:      <<Res:i\d+>>      Sub [<<Sum>>,<<X>>]
2015   /// CHECK-DAG:                        Return [<<Res>>]
2016 
2017   /// CHECK-START: int Main.$noinline$intAddSubSimplifyArg1(int, int) instruction_simplifier (after)
2018   /// CHECK:          <<X:i\d+>>        ParameterValue
2019   /// CHECK:          <<Y:i\d+>>        ParameterValue
2020   /// CHECK-DAG:      <<Sum:i\d+>>      Add [<<X>>,<<Y>>]
2021   /// CHECK-DAG:                        Return [<<Y>>]
2022 
$noinline$intAddSubSimplifyArg1(int x, int y)2023   public static int $noinline$intAddSubSimplifyArg1(int x, int y) {
2024     int sum = x + y;
2025     return sum - x;
2026   }
2027 
2028   /// CHECK-START: int Main.$noinline$intAddSubSimplifyArg2(int, int) instruction_simplifier (before)
2029   /// CHECK:          <<X:i\d+>>        ParameterValue
2030   /// CHECK:          <<Y:i\d+>>        ParameterValue
2031   /// CHECK-DAG:      <<Sum:i\d+>>      Add [<<X>>,<<Y>>]
2032   /// CHECK-DAG:      <<Res:i\d+>>      Sub [<<Sum>>,<<Y>>]
2033   /// CHECK-DAG:                        Return [<<Res>>]
2034 
2035   /// CHECK-START: int Main.$noinline$intAddSubSimplifyArg2(int, int) instruction_simplifier (after)
2036   /// CHECK:          <<X:i\d+>>        ParameterValue
2037   /// CHECK:          <<Y:i\d+>>        ParameterValue
2038   /// CHECK-DAG:      <<Sum:i\d+>>      Add [<<X>>,<<Y>>]
2039   /// CHECK-DAG:                        Return [<<X>>]
2040 
$noinline$intAddSubSimplifyArg2(int x, int y)2041   public static int $noinline$intAddSubSimplifyArg2(int x, int y) {
2042     int sum = x + y;
2043     return sum - y;
2044   }
2045 
2046   /// CHECK-START: int Main.$noinline$intSubAddSimplifyLeft(int, int) instruction_simplifier (before)
2047   /// CHECK:          <<X:i\d+>>        ParameterValue
2048   /// CHECK:          <<Y:i\d+>>        ParameterValue
2049   /// CHECK-DAG:      <<Sub:i\d+>>      Sub [<<X>>,<<Y>>]
2050   /// CHECK-DAG:      <<Res:i\d+>>      Add [<<Sub>>,<<Y>>]
2051   /// CHECK-DAG:                        Return [<<Res>>]
2052 
2053   /// CHECK-START: int Main.$noinline$intSubAddSimplifyLeft(int, int) instruction_simplifier (after)
2054   /// CHECK:          <<X:i\d+>>        ParameterValue
2055   /// CHECK:          <<Y:i\d+>>        ParameterValue
2056   /// CHECK-DAG:      <<Sub:i\d+>>      Sub [<<X>>,<<Y>>]
2057   /// CHECK-DAG:                        Return [<<X>>]
2058 
$noinline$intSubAddSimplifyLeft(int x, int y)2059   public static int $noinline$intSubAddSimplifyLeft(int x, int y) {
2060     int sub = x - y;
2061     return sub + y;
2062   }
2063 
2064   /// CHECK-START: int Main.$noinline$intSubAddSimplifyRight(int, int) instruction_simplifier (before)
2065   /// CHECK:          <<X:i\d+>>        ParameterValue
2066   /// CHECK:          <<Y:i\d+>>        ParameterValue
2067   /// CHECK-DAG:      <<Sub:i\d+>>      Sub [<<X>>,<<Y>>]
2068   /// CHECK-DAG:      <<Res:i\d+>>      Add [<<Y>>,<<Sub>>]
2069   /// CHECK-DAG:                        Return [<<Res>>]
2070 
2071   /// CHECK-START: int Main.$noinline$intSubAddSimplifyRight(int, int) instruction_simplifier (after)
2072   /// CHECK:          <<X:i\d+>>        ParameterValue
2073   /// CHECK:          <<Y:i\d+>>        ParameterValue
2074   /// CHECK-DAG:      <<Sub:i\d+>>      Sub [<<X>>,<<Y>>]
2075   /// CHECK-DAG:                        Return [<<X>>]
2076 
$noinline$intSubAddSimplifyRight(int x, int y)2077   public static int $noinline$intSubAddSimplifyRight(int x, int y) {
2078     int sub = x - y;
2079     return y + sub;
2080   }
2081 
2082   /// CHECK-START: float Main.$noinline$floatAddSubSimplifyArg1(float, float) instruction_simplifier (before)
2083   /// CHECK:          <<X:f\d+>>        ParameterValue
2084   /// CHECK:          <<Y:f\d+>>        ParameterValue
2085   /// CHECK-DAG:      <<Sum:f\d+>>      Add [<<X>>,<<Y>>]
2086   /// CHECK-DAG:      <<Res:f\d+>>      Sub [<<Sum>>,<<X>>]
2087   /// CHECK-DAG:                        Return [<<Res>>]
2088 
2089   /// CHECK-START: float Main.$noinline$floatAddSubSimplifyArg1(float, float) instruction_simplifier (after)
2090   /// CHECK:          <<X:f\d+>>        ParameterValue
2091   /// CHECK:          <<Y:f\d+>>        ParameterValue
2092   /// CHECK-DAG:      <<Sum:f\d+>>      Add [<<X>>,<<Y>>]
2093   /// CHECK-DAG:      <<Res:f\d+>>      Sub [<<Sum>>,<<X>>]
2094   /// CHECK-DAG:                        Return [<<Res>>]
2095 
$noinline$floatAddSubSimplifyArg1(float x, float y)2096   public static float $noinline$floatAddSubSimplifyArg1(float x, float y) {
2097     float sum = x + y;
2098     return sum - x;
2099   }
2100 
2101   /// CHECK-START: float Main.$noinline$floatAddSubSimplifyArg2(float, float) instruction_simplifier (before)
2102   /// CHECK:          <<X:f\d+>>        ParameterValue
2103   /// CHECK:          <<Y:f\d+>>        ParameterValue
2104   /// CHECK-DAG:      <<Sum:f\d+>>      Add [<<X>>,<<Y>>]
2105   /// CHECK-DAG:      <<Res:f\d+>>      Sub [<<Sum>>,<<Y>>]
2106   /// CHECK-DAG:                        Return [<<Res>>]
2107 
2108   /// CHECK-START: float Main.$noinline$floatAddSubSimplifyArg2(float, float) instruction_simplifier (after)
2109   /// CHECK:          <<X:f\d+>>        ParameterValue
2110   /// CHECK:          <<Y:f\d+>>        ParameterValue
2111   /// CHECK-DAG:      <<Sum:f\d+>>      Add [<<X>>,<<Y>>]
2112   /// CHECK-DAG:      <<Res:f\d+>>      Sub [<<Sum>>,<<Y>>]
2113   /// CHECK-DAG:                        Return [<<Res>>]
2114 
$noinline$floatAddSubSimplifyArg2(float x, float y)2115   public static float $noinline$floatAddSubSimplifyArg2(float x, float y) {
2116     float sum = x + y;
2117     return sum - y;
2118   }
2119 
2120   /// CHECK-START: float Main.$noinline$floatSubAddSimplifyLeft(float, float) instruction_simplifier (before)
2121   /// CHECK:          <<X:f\d+>>        ParameterValue
2122   /// CHECK:          <<Y:f\d+>>        ParameterValue
2123   /// CHECK-DAG:      <<Sub:f\d+>>      Sub [<<X>>,<<Y>>]
2124   /// CHECK-DAG:      <<Res:f\d+>>      Add [<<Sub>>,<<Y>>]
2125   /// CHECK-DAG:                        Return [<<Res>>]
2126 
2127   /// CHECK-START: float Main.$noinline$floatSubAddSimplifyLeft(float, float) instruction_simplifier (after)
2128   /// CHECK:          <<X:f\d+>>        ParameterValue
2129   /// CHECK:          <<Y:f\d+>>        ParameterValue
2130   /// CHECK-DAG:      <<Sub:f\d+>>      Sub [<<X>>,<<Y>>]
2131   /// CHECK-DAG:      <<Res:f\d+>>      Add [<<Sub>>,<<Y>>]
2132   /// CHECK-DAG:                        Return [<<Res>>]
2133 
$noinline$floatSubAddSimplifyLeft(float x, float y)2134   public static float $noinline$floatSubAddSimplifyLeft(float x, float y) {
2135     float sub = x - y;
2136     return sub + y;
2137   }
2138 
2139   /// CHECK-START: float Main.$noinline$floatSubAddSimplifyRight(float, float) instruction_simplifier (before)
2140   /// CHECK:          <<X:f\d+>>        ParameterValue
2141   /// CHECK:          <<Y:f\d+>>        ParameterValue
2142   /// CHECK-DAG:      <<Sub:f\d+>>      Sub [<<X>>,<<Y>>]
2143   /// CHECK-DAG:      <<Res:f\d+>>      Add [<<Y>>,<<Sub>>]
2144   /// CHECK-DAG:                        Return [<<Res>>]
2145 
2146   /// CHECK-START: float Main.$noinline$floatSubAddSimplifyRight(float, float) instruction_simplifier (after)
2147   /// CHECK:          <<X:f\d+>>        ParameterValue
2148   /// CHECK:          <<Y:f\d+>>        ParameterValue
2149   /// CHECK-DAG:      <<Sub:f\d+>>      Sub [<<X>>,<<Y>>]
2150   /// CHECK-DAG:      <<Res:f\d+>>      Add [<<Y>>,<<Sub>>]
2151   /// CHECK-DAG:                        Return [<<Res>>]
2152 
$noinline$floatSubAddSimplifyRight(float x, float y)2153   public static float $noinline$floatSubAddSimplifyRight(float x, float y) {
2154     float sub = x - y;
2155     return y + sub;
2156   }
2157 
2158   /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteField(Main) instruction_simplifier (before)
2159   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2160   /// CHECK-DAG:      <<Get:b\d+>>      InstanceFieldGet
2161   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Const255>>]
2162   /// CHECK-DAG:                        Return [<<And>>]
2163 
2164   /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteField(Main) instruction_simplifier (after)
2165   /// CHECK-DAG:      <<Get:a\d+>>      InstanceFieldGet
2166   /// CHECK-DAG:                        Return [<<Get>>]
2167 
2168   /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteField(Main) instruction_simplifier (after)
2169   /// CHECK-NOT:                        And
2170   /// CHECK-NOT:                        TypeConversion
$noinline$getUint8FromInstanceByteField(Main m)2171   public static int $noinline$getUint8FromInstanceByteField(Main m) {
2172     return m.instanceByteField & 0xff;
2173   }
2174 
2175   /// CHECK-START: int Main.$noinline$getUint8FromStaticByteField() instruction_simplifier (before)
2176   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2177   /// CHECK-DAG:      <<Get:b\d+>>      StaticFieldGet
2178   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Const255>>]
2179   /// CHECK-DAG:                        Return [<<And>>]
2180 
2181   /// CHECK-START: int Main.$noinline$getUint8FromStaticByteField() instruction_simplifier (after)
2182   /// CHECK-DAG:      <<Get:a\d+>>      StaticFieldGet
2183   /// CHECK-DAG:                        Return [<<Get>>]
2184 
2185   /// CHECK-START: int Main.$noinline$getUint8FromStaticByteField() instruction_simplifier (after)
2186   /// CHECK-NOT:                        And
2187   /// CHECK-NOT:                        TypeConversion
$noinline$getUint8FromStaticByteField()2188   public static int $noinline$getUint8FromStaticByteField() {
2189     return staticByteField & 0xff;
2190   }
2191 
2192   /// CHECK-START: int Main.$noinline$getUint8FromByteArray(byte[]) instruction_simplifier (before)
2193   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2194   /// CHECK-DAG:      <<Get:b\d+>>      ArrayGet
2195   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Const255>>]
2196   /// CHECK-DAG:                        Return [<<And>>]
2197 
2198   /// CHECK-START: int Main.$noinline$getUint8FromByteArray(byte[]) instruction_simplifier (after)
2199   /// CHECK-DAG:      <<Get:a\d+>>      ArrayGet
2200   /// CHECK-DAG:                        Return [<<Get>>]
2201 
2202   /// CHECK-START: int Main.$noinline$getUint8FromByteArray(byte[]) instruction_simplifier (after)
2203   /// CHECK-NOT:                        And
2204   /// CHECK-NOT:                        TypeConversion
$noinline$getUint8FromByteArray(byte[] a)2205   public static int $noinline$getUint8FromByteArray(byte[] a) {
2206     return a[0] & 0xff;
2207   }
2208 
2209   /// CHECK-START: int Main.$noinline$getUint16FromInstanceShortField(Main) instruction_simplifier (before)
2210   /// CHECK-DAG:      <<Cst65535:i\d+>> IntConstant 65535
2211   /// CHECK-DAG:      <<Get:s\d+>>      InstanceFieldGet
2212   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Cst65535>>]
2213   /// CHECK-DAG:                        Return [<<And>>]
2214 
2215   /// CHECK-START: int Main.$noinline$getUint16FromInstanceShortField(Main) instruction_simplifier (after)
2216   /// CHECK-DAG:      <<Get:c\d+>>      InstanceFieldGet
2217   /// CHECK-DAG:                        Return [<<Get>>]
2218 
2219   /// CHECK-START: int Main.$noinline$getUint16FromInstanceShortField(Main) instruction_simplifier (after)
2220   /// CHECK-NOT:                        And
2221   /// CHECK-NOT:                        TypeConversion
$noinline$getUint16FromInstanceShortField(Main m)2222   public static int $noinline$getUint16FromInstanceShortField(Main m) {
2223     return m.instanceShortField & 0xffff;
2224   }
2225 
2226   /// CHECK-START: int Main.$noinline$getUint16FromStaticShortField() instruction_simplifier (before)
2227   /// CHECK-DAG:      <<Cst65535:i\d+>> IntConstant 65535
2228   /// CHECK-DAG:      <<Get:s\d+>>      StaticFieldGet
2229   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Cst65535>>]
2230   /// CHECK-DAG:                        Return [<<And>>]
2231 
2232   /// CHECK-START: int Main.$noinline$getUint16FromStaticShortField() instruction_simplifier (after)
2233   /// CHECK-DAG:      <<Get:c\d+>>      StaticFieldGet
2234   /// CHECK-DAG:                        Return [<<Get>>]
2235 
2236   /// CHECK-START: int Main.$noinline$getUint16FromStaticShortField() instruction_simplifier (after)
2237   /// CHECK-NOT:                        And
2238   /// CHECK-NOT:                        TypeConversion
$noinline$getUint16FromStaticShortField()2239   public static int $noinline$getUint16FromStaticShortField() {
2240     return staticShortField & 0xffff;
2241   }
2242 
2243   /// CHECK-START: int Main.$noinline$getUint16FromShortArray(short[]) instruction_simplifier (before)
2244   /// CHECK-DAG:      <<Cst65535:i\d+>> IntConstant 65535
2245   /// CHECK-DAG:      <<Get:s\d+>>      ArrayGet
2246   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Cst65535>>]
2247   /// CHECK-DAG:                        Return [<<And>>]
2248 
2249   /// CHECK-START: int Main.$noinline$getUint16FromShortArray(short[]) instruction_simplifier (after)
2250   /// CHECK-DAG:      <<Get:c\d+>>      ArrayGet
2251   /// CHECK-DAG:                        Return [<<Get>>]
2252 
2253   /// CHECK-START: int Main.$noinline$getUint16FromShortArray(short[]) instruction_simplifier (after)
2254   /// CHECK-NOT:                        And
2255   /// CHECK-NOT:                        TypeConversion
$noinline$getUint16FromShortArray(short[] a)2256   public static int $noinline$getUint16FromShortArray(short[] a) {
2257     return a[0] & 0xffff;
2258   }
2259 
2260   /// CHECK-START: int Main.$noinline$getInt16FromInstanceCharField(Main) instruction_simplifier (before)
2261   /// CHECK-DAG:      <<Get:c\d+>>      InstanceFieldGet
2262   /// CHECK-DAG:      <<Conv:s\d+>>     TypeConversion [<<Get>>]
2263   /// CHECK-DAG:                        Return [<<Conv>>]
2264 
2265   /// CHECK-START: int Main.$noinline$getInt16FromInstanceCharField(Main) instruction_simplifier (after)
2266   /// CHECK-DAG:      <<Get:s\d+>>      InstanceFieldGet
2267   /// CHECK-DAG:                        Return [<<Get>>]
2268 
2269   /// CHECK-START: int Main.$noinline$getInt16FromInstanceCharField(Main) instruction_simplifier (after)
2270   /// CHECK-NOT:                        And
2271   /// CHECK-NOT:                        TypeConversion
$noinline$getInt16FromInstanceCharField(Main m)2272   public static int $noinline$getInt16FromInstanceCharField(Main m) {
2273     return (short) m.instanceCharField;
2274   }
2275 
2276   /// CHECK-START: int Main.$noinline$getInt16FromStaticCharField() instruction_simplifier (before)
2277   /// CHECK-DAG:      <<Get:c\d+>>      StaticFieldGet
2278   /// CHECK-DAG:      <<Conv:s\d+>>     TypeConversion [<<Get>>]
2279   /// CHECK-DAG:                        Return [<<Conv>>]
2280 
2281   /// CHECK-START: int Main.$noinline$getInt16FromStaticCharField() instruction_simplifier (after)
2282   /// CHECK-DAG:      <<Get:s\d+>>      StaticFieldGet
2283   /// CHECK-DAG:                        Return [<<Get>>]
2284 
2285   /// CHECK-START: int Main.$noinline$getInt16FromStaticCharField() instruction_simplifier (after)
2286   /// CHECK-NOT:                        And
2287   /// CHECK-NOT:                        TypeConversion
$noinline$getInt16FromStaticCharField()2288   public static int $noinline$getInt16FromStaticCharField() {
2289     return (short) staticCharField;
2290   }
2291 
2292   /// CHECK-START: int Main.$noinline$getInt16FromCharArray(char[]) instruction_simplifier (before)
2293   /// CHECK-DAG:      <<Get:c\d+>>      ArrayGet
2294   /// CHECK-DAG:      <<Conv:s\d+>>     TypeConversion [<<Get>>]
2295   /// CHECK-DAG:                        Return [<<Conv>>]
2296 
2297   /// CHECK-START: int Main.$noinline$getInt16FromCharArray(char[]) instruction_simplifier (after)
2298   /// CHECK-DAG:      <<Get:s\d+>>      ArrayGet
2299   /// CHECK-DAG:                        Return [<<Get>>]
2300 
2301   /// CHECK-START: int Main.$noinline$getInt16FromCharArray(char[]) instruction_simplifier (after)
2302   /// CHECK-NOT:                        And
2303   /// CHECK-NOT:                        TypeConversion
$noinline$getInt16FromCharArray(char[] a)2304   public static int $noinline$getInt16FromCharArray(char[] a) {
2305     return (short) a[0];
2306   }
2307 
2308   /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier (before)
2309   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2310   /// CHECK-DAG:      <<Get:b\d+>>      StaticFieldGet
2311   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Const255>>]
2312   /// CHECK-DAG:      <<Invoke:i\d+>>   InvokeStaticOrDirect [<<And>>{{(,[ij]\d+)?}}]
2313   /// CHECK-DAG:                        Return [<<Invoke>>]
2314 
2315   /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier (after)
2316   /// CHECK-DAG:      <<Get:a\d+>>      StaticFieldGet
2317   /// CHECK-DAG:      <<Invoke:i\d+>>   InvokeStaticOrDirect [<<Get>>{{(,[ij]\d+)?}}]
2318   /// CHECK-DAG:                        Return [<<Invoke>>]
2319 
2320   /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier$after_inlining (before)
2321   /// CHECK-DAG:      <<Get:a\d+>>      StaticFieldGet
2322   /// CHECK-DAG:      <<Conv:b\d+>>     TypeConversion [<<Get>>]
2323   /// CHECK-DAG:                        Return [<<Conv>>]
2324 
2325   /// CHECK-START: int Main.$noinline$byteToUint8AndBack() instruction_simplifier$after_inlining (after)
2326   /// CHECK-DAG:      <<Get:b\d+>>      StaticFieldGet
2327   /// CHECK-DAG:                        Return [<<Get>>]
$noinline$byteToUint8AndBack()2328   public static int $noinline$byteToUint8AndBack() {
2329     return $inline$toByte(staticByteField & 0xff);
2330   }
2331 
$inline$toByte(int value)2332   public static int $inline$toByte(int value) {
2333     return (byte) value;
2334   }
2335 
2336   /// CHECK-START: int Main.$noinline$getStaticCharFieldAnd0xff() instruction_simplifier (before)
2337   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2338   /// CHECK-DAG:      <<Get:c\d+>>      StaticFieldGet
2339   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Const255>>]
2340   /// CHECK-DAG:                        Return [<<And>>]
2341 
2342   /// CHECK-START: int Main.$noinline$getStaticCharFieldAnd0xff() instruction_simplifier (after)
2343   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2344   /// CHECK-DAG:      <<Get:c\d+>>      StaticFieldGet
2345   /// CHECK-DAG:      <<Cnv:a\d+>>      TypeConversion [<<Get>>]
2346   /// CHECK-DAG:                        Return [<<Cnv>>]
2347 
2348   /// CHECK-START: int Main.$noinline$getStaticCharFieldAnd0xff() instruction_simplifier (after)
2349   /// CHECK-NOT:      {{a\d+}}          StaticFieldGet
$noinline$getStaticCharFieldAnd0xff()2350   public static int $noinline$getStaticCharFieldAnd0xff() {
2351     return staticCharField & 0xff;
2352   }
2353 
2354   /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main) instruction_simplifier (before)
2355   /// CHECK-DAG:      <<Const8:i\d+>>   IntConstant 8
2356   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2357   /// CHECK-DAG:      <<Get:b\d+>>      InstanceFieldGet
2358   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Const255>>]
2359   /// CHECK-DAG:      <<Shl:i\d+>>      Shl [<<Get>>,<<Const8>>]
2360   /// CHECK-DAG:      <<Add:i\d+>>      Add [<<And>>,<<Shl>>]
2361   /// CHECK-DAG:                        Return [<<Add>>]
2362 
2363   /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main) instruction_simplifier (after)
2364   /// CHECK-DAG:      <<Const8:i\d+>>   IntConstant 8
2365   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2366   /// CHECK-DAG:      <<Get:b\d+>>      InstanceFieldGet
2367   /// CHECK-DAG:      <<Cnv:a\d+>>      TypeConversion [<<Get>>]
2368   /// CHECK-DAG:      <<Shl:i\d+>>      Shl [<<Get>>,<<Const8>>]
2369   /// CHECK-DAG:      <<Add:i\d+>>      Add [<<Cnv>>,<<Shl>>]
2370   /// CHECK-DAG:                        Return [<<Add>>]
2371 
2372   /// CHECK-START: int Main.$noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main) instruction_simplifier (after)
2373   /// CHECK-NOT:      {{a\d+}}          InstanceFieldGet
$noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main m)2374   public static int $noinline$getUint8FromInstanceByteFieldWithAnotherUse(Main m) {
2375     byte b = m.instanceByteField;
2376     int v1 = b & 0xff;
2377     int v2 = (b << 8);
2378     return v1 + v2;
2379   }
2380 
2381   /// CHECK-START: int Main.$noinline$intAnd0xffToChar(int) instruction_simplifier (before)
2382   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
2383   /// CHECK-DAG:      <<Const255:i\d+>> IntConstant 255
2384   /// CHECK-DAG:      <<And:i\d+>>      And [<<Arg>>,<<Const255>>]
2385   /// CHECK-DAG:      <<Conv:c\d+>>     TypeConversion [<<And>>]
2386   /// CHECK-DAG:                        Return [<<Conv>>]
2387 
2388   /// CHECK-START: int Main.$noinline$intAnd0xffToChar(int) instruction_simplifier (after)
2389   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
2390   /// CHECK-DAG:      <<Conv:a\d+>>     TypeConversion [<<Arg>>]
2391   /// CHECK-DAG:                        Return [<<Conv>>]
$noinline$intAnd0xffToChar(int value)2392   public static int $noinline$intAnd0xffToChar(int value) {
2393     return (char) (value & 0xff);
2394   }
2395 
2396   /// CHECK-START: int Main.$noinline$intAnd0x1ffToChar(int) instruction_simplifier (before)
2397   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
2398   /// CHECK-DAG:      <<Const511:i\d+>> IntConstant 511
2399   /// CHECK-DAG:      <<And:i\d+>>      And [<<Arg>>,<<Const511>>]
2400   /// CHECK-DAG:      <<Conv:c\d+>>     TypeConversion [<<And>>]
2401   /// CHECK-DAG:                        Return [<<Conv>>]
2402 
2403   // TODO: Simplify this. Unlike the $noinline$intAnd0xffToChar(), the TypeConversion
2404   // to `char` is not eliminated despite the result of the And being within the `char` range.
2405 
2406   // CHECK-START: int Main.$noinline$intAnd0x1ffToChar(int) instruction_simplifier (after)
2407   // CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
2408   // CHECK-DAG:      <<Const511:i\d+>> IntConstant 511
2409   // CHECK-DAG:      <<And:i\d+>>      And [<<Arg>>,<<Const511>>]
2410   // CHECK-DAG:                        Return [<<And>>]
$noinline$intAnd0x1ffToChar(int value)2411   public static int $noinline$intAnd0x1ffToChar(int value) {
2412     return (char) (value & 0x1ff);
2413   }
2414 
2415   /// CHECK-START: int Main.$noinline$getInstanceCharFieldAnd0x1ffff(Main) instruction_simplifier (before)
2416   /// CHECK-DAG:      <<Cst1ffff:i\d+>> IntConstant 131071
2417   /// CHECK-DAG:      <<Get:c\d+>>      InstanceFieldGet
2418   /// CHECK-DAG:      <<And:i\d+>>      And [<<Get>>,<<Cst1ffff>>]
2419   /// CHECK-DAG:                        Return [<<And>>]
2420 
2421   /// CHECK-START: int Main.$noinline$getInstanceCharFieldAnd0x1ffff(Main) instruction_simplifier (after)
2422   /// CHECK-DAG:      <<Get:c\d+>>      InstanceFieldGet
2423   /// CHECK-DAG:                        Return [<<Get>>]
$noinline$getInstanceCharFieldAnd0x1ffff(Main m)2424   public static int $noinline$getInstanceCharFieldAnd0x1ffff(Main m) {
2425     return m.instanceCharField & 0x1ffff;
2426   }
2427 
2428   /// CHECK-START: int Main.$noinline$bug68142795Byte(byte) instruction_simplifier (before)
2429   /// CHECK-DAG:      <<Arg:b\d+>>      ParameterValue
2430   /// CHECK-DAG:      <<Const:i\d+>>    IntConstant 255
2431   /// CHECK-DAG:      <<And1:i\d+>>     And [<<Arg>>,<<Const>>]
2432   /// CHECK-DAG:      <<And2:i\d+>>     And [<<And1>>,<<Const>>]
2433   /// CHECK-DAG:      <<Conv:b\d+>>     TypeConversion [<<And2>>]
2434   /// CHECK-DAG:                        Return [<<Conv>>]
2435 
2436   /// CHECK-START: int Main.$noinline$bug68142795Byte(byte) instruction_simplifier (after)
2437   /// CHECK-DAG:      <<Arg:b\d+>>      ParameterValue
2438   /// CHECK-DAG:                        Return [<<Arg>>]
$noinline$bug68142795Byte(byte b)2439   public static int $noinline$bug68142795Byte(byte b) {
2440     return (byte)(0xff & (b & 0xff));
2441   }
2442 
2443   /// CHECK-START: int Main.$noinline$bug68142795Elaborate(byte) instruction_simplifier (before)
2444   /// CHECK-DAG:      <<Arg:b\d+>>      ParameterValue
2445   /// CHECK-DAG:      <<Int255:i\d+>>   IntConstant 255
2446   /// CHECK-DAG:      <<Long255:j\d+>>  LongConstant 255
2447   /// CHECK-DAG:      <<And1:i\d+>>     And [<<Arg>>,<<Int255>>]
2448   /// CHECK-DAG:      <<Conv1:j\d+>>    TypeConversion [<<And1>>]
2449   /// CHECK-DAG:      <<And2:j\d+>>     And [<<Conv1>>,<<Long255>>]
2450   /// CHECK-DAG:      <<Conv2:i\d+>>    TypeConversion [<<And2>>]
2451   /// CHECK-DAG:      <<Conv3:b\d+>>    TypeConversion [<<Conv2>>]
2452   /// CHECK-DAG:                        Return [<<Conv3>>]
2453 
2454   /// CHECK-START: int Main.$noinline$bug68142795Elaborate(byte) instruction_simplifier (after)
2455   /// CHECK-DAG:      <<Arg:b\d+>>      ParameterValue
2456   /// CHECK-DAG:                        Return [<<Arg>>]
$noinline$bug68142795Elaborate(byte b)2457   public static int $noinline$bug68142795Elaborate(byte b) {
2458     return (byte)((int)(((long)(b & 0xff)) & 255L));
2459   }
2460 
2461   /// CHECK-START: int Main.$noinline$emptyStringIndexOf(int) instruction_simplifier (before)
2462   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
2463   /// CHECK-DAG:      <<Empty:l\d+>>    LoadString
2464   /// CHECK-DAG:      <<Equals:i\d+>>   InvokeVirtual [<<Empty>>,<<Arg>>] intrinsic:StringIndexOf
2465   /// CHECK-DAG:                        Return [<<Equals>>]
2466 
2467   /// CHECK-START: int Main.$noinline$emptyStringIndexOf(int) instruction_simplifier (after)
2468   /// CHECK-NOT:                        InvokeVirtual
2469 
2470   /// CHECK-START: int Main.$noinline$emptyStringIndexOf(int) instruction_simplifier (after)
2471   /// CHECK-DAG:      <<Minus1:i\d+>>   IntConstant -1
2472   /// CHECK-DAG:                        Return [<<Minus1>>]
$noinline$emptyStringIndexOf(int ch)2473   public static int $noinline$emptyStringIndexOf(int ch) {
2474     return "".indexOf(ch);
2475   }
2476 
2477   /// CHECK-START: int Main.$noinline$emptyStringIndexOfAfter(int, int) instruction_simplifier (before)
2478   /// CHECK-DAG:      <<Arg1:i\d+>>     ParameterValue
2479   /// CHECK-DAG:      <<Arg2:i\d+>>     ParameterValue
2480   /// CHECK-DAG:      <<Empty:l\d+>>    LoadString
2481   /// CHECK-DAG:      <<Equals:i\d+>>   InvokeVirtual [<<Empty>>,<<Arg1>>,<<Arg2>>] intrinsic:StringIndexOfAfter
2482   /// CHECK-DAG:                        Return [<<Equals>>]
2483 
2484   /// CHECK-START: int Main.$noinline$emptyStringIndexOfAfter(int, int) instruction_simplifier (after)
2485   /// CHECK-NOT:                        InvokeVirtual
2486 
2487   /// CHECK-START: int Main.$noinline$emptyStringIndexOfAfter(int, int) instruction_simplifier (after)
2488   /// CHECK-DAG:      <<Minus1:i\d+>>   IntConstant -1
2489   /// CHECK-DAG:                        Return [<<Minus1>>]
$noinline$emptyStringIndexOfAfter(int ch, int fromIndex)2490   public static int $noinline$emptyStringIndexOfAfter(int ch, int fromIndex) {
2491     return "".indexOf(ch, fromIndex);
2492   }
2493 
2494   /// CHECK-START: int Main.$noinline$singleCharStringIndexOf(int) instruction_simplifier (before)
2495   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
2496   /// CHECK-DAG:      <<Empty:l\d+>>    LoadString
2497   /// CHECK-DAG:      <<Equals:i\d+>>   InvokeVirtual [<<Empty>>,<<Arg>>] intrinsic:StringIndexOf
2498   /// CHECK-DAG:                        Return [<<Equals>>]
2499 
2500   /// CHECK-START: int Main.$noinline$singleCharStringIndexOf(int) instruction_simplifier (after)
2501   /// CHECK-NOT:                        InvokeVirtual
2502 
2503   /// CHECK-START: int Main.$noinline$singleCharStringIndexOf(int) instruction_simplifier (after)
2504   /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
2505   /// CHECK-DAG:      <<x:i\d+>>        IntConstant 120
2506   /// CHECK-DAG:      <<Zero:i\d+>>     IntConstant 0
2507   /// CHECK-DAG:      <<Minus1:i\d+>>   IntConstant -1
2508   /// CHECK-DAG:      <<Eq:z\d+>>       Equal [<<Arg>>,<<x>>]
2509   /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Minus1>>,<<Zero>>,<<Eq>>]
2510   /// CHECK-DAG:                        Return [<<Select>>]
$noinline$singleCharStringIndexOf(int ch)2511   public static int $noinline$singleCharStringIndexOf(int ch) {
2512     return "x".indexOf(ch);
2513   }
2514 
2515   /// CHECK-START: int Main.$noinline$singleCharStringIndexOfAfter(int, int) instruction_simplifier (before)
2516   /// CHECK-DAG:      <<Arg1:i\d+>>     ParameterValue
2517   /// CHECK-DAG:      <<Arg2:i\d+>>     ParameterValue
2518   /// CHECK-DAG:      <<Empty:l\d+>>    LoadString
2519   /// CHECK-DAG:      <<Equals:i\d+>>   InvokeVirtual [<<Empty>>,<<Arg1>>,<<Arg2>>] intrinsic:StringIndexOfAfter
2520   /// CHECK-DAG:                        Return [<<Equals>>]
2521 
2522   /// CHECK-START: int Main.$noinline$singleCharStringIndexOfAfter(int, int) instruction_simplifier (after)
2523   /// CHECK-DAG:      <<Arg1:i\d+>>     ParameterValue
2524   /// CHECK-DAG:      <<Arg2:i\d+>>     ParameterValue
2525   /// CHECK-DAG:      <<Empty:l\d+>>    LoadString
2526   /// CHECK-DAG:      <<Equals:i\d+>>   InvokeVirtual [<<Empty>>,<<Arg1>>,<<Arg2>>] intrinsic:StringIndexOfAfter
2527   /// CHECK-DAG:                        Return [<<Equals>>]
$noinline$singleCharStringIndexOfAfter(int ch, int fromIndex)2528   public static int $noinline$singleCharStringIndexOfAfter(int ch, int fromIndex) {
2529     return "x".indexOf(ch, fromIndex);  // Not simplified.
2530   }
2531 
main(String[] args)2532   public static void main(String[] args) throws Exception {
2533     Class smaliTests2 = Class.forName("SmaliTests2");
2534     Method $noinline$XorAllOnes = smaliTests2.getMethod("$noinline$XorAllOnes", int.class);
2535     Method $noinline$NotNot1 = smaliTests2.getMethod("$noinline$NotNot1", long.class);
2536     Method $noinline$NotNot2 = smaliTests2.getMethod("$noinline$NotNot2", int.class);
2537     Method $noinline$NotNotBool = smaliTests2.getMethod("$noinline$NotNotBool", boolean.class);
2538     Method $noinline$bug68142795Short = smaliTests2.getMethod("$noinline$bug68142795Short", short.class);
2539     Method $noinline$bug68142795Boolean = smaliTests2.getMethod("$noinline$bug68142795Boolean", boolean.class);
2540 
2541     int arg = 123456;
2542     float floatArg = 123456.125f;
2543 
2544     assertLongEquals(arg, $noinline$Add0(arg));
2545     assertIntEquals(5, $noinline$AddAddSubAddConst(1));
2546     assertIntEquals(arg, $noinline$AndAllOnes(arg));
2547     assertLongEquals(arg, $noinline$Div1(arg));
2548     assertIntEquals(-arg, $noinline$DivN1(arg));
2549     assertLongEquals(arg, $noinline$Mul1(arg));
2550     assertIntEquals(-arg, $noinline$MulN1(arg));
2551     assertLongEquals((128 * arg), $noinline$MulPowerOfTwo128(arg));
2552     assertLongEquals(2640, $noinline$MulMulMulConst(2));
2553     assertIntEquals(arg, $noinline$Or0(arg));
2554     assertLongEquals(arg, $noinline$OrSame(arg));
2555     assertIntEquals(arg, $noinline$Shl0(arg));
2556     assertLongEquals(arg, $noinline$Shr0(arg));
2557     assertLongEquals(arg, $noinline$Shr64(arg));
2558     assertLongEquals(arg, $noinline$Sub0(arg));
2559     assertIntEquals(-arg, $noinline$SubAliasNeg(arg));
2560     assertIntEquals(9, $noinline$SubAddConst1(2));
2561     assertIntEquals(-2, $noinline$SubAddConst2(3));
2562     assertLongEquals(3, $noinline$SubSubConst(4));
2563     assertLongEquals(arg, $noinline$UShr0(arg));
2564     assertIntEquals(arg, $noinline$Xor0(arg));
2565     assertIntEquals(~arg, (int)$noinline$XorAllOnes.invoke(null, arg));
2566     assertIntEquals(-(arg + arg + 1), $noinline$AddNegs1(arg, arg + 1));
2567     assertIntEquals(-(arg + arg + 1), $noinline$AddNegs2(arg, arg + 1));
2568     assertLongEquals(-(2 * arg + 1), $noinline$AddNegs3(arg, arg + 1));
2569     assertLongEquals(1, $noinline$AddNeg1(arg, arg + 1));
2570     assertLongEquals(-1, $noinline$AddNeg2(arg, arg + 1));
2571     assertLongEquals(arg, $noinline$NegNeg1(arg));
2572     assertIntEquals(0, $noinline$NegNeg2(arg));
2573     assertLongEquals(arg, $noinline$NegNeg3(arg));
2574     assertIntEquals(1, $noinline$NegSub1(arg, arg + 1));
2575     assertIntEquals(1, $noinline$NegSub2(arg, arg + 1));
2576     assertLongEquals(arg, (long)$noinline$NotNot1.invoke(null, arg));
2577     assertLongEquals(arg, $noinline$runSmaliTest2Long("$noinline$NotNot1", arg));
2578     assertIntEquals(-1, (int)$noinline$NotNot2.invoke(null, arg));
2579     assertIntEquals(-1, $noinline$runSmaliTestInt("2", "$noinline$NotNot2", arg));
2580     assertIntEquals(-(arg + arg + 1), $noinline$SubNeg1(arg, arg + 1));
2581     assertIntEquals(-(arg + arg + 1), $noinline$SubNeg2(arg, arg + 1));
2582     assertLongEquals(-(2 * arg + 1), $noinline$SubNeg3(arg, arg + 1));
2583     assertBooleanEquals(true, $noinline$EqualBoolVsIntConst(true));
2584     assertBooleanEquals(true, $noinline$EqualBoolVsIntConst(true));
2585     assertBooleanEquals(false, $noinline$NotEqualBoolVsIntConst(false));
2586     assertBooleanEquals(false, $noinline$NotEqualBoolVsIntConst(false));
2587     assertBooleanEquals(true, (boolean)$noinline$NotNotBool.invoke(null, true));
2588     assertBooleanEquals(true, $noinline$runSmaliTest2Boolean("$noinline$NotNotBool", true));
2589     assertBooleanEquals(false, (boolean)$noinline$NotNotBool.invoke(null, false));
2590     assertBooleanEquals(false, $noinline$runSmaliTest2Boolean("$noinline$NotNotBool", false));
2591     assertFloatEquals(50.0f, $noinline$Div2(100.0f));
2592     assertDoubleEquals(75.0, $noinline$Div2(150.0));
2593     assertFloatEquals(-400.0f, $noinline$DivMP25(100.0f));
2594     assertDoubleEquals(-600.0, $noinline$DivMP25(150.0));
2595     assertIntEquals(0xc, $noinline$UShr28And15(0xc1234567));
2596     assertLongEquals(0xcL, $noinline$UShr60And15(0xc123456787654321L));
2597     assertIntEquals(0x4, $noinline$UShr28And7(0xc1234567));
2598     assertLongEquals(0x4L, $noinline$UShr60And7(0xc123456787654321L));
2599     assertIntEquals(0xc1, $noinline$Shr24And255(0xc1234567));
2600     assertIntEquals(0x60, $noinline$Shr25And127(0xc1234567));
2601     assertLongEquals(0xc1L, $noinline$Shr56And255(0xc123456787654321L));
2602     assertLongEquals(0x60L, $noinline$Shr57And127(0xc123456787654321L));
2603     assertIntEquals(0x41, $noinline$Shr24And127(0xc1234567));
2604     assertLongEquals(0x41L, $noinline$Shr56And127(0xc123456787654321L));
2605     assertIntEquals(0, $noinline$mulPow2Plus1(0));
2606     assertIntEquals(9, $noinline$mulPow2Plus1(1));
2607     assertIntEquals(18, $noinline$mulPow2Plus1(2));
2608     assertIntEquals(900, $noinline$mulPow2Plus1(100));
2609     assertIntEquals(111105, $noinline$mulPow2Plus1(12345));
2610     assertLongEquals(0, $noinline$mulPow2Minus1(0));
2611     assertLongEquals(31, $noinline$mulPow2Minus1(1));
2612     assertLongEquals(62, $noinline$mulPow2Minus1(2));
2613     assertLongEquals(3100, $noinline$mulPow2Minus1(100));
2614     assertLongEquals(382695, $noinline$mulPow2Minus1(12345));
2615 
2616     booleanField = false;
2617     assertIntEquals($noinline$booleanFieldNotEqualOne(), 54);
2618     assertIntEquals($noinline$booleanFieldEqualZero(), 54);
2619     booleanField = true;
2620     assertIntEquals(13, $noinline$booleanFieldNotEqualOne());
2621     assertIntEquals(13, $noinline$booleanFieldEqualZero());
2622     assertIntEquals(54, $noinline$intConditionNotEqualOne(6));
2623     assertIntEquals(13, $noinline$intConditionNotEqualOne(43));
2624     assertIntEquals(54, $noinline$intConditionEqualZero(6));
2625     assertIntEquals(13, $noinline$intConditionEqualZero(43));
2626     assertIntEquals(54, $noinline$floatConditionNotEqualOne(6.0f));
2627     assertIntEquals(13, $noinline$floatConditionNotEqualOne(43.0f));
2628     assertIntEquals(54, $noinline$doubleConditionEqualZero(6.0));
2629     assertIntEquals(13, $noinline$doubleConditionEqualZero(43.0));
2630 
2631     assertIntEquals(1234567, $noinline$intToDoubleToInt(1234567));
2632     assertIntEquals(Integer.MIN_VALUE, $noinline$intToDoubleToInt(Integer.MIN_VALUE));
2633     assertIntEquals(Integer.MAX_VALUE, $noinline$intToDoubleToInt(Integer.MAX_VALUE));
2634     assertStringEquals("d=7654321.0, i=7654321", $noinline$intToDoubleToIntPrint(7654321));
2635     assertIntEquals(12, $noinline$byteToDoubleToInt((byte) 12));
2636     assertIntEquals(Byte.MIN_VALUE, $noinline$byteToDoubleToInt(Byte.MIN_VALUE));
2637     assertIntEquals(Byte.MAX_VALUE, $noinline$byteToDoubleToInt(Byte.MAX_VALUE));
2638     assertIntEquals(11, $noinline$floatToDoubleToInt(11.3f));
2639     assertStringEquals("d=12.25, i=12", $noinline$floatToDoubleToIntPrint(12.25f));
2640     assertIntEquals(123, $noinline$byteToDoubleToShort((byte) 123));
2641     assertIntEquals(Byte.MIN_VALUE, $noinline$byteToDoubleToShort(Byte.MIN_VALUE));
2642     assertIntEquals(Byte.MAX_VALUE, $noinline$byteToDoubleToShort(Byte.MAX_VALUE));
2643     assertIntEquals(1234, $noinline$charToDoubleToShort((char) 1234));
2644     assertIntEquals(Character.MIN_VALUE, $noinline$charToDoubleToShort(Character.MIN_VALUE));
2645     assertIntEquals(/* sign-extended */ -1, $noinline$charToDoubleToShort(Character.MAX_VALUE));
2646     assertIntEquals(12345, $noinline$floatToIntToShort(12345.75f));
2647     assertIntEquals(Short.MAX_VALUE, $noinline$floatToIntToShort((float)(Short.MIN_VALUE - 1)));
2648     assertIntEquals(Short.MIN_VALUE, $noinline$floatToIntToShort((float)(Short.MAX_VALUE + 1)));
2649     assertIntEquals(-54321, $noinline$intToFloatToInt(-54321));
2650     assertDoubleEquals((double) 0x12345678, $noinline$longToIntToDouble(0x1234567812345678L));
2651     assertDoubleEquals(0.0, $noinline$longToIntToDouble(Long.MIN_VALUE));
2652     assertDoubleEquals(-1.0, $noinline$longToIntToDouble(Long.MAX_VALUE));
2653     assertLongEquals(0x0000000012345678L, $noinline$longToIntToLong(0x1234567812345678L));
2654     assertLongEquals(0xffffffff87654321L, $noinline$longToIntToLong(0x1234567887654321L));
2655     assertLongEquals(0L, $noinline$longToIntToLong(Long.MIN_VALUE));
2656     assertLongEquals(-1L, $noinline$longToIntToLong(Long.MAX_VALUE));
2657     assertIntEquals((short) -5678, $noinline$shortToCharToShort((short) -5678));
2658     assertIntEquals(Short.MIN_VALUE, $noinline$shortToCharToShort(Short.MIN_VALUE));
2659     assertIntEquals(Short.MAX_VALUE, $noinline$shortToCharToShort(Short.MAX_VALUE));
2660     assertIntEquals(5678, $noinline$shortToLongToInt((short) 5678));
2661     assertIntEquals(Short.MIN_VALUE, $noinline$shortToLongToInt(Short.MIN_VALUE));
2662     assertIntEquals(Short.MAX_VALUE, $noinline$shortToLongToInt(Short.MAX_VALUE));
2663     assertIntEquals(0x34, $noinline$shortToCharToByte((short) 0x1234));
2664     assertIntEquals(-0x10, $noinline$shortToCharToByte((short) 0x12f0));
2665     assertIntEquals(0, $noinline$shortToCharToByte(Short.MIN_VALUE));
2666     assertIntEquals(-1, $noinline$shortToCharToByte(Short.MAX_VALUE));
2667     assertStringEquals("c=1025, b=1", $noinline$shortToCharToBytePrint((short) 1025));
2668     assertStringEquals("c=1023, b=-1", $noinline$shortToCharToBytePrint((short) 1023));
2669     assertStringEquals("c=65535, b=-1", $noinline$shortToCharToBytePrint((short) -1));
2670 
2671     assertLongEquals(0x55411410L, $noinline$intAndSmallLongConstant(0x55555555));
2672     assertLongEquals(0xffffffffaa028aa2L, $noinline$intAndSmallLongConstant(0xaaaaaaaa));
2673     assertLongEquals(0x44101440L, $noinline$intAndLargeLongConstant(0x55555555));
2674     assertLongEquals(0x208a002aaL, $noinline$intAndLargeLongConstant(0xaaaaaaaa));
2675     assertLongEquals(7L, $noinline$intShr28And15L(0x76543210));
2676 
2677     assertIntEquals(0x21, $noinline$longAnd0xffToByte(0x1234432112344321L));
2678     assertIntEquals(0, $noinline$longAnd0xffToByte(Long.MIN_VALUE));
2679     assertIntEquals(-1, $noinline$longAnd0xffToByte(Long.MAX_VALUE));
2680     assertIntEquals(0x1234, $noinline$intAnd0x1ffffToChar(0x43211234));
2681     assertIntEquals(0, $noinline$intAnd0x1ffffToChar(Integer.MIN_VALUE));
2682     assertIntEquals(Character.MAX_VALUE, $noinline$intAnd0x1ffffToChar(Integer.MAX_VALUE));
2683     assertIntEquals(0x4321, $noinline$intAnd0x17fffToShort(0x87654321));
2684     assertIntEquals(0x0888, $noinline$intAnd0x17fffToShort(0x88888888));
2685     assertIntEquals(0, $noinline$intAnd0x17fffToShort(Integer.MIN_VALUE));
2686     assertIntEquals(Short.MAX_VALUE, $noinline$intAnd0x17fffToShort(Integer.MAX_VALUE));
2687 
2688     assertDoubleEquals(0.0, $noinline$shortAnd0xffffToShortToDouble((short) 0));
2689     assertDoubleEquals(1.0, $noinline$shortAnd0xffffToShortToDouble((short) 1));
2690     assertDoubleEquals(-2.0, $noinline$shortAnd0xffffToShortToDouble((short) -2));
2691     assertDoubleEquals(12345.0, $noinline$shortAnd0xffffToShortToDouble((short) 12345));
2692     assertDoubleEquals((double)Short.MAX_VALUE,
2693                        $noinline$shortAnd0xffffToShortToDouble(Short.MAX_VALUE));
2694     assertDoubleEquals((double)Short.MIN_VALUE,
2695                        $noinline$shortAnd0xffffToShortToDouble(Short.MIN_VALUE));
2696 
2697     assertIntEquals(13, $noinline$intReverseCondition(41));
2698     assertIntEquals(13, $noinline$intReverseConditionNaN(-5));
2699 
2700     for (String condition : new String[] { "Equal", "NotEqual" }) {
2701       for (String constant : new String[] { "True", "False" }) {
2702         for (String side : new String[] { "Rhs", "Lhs" }) {
2703           String name = condition + constant + side;
2704           assertIntEquals(5, $noinline$runSmaliTest(name, true));
2705           assertIntEquals(3, $noinline$runSmaliTest(name, false));
2706         }
2707       }
2708     }
2709 
2710     assertIntEquals(0, $noinline$runSmaliTestInt("AddSubConst", 1));
2711     assertIntEquals(3, $noinline$runSmaliTestInt("SubAddConst", 2));
2712     assertIntEquals(-16, $noinline$runSmaliTestInt("SubSubConst1", 3));
2713     assertIntEquals(-5, $noinline$runSmaliTestInt("SubSubConst2", 4));
2714     assertIntEquals(26, $noinline$runSmaliTestInt("SubSubConst3", 5));
2715     assertIntEquals(0x5e6f7808, $noinline$intUnnecessaryShiftMasking(0xabcdef01, 3));
2716     assertIntEquals(0x5e6f7808, $noinline$intUnnecessaryShiftMasking(0xabcdef01, 3 + 32));
2717     assertLongEquals(0xffffffffffffeaf3L,
2718                      $noinline$longUnnecessaryShiftMasking(0xabcdef0123456789L, 50));
2719     assertLongEquals(0xffffffffffffeaf3L,
2720                      $noinline$longUnnecessaryShiftMasking(0xabcdef0123456789L, 50 + 64));
2721     assertIntEquals(0x2af37b, $noinline$intUnnecessaryWiderShiftMasking(0xabcdef01, 10));
2722     assertIntEquals(0x2af37b, $noinline$intUnnecessaryWiderShiftMasking(0xabcdef01, 10 + 128));
2723     assertLongEquals(0xaf37bc048d159e24L,
2724                      $noinline$longSmallerShiftMasking(0xabcdef0123456789L, 2));
2725     assertLongEquals(0xaf37bc048d159e24L,
2726                      $noinline$longSmallerShiftMasking(0xabcdef0123456789L, 2 + 256));
2727     assertIntEquals(0xfffd5e7c, $noinline$otherUseOfUnnecessaryShiftMasking(0xabcdef01, 13));
2728     assertIntEquals(0xfffd5e7c, $noinline$otherUseOfUnnecessaryShiftMasking(0xabcdef01, 13 + 512));
2729     assertIntEquals(0x5f49eb48, $noinline$intUnnecessaryShiftModifications(0xabcdef01, 2));
2730     assertIntEquals(0xbd4c29b0, $noinline$intUnnecessaryShiftModifications(0xabcdef01, 3));
2731     assertIntEquals(0xc0fed1ca, $noinline$intNecessaryShiftModifications(0xabcdef01, 2));
2732     assertIntEquals(0x03578ebc, $noinline$intNecessaryShiftModifications(0xabcdef01, 3));
2733 
2734     assertIntEquals(654321, $noinline$intAddSubSimplifyArg1(arg, 654321));
2735     assertIntEquals(arg, $noinline$intAddSubSimplifyArg2(arg, 654321));
2736     assertIntEquals(arg, $noinline$intSubAddSimplifyLeft(arg, 654321));
2737     assertIntEquals(arg, $noinline$intSubAddSimplifyRight(arg, 654321));
2738     assertFloatEquals(654321.125f, $noinline$floatAddSubSimplifyArg1(floatArg, 654321.125f));
2739     assertFloatEquals(floatArg, $noinline$floatAddSubSimplifyArg2(floatArg, 654321.125f));
2740     assertFloatEquals(floatArg, $noinline$floatSubAddSimplifyLeft(floatArg, 654321.125f));
2741     assertFloatEquals(floatArg, $noinline$floatSubAddSimplifyRight(floatArg, 654321.125f));
2742 
2743     Main m = new Main();
2744     m.instanceByteField = -1;
2745     assertIntEquals(0xff, $noinline$getUint8FromInstanceByteField(m));
2746     staticByteField = -2;
2747     assertIntEquals(0xfe, $noinline$getUint8FromStaticByteField());
2748     assertIntEquals(0xfd, $noinline$getUint8FromByteArray(new byte[] { -3 }));
2749     m.instanceShortField = -4;
2750     assertIntEquals(0xfffc, $noinline$getUint16FromInstanceShortField(m));
2751     staticShortField = -5;
2752     assertIntEquals(0xfffb, $noinline$getUint16FromStaticShortField());
2753     assertIntEquals(0xfffa, $noinline$getUint16FromShortArray(new short[] { -6 }));
2754     m.instanceCharField = 0xfff9;
2755     assertIntEquals(-7, $noinline$getInt16FromInstanceCharField(m));
2756     staticCharField = 0xfff8;
2757     assertIntEquals(-8, $noinline$getInt16FromStaticCharField());
2758     assertIntEquals(-9, $noinline$getInt16FromCharArray(new char[] { 0xfff7 }));
2759 
2760     staticCharField = 0xfff6;
2761     assertIntEquals(0xf6, $noinline$getStaticCharFieldAnd0xff());
2762 
2763     staticByteField = -11;
2764     assertIntEquals(-11, $noinline$byteToUint8AndBack());
2765 
2766     m.instanceByteField = -12;
2767     assertIntEquals(0xfffff4f4, $noinline$getUint8FromInstanceByteFieldWithAnotherUse(m));
2768 
2769     assertIntEquals(0x21, $noinline$intAnd0xffToChar(0x87654321));
2770     assertIntEquals(0x121, $noinline$intAnd0x1ffToChar(0x87654321));
2771 
2772     m.instanceCharField = 'x';
2773     assertIntEquals('x', $noinline$getInstanceCharFieldAnd0x1ffff(m));
2774 
2775     assertIntEquals(0x7f, $noinline$bug68142795Byte((byte) 0x7f));
2776     assertIntEquals((byte) 0x80, $noinline$bug68142795Byte((byte) 0x80));
2777     assertIntEquals(0x7fff, (int)$noinline$bug68142795Short.invoke(null, (short) 0x7fff));
2778     assertIntEquals((short) 0x8000, (int)$noinline$bug68142795Short.invoke(null, (short) 0x8000));
2779     assertIntEquals(0, (int)$noinline$bug68142795Boolean.invoke(null, false));
2780     assertIntEquals(1, (int)$noinline$bug68142795Boolean.invoke(null, true));
2781     assertIntEquals(0x7f, $noinline$bug68142795Elaborate((byte) 0x7f));
2782     assertIntEquals((byte) 0x80, $noinline$bug68142795Elaborate((byte) 0x80));
2783 
2784     assertIntEquals(-1, $noinline$emptyStringIndexOf('a'));
2785     assertIntEquals(-1, $noinline$emptyStringIndexOf('Z'));
2786     assertIntEquals(-1, $noinline$emptyStringIndexOfAfter('a', 0));
2787     assertIntEquals(-1, $noinline$emptyStringIndexOfAfter('Z', -1));
2788 
2789     assertIntEquals(-1, $noinline$singleCharStringIndexOf('a'));
2790     assertIntEquals(0, $noinline$singleCharStringIndexOf('x'));
2791     assertIntEquals(-1, $noinline$singleCharStringIndexOf('Z'));
2792     assertIntEquals(-1, $noinline$singleCharStringIndexOfAfter('a', 0));
2793     assertIntEquals(0, $noinline$singleCharStringIndexOfAfter('x', -1));
2794     assertIntEquals(-1, $noinline$singleCharStringIndexOfAfter('x', 1));
2795     assertIntEquals(-1, $noinline$singleCharStringIndexOfAfter('Z', -1));
2796   }
2797 
$inline$true()2798   private static boolean $inline$true() { return true; }
$inline$false()2799   private static boolean $inline$false() { return false; }
2800 
2801   public static boolean booleanField;
2802 
2803   public static byte staticByteField;
2804   public static char staticCharField;
2805   public static short staticShortField;
2806 
2807   public byte instanceByteField;
2808   public char instanceCharField;
2809   public short instanceShortField;
2810 }
2811