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 public class Main {
18 
assertBooleanEquals(boolean expected, boolean result)19   public static void assertBooleanEquals(boolean expected, boolean result) {
20     if (expected != result) {
21       throw new Error("Expected: " + expected + ", found: " + result);
22     }
23   }
24 
assertIntEquals(int expected, int result)25   public static void assertIntEquals(int expected, int result) {
26     if (expected != result) {
27       throw new Error("Expected: " + expected + ", found: " + result);
28     }
29   }
30 
assertLongEquals(long expected, long result)31   public static void assertLongEquals(long expected, long result) {
32     if (expected != result) {
33       throw new Error("Expected: " + expected + ", found: " + result);
34     }
35   }
36 
assertFloatEquals(float expected, float result)37   public static void assertFloatEquals(float expected, float result) {
38     if (expected != result) {
39       throw new Error("Expected: " + expected + ", found: " + result);
40     }
41   }
42 
assertDoubleEquals(double expected, double result)43   public static void assertDoubleEquals(double expected, double result) {
44     if (expected != result) {
45       throw new Error("Expected: " + expected + ", found: " + result);
46     }
47   }
48 
49   /**
50    * Tiny programs exercising optimizations of arithmetic identities.
51    */
52 
53   // CHECK-START: long Main.Add0(long) instruction_simplifier (before)
54   // CHECK-DAG:     [[Arg:j\d+]]     ParameterValue
55   // CHECK-DAG:     [[Const0:j\d+]]  LongConstant 0
56   // CHECK-DAG:     [[Add:j\d+]]     Add [ [[Const0]] [[Arg]] ]
57   // CHECK-DAG:                      Return [ [[Add]] ]
58 
59   // CHECK-START: long Main.Add0(long) instruction_simplifier (after)
60   // CHECK-DAG:     [[Arg:j\d+]]     ParameterValue
61   // CHECK-DAG:                      Return [ [[Arg]] ]
62 
63   // CHECK-START: long Main.Add0(long) instruction_simplifier (after)
64   // CHECK-NOT:                        Add
65 
Add0(long arg)66   public static long Add0(long arg) {
67     return 0 + arg;
68   }
69 
70   // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before)
71   // CHECK-DAG:     [[Arg:i\d+]]     ParameterValue
72   // CHECK-DAG:     [[ConstF:i\d+]]  IntConstant -1
73   // CHECK-DAG:     [[And:i\d+]]     And [ [[Arg]] [[ConstF]] ]
74   // CHECK-DAG:                      Return [ [[And]] ]
75 
76   // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
77   // CHECK-DAG:     [[Arg:i\d+]]     ParameterValue
78   // CHECK-DAG:                      Return [ [[Arg]] ]
79 
80   // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after)
81   // CHECK-NOT:                      And
82 
AndAllOnes(int arg)83   public static int AndAllOnes(int arg) {
84     return arg & -1;
85   }
86 
87   // CHECK-START: long Main.Div1(long) instruction_simplifier (before)
88   // CHECK-DAG:     [[Arg:j\d+]]     ParameterValue
89   // CHECK-DAG:     [[Const1:j\d+]]  LongConstant 1
90   // CHECK-DAG:     [[Div:j\d+]]     Div [ [[Arg]] [[Const1]] ]
91   // CHECK-DAG:                      Return [ [[Div]] ]
92 
93   // CHECK-START: long Main.Div1(long) instruction_simplifier (after)
94   // CHECK-DAG:     [[Arg:j\d+]]     ParameterValue
95   // CHECK-DAG:                      Return [ [[Arg]] ]
96 
97   // CHECK-START: long Main.Div1(long) instruction_simplifier (after)
98   // CHECK-NOT:                      Div
99 
Div1(long arg)100   public static long Div1(long arg) {
101     return arg / 1;
102   }
103 
104   // CHECK-START: int Main.DivN1(int) instruction_simplifier (before)
105   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
106   // CHECK-DAG:     [[ConstN1:i\d+]]  IntConstant -1
107   // CHECK-DAG:     [[Div:i\d+]]      Div [ [[Arg]] [[ConstN1]] ]
108   // CHECK-DAG:                       Return [ [[Div]] ]
109 
110   // CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
111   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
112   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Arg]] ]
113   // CHECK-DAG:                       Return [ [[Neg]] ]
114 
115   // CHECK-START: int Main.DivN1(int) instruction_simplifier (after)
116   // CHECK-NOT:                       Div
117 
DivN1(int arg)118   public static int DivN1(int arg) {
119     return arg / -1;
120   }
121 
122   // CHECK-START: long Main.Mul1(long) instruction_simplifier (before)
123   // CHECK-DAG:     [[Arg:j\d+]]     ParameterValue
124   // CHECK-DAG:     [[Const1:j\d+]]  LongConstant 1
125   // CHECK-DAG:     [[Mul:j\d+]]     Mul [ [[Arg]] [[Const1]] ]
126   // CHECK-DAG:                      Return [ [[Mul]] ]
127 
128   // CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
129   // CHECK-DAG:     [[Arg:j\d+]]     ParameterValue
130   // CHECK-DAG:                      Return [ [[Arg]] ]
131 
132   // CHECK-START: long Main.Mul1(long) instruction_simplifier (after)
133   // CHECK-NOT:                       Mul
134 
Mul1(long arg)135   public static long Mul1(long arg) {
136     return arg * 1;
137   }
138 
139   // CHECK-START: int Main.MulN1(int) instruction_simplifier (before)
140   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
141   // CHECK-DAG:     [[ConstN1:i\d+]]  IntConstant -1
142   // CHECK-DAG:     [[Mul:i\d+]]      Mul [ [[Arg]] [[ConstN1]] ]
143   // CHECK-DAG:                       Return [ [[Mul]] ]
144 
145   // CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
146   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
147   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Arg]] ]
148   // CHECK-DAG:                       Return [ [[Neg]] ]
149 
150   // CHECK-START: int Main.MulN1(int) instruction_simplifier (after)
151   // CHECK-NOT:                       Mul
152 
MulN1(int arg)153   public static int MulN1(int arg) {
154     return arg * -1;
155   }
156 
157   // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before)
158   // CHECK-DAG:     [[Arg:j\d+]]       ParameterValue
159   // CHECK-DAG:     [[Const128:j\d+]]  LongConstant 128
160   // CHECK-DAG:     [[Mul:j\d+]]       Mul [ [[Arg]] [[Const128]] ]
161   // CHECK-DAG:                        Return [ [[Mul]] ]
162 
163   // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
164   // CHECK-DAG:     [[Arg:j\d+]]       ParameterValue
165   // CHECK-DAG:     [[Const7:i\d+]]    IntConstant 7
166   // CHECK-DAG:     [[Shl:j\d+]]       Shl [ [[Arg]] [[Const7]] ]
167   // CHECK-DAG:                        Return [ [[Shl]] ]
168 
169   // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after)
170   // CHECK-NOT:                        Mul
171 
MulPowerOfTwo128(long arg)172   public static long MulPowerOfTwo128(long arg) {
173     return arg * 128;
174   }
175 
176   // CHECK-START: int Main.Or0(int) instruction_simplifier (before)
177   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
178   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
179   // CHECK-DAG:     [[Or:i\d+]]       Or [ [[Arg]] [[Const0]] ]
180   // CHECK-DAG:                       Return [ [[Or]] ]
181 
182   // CHECK-START: int Main.Or0(int) instruction_simplifier (after)
183   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
184   // CHECK-DAG:                       Return [ [[Arg]] ]
185 
186   // CHECK-START: int Main.Or0(int) instruction_simplifier (after)
187   // CHECK-NOT:                       Or
188 
Or0(int arg)189   public static int Or0(int arg) {
190     return arg | 0;
191   }
192 
193   // CHECK-START: long Main.OrSame(long) instruction_simplifier (before)
194   // CHECK-DAG:     [[Arg:j\d+]]       ParameterValue
195   // CHECK-DAG:     [[Or:j\d+]]        Or [ [[Arg]] [[Arg]] ]
196   // CHECK-DAG:                        Return [ [[Or]] ]
197 
198   // CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
199   // CHECK-DAG:     [[Arg:j\d+]]       ParameterValue
200   // CHECK-DAG:                        Return [ [[Arg]] ]
201 
202   // CHECK-START: long Main.OrSame(long) instruction_simplifier (after)
203   // CHECK-NOT:                        Or
204 
OrSame(long arg)205   public static long OrSame(long arg) {
206     return arg | arg;
207   }
208 
209   // CHECK-START: int Main.Shl0(int) instruction_simplifier (before)
210   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
211   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
212   // CHECK-DAG:     [[Shl:i\d+]]      Shl [ [[Arg]] [[Const0]] ]
213   // CHECK-DAG:                       Return [ [[Shl]] ]
214 
215   // CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
216   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
217   // CHECK-DAG:                       Return [ [[Arg]] ]
218 
219   // CHECK-START: int Main.Shl0(int) instruction_simplifier (after)
220   // CHECK-NOT:                       Shl
221 
Shl0(int arg)222   public static int Shl0(int arg) {
223     return arg << 0;
224   }
225 
226   // CHECK-START: int Main.Shl1(int) instruction_simplifier (before)
227   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
228   // CHECK-DAG:     [[Const1:i\d+]]   IntConstant 1
229   // CHECK-DAG:     [[Shl:i\d+]]      Shl [ [[Arg]] [[Const1]] ]
230   // CHECK-DAG:                       Return [ [[Shl]] ]
231 
232   // CHECK-START: int Main.Shl1(int) instruction_simplifier (after)
233   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
234   // CHECK-DAG:     [[Add:i\d+]]      Add [ [[Arg]] [[Arg]] ]
235   // CHECK-DAG:                       Return [ [[Add]] ]
236 
237   // CHECK-START: int Main.Shl1(int) instruction_simplifier (after)
238   // CHECK-NOT:                       Shl
239 
Shl1(int arg)240   public static int Shl1(int arg) {
241     return arg << 1;
242   }
243 
244   // CHECK-START: long Main.Shr0(long) instruction_simplifier (before)
245   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
246   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
247   // CHECK-DAG:     [[Shr:j\d+]]      Shr [ [[Arg]] [[Const0]] ]
248   // CHECK-DAG:                       Return [ [[Shr]] ]
249 
250   // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
251   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
252   // CHECK-DAG:                       Return [ [[Arg]] ]
253 
254   // CHECK-START: long Main.Shr0(long) instruction_simplifier (after)
255   // CHECK-NOT:                       Shr
256 
Shr0(long arg)257   public static long Shr0(long arg) {
258     return arg >> 0;
259   }
260 
261   // CHECK-START: long Main.Sub0(long) instruction_simplifier (before)
262   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
263   // CHECK-DAG:     [[Const0:j\d+]]   LongConstant 0
264   // CHECK-DAG:     [[Sub:j\d+]]      Sub [ [[Arg]] [[Const0]] ]
265   // CHECK-DAG:                       Return [ [[Sub]] ]
266 
267   // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
268   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
269   // CHECK-DAG:                       Return [ [[Arg]] ]
270 
271   // CHECK-START: long Main.Sub0(long) instruction_simplifier (after)
272   // CHECK-NOT:                       Sub
273 
Sub0(long arg)274   public static long Sub0(long arg) {
275     return arg - 0;
276   }
277 
278   // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before)
279   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
280   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
281   // CHECK-DAG:     [[Sub:i\d+]]      Sub [ [[Const0]] [[Arg]] ]
282   // CHECK-DAG:                       Return [ [[Sub]] ]
283 
284   // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
285   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
286   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Arg]] ]
287   // CHECK-DAG:                       Return [ [[Neg]] ]
288 
289   // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after)
290   // CHECK-NOT:                       Sub
291 
SubAliasNeg(int arg)292   public static int SubAliasNeg(int arg) {
293     return 0 - arg;
294   }
295 
296   // CHECK-START: long Main.UShr0(long) instruction_simplifier (before)
297   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
298   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
299   // CHECK-DAG:     [[UShr:j\d+]]     UShr [ [[Arg]] [[Const0]] ]
300   // CHECK-DAG:                       Return [ [[UShr]] ]
301 
302   // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
303   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
304   // CHECK-DAG:                       Return [ [[Arg]] ]
305 
306   // CHECK-START: long Main.UShr0(long) instruction_simplifier (after)
307   // CHECK-NOT:                       UShr
308 
UShr0(long arg)309   public static long UShr0(long arg) {
310     return arg >>> 0;
311   }
312 
313   // CHECK-START: int Main.Xor0(int) instruction_simplifier (before)
314   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
315   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
316   // CHECK-DAG:     [[Xor:i\d+]]      Xor [ [[Arg]] [[Const0]] ]
317   // CHECK-DAG:                       Return [ [[Xor]] ]
318 
319   // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
320   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
321   // CHECK-DAG:                       Return [ [[Arg]] ]
322 
323   // CHECK-START: int Main.Xor0(int) instruction_simplifier (after)
324   // CHECK-NOT:                       Xor
325 
Xor0(int arg)326   public static int Xor0(int arg) {
327     return arg ^ 0;
328   }
329 
330   // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before)
331   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
332   // CHECK-DAG:     [[ConstF:i\d+]]   IntConstant -1
333   // CHECK-DAG:     [[Xor:i\d+]]      Xor [ [[Arg]] [[ConstF]] ]
334   // CHECK-DAG:                       Return [ [[Xor]] ]
335 
336   // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
337   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
338   // CHECK-DAG:     [[Not:i\d+]]      Not [ [[Arg]] ]
339   // CHECK-DAG:                       Return [ [[Not]] ]
340 
341   // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after)
342   // CHECK-NOT:                       Xor
343 
XorAllOnes(int arg)344   public static int XorAllOnes(int arg) {
345     return arg ^ -1;
346   }
347 
348   /**
349    * Test that addition or subtraction operation with both inputs negated are
350    * optimized to use a single negation after the operation.
351    * The transformation tested is implemented in
352    * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
353    */
354 
355   // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before)
356   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
357   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
358   // CHECK-DAG:     [[Neg1:i\d+]]     Neg [ [[Arg1]] ]
359   // CHECK-DAG:     [[Neg2:i\d+]]     Neg [ [[Arg2]] ]
360   // CHECK-DAG:     [[Add:i\d+]]      Add [ [[Neg1]] [[Neg2]] ]
361   // CHECK-DAG:                       Return [ [[Add]] ]
362 
363   // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after)
364   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
365   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
366   // CHECK-NOT:                       Neg
367   // CHECK-DAG:     [[Add:i\d+]]      Add [ [[Arg1]] [[Arg2]] ]
368   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Add]] ]
369   // CHECK-DAG:                       Return [ [[Neg]] ]
370 
AddNegs1(int arg1, int arg2)371   public static int AddNegs1(int arg1, int arg2) {
372     return -arg1 + -arg2;
373   }
374 
375   /**
376    * This is similar to the test-case AddNegs1, but the negations have
377    * multiple uses.
378    * The transformation tested is implemented in
379    * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
380    * The current code won't perform the previous optimization. The
381    * transformations do not look at other uses of their inputs. As they don't
382    * know what will happen with other uses, they do not take the risk of
383    * increasing the register pressure by creating or extending live ranges.
384    */
385 
386   // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before)
387   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
388   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
389   // CHECK-DAG:     [[Neg1:i\d+]]     Neg [ [[Arg1]] ]
390   // CHECK-DAG:     [[Neg2:i\d+]]     Neg [ [[Arg2]] ]
391   // CHECK-DAG:     [[Add1:i\d+]]     Add [ [[Neg1]] [[Neg2]] ]
392   // CHECK-DAG:     [[Add2:i\d+]]     Add [ [[Neg1]] [[Neg2]] ]
393   // CHECK-DAG:     [[Or:i\d+]]       Or [ [[Add1]] [[Add2]] ]
394   // CHECK-DAG:                       Return [ [[Or]] ]
395 
396   // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after)
397   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
398   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
399   // CHECK-DAG:     [[Neg1:i\d+]]     Neg [ [[Arg1]] ]
400   // CHECK-DAG:     [[Neg2:i\d+]]     Neg [ [[Arg2]] ]
401   // CHECK-DAG:     [[Add1:i\d+]]     Add [ [[Neg1]] [[Neg2]] ]
402   // CHECK-DAG:     [[Add2:i\d+]]     Add [ [[Neg1]] [[Neg2]] ]
403   // CHECK-NOT:                       Neg
404   // CHECK-DAG:     [[Or:i\d+]]       Or [ [[Add1]] [[Add2]] ]
405   // CHECK-DAG:                       Return [ [[Or]] ]
406 
407   // CHECK-START: int Main.AddNegs2(int, int) GVN (after)
408   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
409   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
410   // CHECK-DAG:     [[Neg1:i\d+]]     Neg [ [[Arg1]] ]
411   // CHECK-DAG:     [[Neg2:i\d+]]     Neg [ [[Arg2]] ]
412   // CHECK-DAG:     [[Add:i\d+]]      Add [ [[Neg1]] [[Neg2]] ]
413   // CHECK-DAG:     [[Or:i\d+]]       Or [ [[Add]] [[Add]] ]
414   // CHECK-DAG:                       Return [ [[Or]] ]
415 
AddNegs2(int arg1, int arg2)416   public static int AddNegs2(int arg1, int arg2) {
417     int temp1 = -arg1;
418     int temp2 = -arg2;
419     return (temp1 + temp2) | (temp1 + temp2);
420   }
421 
422   /**
423    * This follows test-cases AddNegs1 and AddNegs2.
424    * The transformation tested is implemented in
425    * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`.
426    * The optimization should not happen if it moves an additional instruction in
427    * the loop.
428    */
429 
430   // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before)
431   // -------------- Arguments and initial negation operations.
432   // CHECK-DAG:     [[Arg1:j\d+]]     ParameterValue
433   // CHECK-DAG:     [[Arg2:j\d+]]     ParameterValue
434   // CHECK-DAG:     [[Neg1:j\d+]]     Neg [ [[Arg1]] ]
435   // CHECK-DAG:     [[Neg2:j\d+]]     Neg [ [[Arg2]] ]
436   // CHECK:                           Goto
437   // -------------- Loop
438   // CHECK:                           SuspendCheck
439   // CHECK:         [[Add:j\d+]]      Add [ [[Neg1]] [[Neg2]] ]
440   // CHECK:                           Goto
441 
442   // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after)
443   // -------------- Arguments and initial negation operations.
444   // CHECK-DAG:     [[Arg1:j\d+]]     ParameterValue
445   // CHECK-DAG:     [[Arg2:j\d+]]     ParameterValue
446   // CHECK-DAG:     [[Neg1:j\d+]]     Neg [ [[Arg1]] ]
447   // CHECK-DAG:     [[Neg2:j\d+]]     Neg [ [[Arg2]] ]
448   // CHECK:                           Goto
449   // -------------- Loop
450   // CHECK:                           SuspendCheck
451   // CHECK:         [[Add:j\d+]]      Add [ [[Neg1]] [[Neg2]] ]
452   // CHECK-NOT:                       Neg
453   // CHECK:                           Goto
454 
AddNegs3(long arg1, long arg2)455   public static long AddNegs3(long arg1, long arg2) {
456     long res = 0;
457     long n_arg1 = -arg1;
458     long n_arg2 = -arg2;
459     for (long i = 0; i < 1; i++) {
460       res += n_arg1 + n_arg2 + i;
461     }
462     return res;
463   }
464 
465   /**
466    * Test the simplification of an addition with a negated argument into a
467    * subtraction.
468    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
469    */
470 
471   // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before)
472   // CHECK-DAG:     [[Arg1:j\d+]]     ParameterValue
473   // CHECK-DAG:     [[Arg2:j\d+]]     ParameterValue
474   // CHECK-DAG:     [[Neg:j\d+]]      Neg [ [[Arg1]] ]
475   // CHECK-DAG:     [[Add:j\d+]]      Add [ [[Neg]] [[Arg2]] ]
476   // CHECK-DAG:                       Return [ [[Add]] ]
477 
478   // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
479   // CHECK-DAG:     [[Arg1:j\d+]]     ParameterValue
480   // CHECK-DAG:     [[Arg2:j\d+]]     ParameterValue
481   // CHECK-DAG:     [[Sub:j\d+]]      Sub [ [[Arg2]] [[Arg1]] ]
482   // CHECK-DAG:                       Return [ [[Sub]] ]
483 
484   // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after)
485   // CHECK-NOT:                       Neg
486   // CHECK-NOT:                       Add
487 
AddNeg1(long arg1, long arg2)488   public static long AddNeg1(long arg1, long arg2) {
489     return -arg1 + arg2;
490   }
491 
492   /**
493    * This is similar to the test-case AddNeg1, but the negation has two uses.
494    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`.
495    * The current code won't perform the previous optimization. The
496    * transformations do not look at other uses of their inputs. As they don't
497    * know what will happen with other uses, they do not take the risk of
498    * increasing the register pressure by creating or extending live ranges.
499    */
500 
501   // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before)
502   // CHECK-DAG:     [[Arg1:j\d+]]     ParameterValue
503   // CHECK-DAG:     [[Arg2:j\d+]]     ParameterValue
504   // CHECK-DAG:     [[Neg:j\d+]]      Neg [ [[Arg2]] ]
505   // CHECK-DAG:     [[Add1:j\d+]]     Add [ [[Arg1]] [[Neg]] ]
506   // CHECK-DAG:     [[Add2:j\d+]]     Add [ [[Arg1]] [[Neg]] ]
507   // CHECK-DAG:     [[Res:j\d+]]      Or [ [[Add1]] [[Add2]] ]
508   // CHECK-DAG:                       Return [ [[Res]] ]
509 
510   // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
511   // CHECK-DAG:     [[Arg1:j\d+]]     ParameterValue
512   // CHECK-DAG:     [[Arg2:j\d+]]     ParameterValue
513   // CHECK-DAG:     [[Neg:j\d+]]      Neg [ [[Arg2]] ]
514   // CHECK-DAG:     [[Add1:j\d+]]     Add [ [[Arg1]] [[Neg]] ]
515   // CHECK-DAG:     [[Add2:j\d+]]     Add [ [[Arg1]] [[Neg]] ]
516   // CHECK-DAG:     [[Res:j\d+]]      Or [ [[Add1]] [[Add2]] ]
517   // CHECK-DAG:                       Return [ [[Res]] ]
518 
519   // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after)
520   // CHECK-NOT:                       Sub
521 
AddNeg2(long arg1, long arg2)522   public static long AddNeg2(long arg1, long arg2) {
523     long temp = -arg2;
524     return (arg1 + temp) | (arg1 + temp);
525   }
526 
527   /**
528    * Test simplification of the `-(-var)` pattern.
529    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
530    */
531 
532   // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before)
533   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
534   // CHECK-DAG:     [[Neg1:j\d+]]     Neg [ [[Arg]] ]
535   // CHECK-DAG:     [[Neg2:j\d+]]     Neg [ [[Neg1]] ]
536   // CHECK-DAG:                       Return [ [[Neg2]] ]
537 
538   // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
539   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
540   // CHECK-DAG:                       Return [ [[Arg]] ]
541 
542   // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after)
543   // CHECK-NOT:                       Neg
544 
NegNeg1(long arg)545   public static long NegNeg1(long arg) {
546     return -(-arg);
547   }
548 
549   /**
550    * Test 'multi-step' simplification, where a first transformation yields a
551    * new simplification possibility for the current instruction.
552    * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
553    * and in `InstructionSimplifierVisitor::VisitAdd`.
554    */
555 
556   // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before)
557   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
558   // CHECK-DAG:     [[Neg1:i\d+]]     Neg [ [[Arg]] ]
559   // CHECK-DAG:     [[Neg2:i\d+]]     Neg [ [[Neg1]] ]
560   // CHECK-DAG:     [[Add:i\d+]]      Add [ [[Neg1]] [[Neg2]] ]
561   // CHECK-DAG:                       Return [ [[Add]] ]
562 
563   // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
564   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
565   // CHECK-DAG:     [[Sub:i\d+]]      Sub [ [[Arg]] [[Arg]] ]
566   // CHECK-DAG:                       Return [ [[Sub]] ]
567 
568   // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after)
569   // CHECK-NOT:                       Neg
570   // CHECK-NOT:                       Add
571 
572   // CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after)
573   // CHECK:         [[Const0:i\d+]]   IntConstant 0
574   // CHECK-NOT:                       Neg
575   // CHECK-NOT:                       Add
576   // CHECK:                           Return [ [[Const0]] ]
577 
NegNeg2(int arg)578   public static int NegNeg2(int arg) {
579     int temp = -arg;
580     return temp + -temp;
581   }
582 
583   /**
584    * Test another 'multi-step' simplification, where a first transformation
585    * yields a new simplification possibility for the current instruction.
586    * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg`
587    * and in `InstructionSimplifierVisitor::VisitSub`.
588    */
589 
590   // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before)
591   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
592   // CHECK-DAG:     [[Const0:j\d+]]   LongConstant 0
593   // CHECK-DAG:     [[Neg:j\d+]]      Neg [ [[Arg]] ]
594   // CHECK-DAG:     [[Sub:j\d+]]      Sub [ [[Const0]] [[Neg]] ]
595   // CHECK-DAG:                       Return [ [[Sub]] ]
596 
597   // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
598   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
599   // CHECK-DAG:                       Return [ [[Arg]] ]
600 
601   // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after)
602   // CHECK-NOT:                       Neg
603   // CHECK-NOT:                       Sub
604 
NegNeg3(long arg)605   public static long NegNeg3(long arg) {
606     return 0 - -arg;
607   }
608 
609   /**
610    * Test that a negated subtraction is simplified to a subtraction with its
611    * arguments reversed.
612    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
613    */
614 
615   // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before)
616   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
617   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
618   // CHECK-DAG:     [[Sub:i\d+]]      Sub [ [[Arg1]] [[Arg2]] ]
619   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Sub]] ]
620   // CHECK-DAG:                       Return [ [[Neg]] ]
621 
622   // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
623   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
624   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
625   // CHECK-DAG:     [[Sub:i\d+]]      Sub [ [[Arg2]] [[Arg1]] ]
626   // CHECK-DAG:                       Return [ [[Sub]] ]
627 
628   // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after)
629   // CHECK-NOT:                       Neg
630 
NegSub1(int arg1, int arg2)631   public static int NegSub1(int arg1, int arg2) {
632     return -(arg1 - arg2);
633   }
634 
635   /**
636    * This is similar to the test-case NegSub1, but the subtraction has
637    * multiple uses.
638    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`.
639    * The current code won't perform the previous optimization. The
640    * transformations do not look at other uses of their inputs. As they don't
641    * know what will happen with other uses, they do not take the risk of
642    * increasing the register pressure by creating or extending live ranges.
643    */
644 
645   // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before)
646   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
647   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
648   // CHECK-DAG:     [[Sub:i\d+]]      Sub [ [[Arg1]] [[Arg2]] ]
649   // CHECK-DAG:     [[Neg1:i\d+]]     Neg [ [[Sub]] ]
650   // CHECK-DAG:     [[Neg2:i\d+]]     Neg [ [[Sub]] ]
651   // CHECK-DAG:     [[Or:i\d+]]       Or [ [[Neg1]] [[Neg2]] ]
652   // CHECK-DAG:                       Return [ [[Or]] ]
653 
654   // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after)
655   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
656   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
657   // CHECK-DAG:     [[Sub:i\d+]]      Sub [ [[Arg1]] [[Arg2]] ]
658   // CHECK-DAG:     [[Neg1:i\d+]]     Neg [ [[Sub]] ]
659   // CHECK-DAG:     [[Neg2:i\d+]]     Neg [ [[Sub]] ]
660   // CHECK-DAG:     [[Or:i\d+]]       Or [ [[Neg1]] [[Neg2]] ]
661   // CHECK-DAG:                       Return [ [[Or]] ]
662 
NegSub2(int arg1, int arg2)663   public static int NegSub2(int arg1, int arg2) {
664     int temp = arg1 - arg2;
665     return -temp | -temp;
666   }
667 
668   /**
669    * Test simplification of the `~~var` pattern.
670    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
671    */
672 
673   // CHECK-START: long Main.NotNot1(long) instruction_simplifier (before)
674   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
675   // CHECK-DAG:     [[ConstF1:j\d+]]  LongConstant -1
676   // CHECK-DAG:     [[Xor1:j\d+]]     Xor [ [[Arg]] [[ConstF1]] ]
677   // CHECK-DAG:     [[Xor2:j\d+]]     Xor [ [[Xor1]] [[ConstF1]] ]
678   // CHECK-DAG:                       Return [ [[Xor2]] ]
679 
680   // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
681   // CHECK-DAG:     [[Arg:j\d+]]      ParameterValue
682   // CHECK-DAG:                       Return [ [[Arg]] ]
683 
684   // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after)
685   // CHECK-NOT:                       Xor
686 
NotNot1(long arg)687   public static long NotNot1(long arg) {
688     return ~~arg;
689   }
690 
691   // CHECK-START: int Main.NotNot2(int) instruction_simplifier (before)
692   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
693   // CHECK-DAG:     [[ConstF1:i\d+]]  IntConstant -1
694   // CHECK-DAG:     [[Xor1:i\d+]]     Xor [ [[Arg]] [[ConstF1]] ]
695   // CHECK-DAG:     [[Xor2:i\d+]]     Xor [ [[Xor1]] [[ConstF1]] ]
696   // CHECK-DAG:     [[Add:i\d+]]      Add [ [[Xor1]] [[Xor2]] ]
697   // CHECK-DAG:                       Return [ [[Add]] ]
698 
699   // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
700   // CHECK-DAG:     [[Arg:i\d+]]      ParameterValue
701   // CHECK-DAG:     [[Not:i\d+]]      Not [ [[Arg]] ]
702   // CHECK-DAG:     [[Add:i\d+]]      Add [ [[Not]] [[Arg]] ]
703   // CHECK-DAG:                       Return [ [[Add]] ]
704 
705   // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after)
706   // CHECK-NOT:                       Xor
707 
NotNot2(int arg)708   public static int NotNot2(int arg) {
709     int temp = ~arg;
710     return temp + ~temp;
711   }
712 
713   /**
714    * Test the simplification of a subtraction with a negated argument.
715    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
716    */
717 
718   // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before)
719   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
720   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
721   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Arg1]] ]
722   // CHECK-DAG:     [[Sub:i\d+]]      Sub [ [[Neg]] [[Arg2]] ]
723   // CHECK-DAG:                       Return [ [[Sub]] ]
724 
725   // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
726   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
727   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
728   // CHECK-DAG:     [[Add:i\d+]]      Add [ [[Arg1]] [[Arg2]] ]
729   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Add]] ]
730   // CHECK-DAG:                       Return [ [[Neg]] ]
731 
732   // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after)
733   // CHECK-NOT:                       Sub
734 
SubNeg1(int arg1, int arg2)735   public static int SubNeg1(int arg1, int arg2) {
736     return -arg1 - arg2;
737   }
738 
739   /**
740    * This is similar to the test-case SubNeg1, but the negation has
741    * multiple uses.
742    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
743    * The current code won't perform the previous optimization. The
744    * transformations do not look at other uses of their inputs. As they don't
745    * know what will happen with other uses, they do not take the risk of
746    * increasing the register pressure by creating or extending live ranges.
747    */
748 
749   // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before)
750   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
751   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
752   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Arg1]] ]
753   // CHECK-DAG:     [[Sub1:i\d+]]     Sub [ [[Neg]] [[Arg2]] ]
754   // CHECK-DAG:     [[Sub2:i\d+]]     Sub [ [[Neg]] [[Arg2]] ]
755   // CHECK-DAG:     [[Or:i\d+]]       Or [ [[Sub1]] [[Sub2]] ]
756   // CHECK-DAG:                       Return [ [[Or]] ]
757 
758   // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
759   // CHECK-DAG:     [[Arg1:i\d+]]     ParameterValue
760   // CHECK-DAG:     [[Arg2:i\d+]]     ParameterValue
761   // CHECK-DAG:     [[Neg:i\d+]]      Neg [ [[Arg1]] ]
762   // CHECK-DAG:     [[Sub1:i\d+]]     Sub [ [[Neg]] [[Arg2]] ]
763   // CHECK-DAG:     [[Sub2:i\d+]]     Sub [ [[Neg]] [[Arg2]] ]
764   // CHECK-DAG:     [[Or:i\d+]]       Or [ [[Sub1]] [[Sub2]] ]
765   // CHECK-DAG:                       Return [ [[Or]] ]
766 
767   // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after)
768   // CHECK-NOT:                       Add
769 
SubNeg2(int arg1, int arg2)770   public static int SubNeg2(int arg1, int arg2) {
771     int temp = -arg1;
772     return (temp - arg2) | (temp - arg2);
773   }
774 
775   /**
776    * This follows test-cases SubNeg1 and SubNeg2.
777    * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`.
778    * The optimization should not happen if it moves an additional instruction in
779    * the loop.
780    */
781 
782   // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before)
783   // -------------- Arguments and initial negation operation.
784   // CHECK-DAG:     [[Arg1:j\d+]]     ParameterValue
785   // CHECK-DAG:     [[Arg2:j\d+]]     ParameterValue
786   // CHECK-DAG:     [[Neg:j\d+]]      Neg [ [[Arg1]] ]
787   // CHECK:                           Goto
788   // -------------- Loop
789   // CHECK:                           SuspendCheck
790   // CHECK:         [[Sub:j\d+]]      Sub [ [[Neg]] [[Arg2]] ]
791   // CHECK:                           Goto
792 
793   // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after)
794   // -------------- Arguments and initial negation operation.
795   // CHECK-DAG:     [[Arg1:j\d+]]     ParameterValue
796   // CHECK-DAG:     [[Arg2:j\d+]]     ParameterValue
797   // CHECK-DAG:     [[Neg:j\d+]]      Neg [ [[Arg1]] ]
798   // CHECK-DAG:                       Goto
799   // -------------- Loop
800   // CHECK:                           SuspendCheck
801   // CHECK:         [[Sub:j\d+]]      Sub [ [[Neg]] [[Arg2]] ]
802   // CHECK-NOT:                       Neg
803   // CHECK:                           Goto
804 
SubNeg3(long arg1, long arg2)805   public static long SubNeg3(long arg1, long arg2) {
806     long res = 0;
807     long temp = -arg1;
808     for (long i = 0; i < 1; i++) {
809       res += temp - arg2 - i;
810     }
811     return res;
812   }
813 
814   // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before)
815   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
816   // CHECK-DAG:     [[Const1:i\d+]]   IntConstant 1
817   // CHECK-DAG:     [[Cond:z\d+]]     Equal [ [[Arg]] [[Const1]] ]
818   // CHECK-DAG:                       If [ [[Cond]] ]
819 
820   // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after)
821   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
822   // CHECK-DAG:                       If [ [[Arg]] ]
823 
EqualTrueRhs(boolean arg)824   public static int EqualTrueRhs(boolean arg) {
825     return (arg != true) ? 3 : 5;
826   }
827 
828   // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before)
829   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
830   // CHECK-DAG:     [[Const1:i\d+]]   IntConstant 1
831   // CHECK-DAG:     [[Cond:z\d+]]     Equal [ [[Const1]] [[Arg]] ]
832   // CHECK-DAG:                       If [ [[Cond]] ]
833 
834   // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after)
835   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
836   // CHECK-DAG:                       If [ [[Arg]] ]
837 
EqualTrueLhs(boolean arg)838   public static int EqualTrueLhs(boolean arg) {
839     return (true != arg) ? 3 : 5;
840   }
841 
842   // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (before)
843   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
844   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
845   // CHECK-DAG:     [[Cond:z\d+]]     Equal [ [[Arg]] [[Const0]] ]
846   // CHECK-DAG:                       If [ [[Cond]] ]
847 
848   // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (after)
849   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
850   // CHECK-DAG:     [[NotArg:z\d+]]   BooleanNot [ [[Arg]] ]
851   // CHECK-DAG:                       If [ [[NotArg]] ]
852 
EqualFalseRhs(boolean arg)853   public static int EqualFalseRhs(boolean arg) {
854     return (arg != false) ? 3 : 5;
855   }
856 
857   // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before)
858   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
859   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
860   // CHECK-DAG:     [[Cond:z\d+]]     Equal [ [[Const0]] [[Arg]] ]
861   // CHECK-DAG:                       If [ [[Cond]] ]
862 
863   // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (after)
864   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
865   // CHECK-DAG:     [[NotArg:z\d+]]   BooleanNot [ [[Arg]] ]
866   // CHECK-DAG:                       If [ [[NotArg]] ]
867 
EqualFalseLhs(boolean arg)868   public static int EqualFalseLhs(boolean arg) {
869     return (false != arg) ? 3 : 5;
870   }
871 
872   // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (before)
873   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
874   // CHECK-DAG:     [[Const1:i\d+]]   IntConstant 1
875   // CHECK-DAG:     [[Cond:z\d+]]     NotEqual [ [[Arg]] [[Const1]] ]
876   // CHECK-DAG:                       If [ [[Cond]] ]
877 
878   // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (after)
879   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
880   // CHECK-DAG:     [[NotArg:z\d+]]   BooleanNot [ [[Arg]] ]
881   // CHECK-DAG:                       If [ [[NotArg]] ]
882 
NotEqualTrueRhs(boolean arg)883   public static int NotEqualTrueRhs(boolean arg) {
884     return (arg == true) ? 3 : 5;
885   }
886 
887   // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before)
888   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
889   // CHECK-DAG:     [[Const1:i\d+]]   IntConstant 1
890   // CHECK-DAG:     [[Cond:z\d+]]     NotEqual [ [[Const1]] [[Arg]] ]
891   // CHECK-DAG:                       If [ [[Cond]] ]
892 
893   // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after)
894   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
895   // CHECK-DAG:     [[NotArg:z\d+]]   BooleanNot [ [[Arg]] ]
896   // CHECK-DAG:                       If [ [[NotArg]] ]
897 
NotEqualTrueLhs(boolean arg)898   public static int NotEqualTrueLhs(boolean arg) {
899     return (true == arg) ? 3 : 5;
900   }
901 
902   // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before)
903   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
904   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
905   // CHECK-DAG:     [[Cond:z\d+]]     NotEqual [ [[Arg]] [[Const0]] ]
906   // CHECK-DAG:                       If [ [[Cond]] ]
907 
908   // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after)
909   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
910   // CHECK-DAG:                       If [ [[Arg]] ]
911 
NotEqualFalseRhs(boolean arg)912   public static int NotEqualFalseRhs(boolean arg) {
913     return (arg == false) ? 3 : 5;
914   }
915 
916   // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before)
917   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
918   // CHECK-DAG:     [[Const0:i\d+]]   IntConstant 0
919   // CHECK-DAG:     [[Cond:z\d+]]     NotEqual [ [[Const0]] [[Arg]] ]
920   // CHECK-DAG:                       If [ [[Cond]] ]
921 
922   // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after)
923   // CHECK-DAG:     [[Arg:z\d+]]      ParameterValue
924   // CHECK-DAG:                       If [ [[Arg]] ]
925 
NotEqualFalseLhs(boolean arg)926   public static int NotEqualFalseLhs(boolean arg) {
927     return (false == arg) ? 3 : 5;
928   }
929 
930   /*
931    * Test simplification of double Boolean negation. Note that sometimes
932    * both negations can be removed but we only expect the simplifier to
933    * remove the second.
934    */
935 
936   // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (before)
937   // CHECK-DAG:     [[Arg:z\d+]]       ParameterValue
938   // CHECK-DAG:     [[NotArg:z\d+]]    BooleanNot [ [[Arg]] ]
939   // CHECK-DAG:     [[NotNotArg:z\d+]] BooleanNot [ [[NotArg]] ]
940   // CHECK-DAG:                        Return [ [[NotNotArg]] ]
941 
942   // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
943   // CHECK-DAG:     [[Arg:z\d+]]       ParameterValue
944   // CHECK-DAG:                        BooleanNot [ [[Arg]] ]
945   // CHECK-DAG:                        Return [ [[Arg]] ]
946 
947   // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after)
948   // CHECK:                            BooleanNot
949   // CHECK-NOT:                        BooleanNot
950 
NegateValue(boolean arg)951   public static boolean NegateValue(boolean arg) {
952     return !arg;
953   }
954 
NotNotBool(boolean arg)955   public static boolean NotNotBool(boolean arg) {
956     return !(NegateValue(arg));
957   }
958 
959   // CHECK-START: float Main.Div2(float) instruction_simplifier (before)
960   // CHECK-DAG:      [[Arg:f\d+]]      ParameterValue
961   // CHECK-DAG:      [[Const2:f\d+]]   FloatConstant 2
962   // CHECK-DAG:      [[Div:f\d+]]      Div [ [[Arg]] [[Const2]] ]
963   // CHECK-DAG:                        Return [ [[Div]] ]
964 
965   // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
966   // CHECK-DAG:      [[Arg:f\d+]]      ParameterValue
967   // CHECK-DAG:      [[ConstP5:f\d+]]  FloatConstant 0.5
968   // CHECK-DAG:      [[Mul:f\d+]]      Mul [ [[Arg]] [[ConstP5]] ]
969   // CHECK-DAG:                        Return [ [[Mul]] ]
970 
971   // CHECK-START: float Main.Div2(float) instruction_simplifier (after)
972   // CHECK-NOT:                        Div
973 
Div2(float arg)974   public static float Div2(float arg) {
975     return arg / 2.0f;
976   }
977 
978   // CHECK-START: double Main.Div2(double) instruction_simplifier (before)
979   // CHECK-DAG:      [[Arg:d\d+]]      ParameterValue
980   // CHECK-DAG:      [[Const2:d\d+]]   DoubleConstant 2
981   // CHECK-DAG:      [[Div:d\d+]]      Div [ [[Arg]] [[Const2]] ]
982   // CHECK-DAG:                        Return [ [[Div]] ]
983 
984   // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
985   // CHECK-DAG:      [[Arg:d\d+]]      ParameterValue
986   // CHECK-DAG:      [[ConstP5:d\d+]]  DoubleConstant 0.5
987   // CHECK-DAG:      [[Mul:d\d+]]      Mul [ [[Arg]] [[ConstP5]] ]
988   // CHECK-DAG:                        Return [ [[Mul]] ]
989 
990   // CHECK-START: double Main.Div2(double) instruction_simplifier (after)
991   // CHECK-NOT:                        Div
Div2(double arg)992   public static double Div2(double arg) {
993     return arg / 2.0;
994   }
995 
996   // CHECK-START: float Main.DivMP25(float) instruction_simplifier (before)
997   // CHECK-DAG:      [[Arg:f\d+]]      ParameterValue
998   // CHECK-DAG:      [[ConstMP25:f\d+]]   FloatConstant -0.25
999   // CHECK-DAG:      [[Div:f\d+]]      Div [ [[Arg]] [[ConstMP25]] ]
1000   // CHECK-DAG:                        Return [ [[Div]] ]
1001 
1002   // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
1003   // CHECK-DAG:      [[Arg:f\d+]]      ParameterValue
1004   // CHECK-DAG:      [[ConstM4:f\d+]]  FloatConstant -4
1005   // CHECK-DAG:      [[Mul:f\d+]]      Mul [ [[Arg]] [[ConstM4]] ]
1006   // CHECK-DAG:                        Return [ [[Mul]] ]
1007 
1008   // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after)
1009   // CHECK-NOT:                        Div
1010 
DivMP25(float arg)1011   public static float DivMP25(float arg) {
1012     return arg / -0.25f;
1013   }
1014 
1015   // CHECK-START: double Main.DivMP25(double) instruction_simplifier (before)
1016   // CHECK-DAG:      [[Arg:d\d+]]      ParameterValue
1017   // CHECK-DAG:      [[ConstMP25:d\d+]]   DoubleConstant -0.25
1018   // CHECK-DAG:      [[Div:d\d+]]      Div [ [[Arg]] [[ConstMP25]] ]
1019   // CHECK-DAG:                        Return [ [[Div]] ]
1020 
1021   // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1022   // CHECK-DAG:      [[Arg:d\d+]]      ParameterValue
1023   // CHECK-DAG:      [[ConstM4:d\d+]]  DoubleConstant -4
1024   // CHECK-DAG:      [[Mul:d\d+]]      Mul [ [[Arg]] [[ConstM4]] ]
1025   // CHECK-DAG:                        Return [ [[Mul]] ]
1026 
1027   // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after)
1028   // CHECK-NOT:                        Div
DivMP25(double arg)1029   public static double DivMP25(double arg) {
1030     return arg / -0.25f;
1031   }
1032 
main(String[] args)1033   public static void main(String[] args) {
1034     int arg = 123456;
1035 
1036     assertLongEquals(Add0(arg), arg);
1037     assertIntEquals(AndAllOnes(arg), arg);
1038     assertLongEquals(Div1(arg), arg);
1039     assertIntEquals(DivN1(arg), -arg);
1040     assertLongEquals(Mul1(arg), arg);
1041     assertIntEquals(MulN1(arg), -arg);
1042     assertLongEquals(MulPowerOfTwo128(arg), (128 * arg));
1043     assertIntEquals(Or0(arg), arg);
1044     assertLongEquals(OrSame(arg), arg);
1045     assertIntEquals(Shl0(arg), arg);
1046     assertLongEquals(Shr0(arg), arg);
1047     assertLongEquals(Sub0(arg), arg);
1048     assertIntEquals(SubAliasNeg(arg), -arg);
1049     assertLongEquals(UShr0(arg), arg);
1050     assertIntEquals(Xor0(arg), arg);
1051     assertIntEquals(XorAllOnes(arg), ~arg);
1052     assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1));
1053     assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1));
1054     assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1));
1055     assertLongEquals(AddNeg1(arg, arg + 1), 1);
1056     assertLongEquals(AddNeg2(arg, arg + 1), -1);
1057     assertLongEquals(NegNeg1(arg), arg);
1058     assertIntEquals(NegNeg2(arg), 0);
1059     assertLongEquals(NegNeg3(arg), arg);
1060     assertIntEquals(NegSub1(arg, arg + 1), 1);
1061     assertIntEquals(NegSub2(arg, arg + 1), 1);
1062     assertLongEquals(NotNot1(arg), arg);
1063     assertIntEquals(NotNot2(arg), -1);
1064     assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1));
1065     assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1));
1066     assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1));
1067     assertIntEquals(EqualTrueRhs(true), 5);
1068     assertIntEquals(EqualTrueLhs(true), 5);
1069     assertIntEquals(EqualFalseRhs(true), 3);
1070     assertIntEquals(EqualFalseLhs(true), 3);
1071     assertIntEquals(NotEqualTrueRhs(true), 3);
1072     assertIntEquals(NotEqualTrueLhs(true), 3);
1073     assertIntEquals(NotEqualFalseRhs(true), 5);
1074     assertIntEquals(NotEqualFalseLhs(true), 5);
1075     assertBooleanEquals(NotNotBool(true), true);
1076     assertBooleanEquals(NotNotBool(false), false);
1077     assertFloatEquals(Div2(100.0f), 50.0f);
1078     assertDoubleEquals(Div2(150.0), 75.0);
1079     assertFloatEquals(DivMP25(100.0f), -400.0f);
1080     assertDoubleEquals(DivMP25(150.0), -600.0);
1081     assertLongEquals(Shl1(100), 200);
1082   }
1083 }
1084