xref: /aosp_15_r20/art/test/663-checker-select-generator/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2017 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   // Check that we don't generate a select since we don't have a Phi (not even at
19   // the builder stage) since both values are the same.
20 
21   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValue(boolean) builder (after)
22   /// CHECK-NOT: Phi
23 
24   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValue(boolean) select_generator (before)
25   /// CHECK-NOT: Phi
26 
27   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValue(boolean) select_generator (after)
28   /// CHECK-NOT: Phi
29 
30   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValue(boolean) select_generator (after)
31   /// CHECK-NOT: Select
$noinline$testSimpleDiamondSameValue(boolean bool_param)32   private static int $noinline$testSimpleDiamondSameValue(boolean bool_param) {
33     int return_value;
34     if (bool_param) {
35       return_value = 10;
36     } else {
37       return_value = 10;
38     }
39     return return_value;
40   }
41 
42   // Check that we generate a select for a simple diamond pattern, with different values.
43 
44   /// CHECK-START: int Main.$noinline$testSimpleDiamondDifferentValue(boolean) select_generator (before)
45   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
46   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
47   /// CHECK-DAG:   <<Phi:i\d+>>     Phi [<<Arg1:i\d+>>,<<Arg2:i\d+>>]
48   /// CHECK-DAG:                    Return [<<Phi>>]
49   /// CHECK-EVAL:  set(["<<Arg1>>","<<Arg2>>"]) == set(["<<Const10>>","<<Const20>>"])
50 
51   /// CHECK-START: int Main.$noinline$testSimpleDiamondDifferentValue(boolean) select_generator (after)
52   /// CHECK-DAG:   <<Bool:z\d+>>    ParameterValue
53   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
54   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
55   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const10>>,<<Bool>>]
56   /// CHECK-DAG:                    Return [<<Select>>]
$noinline$testSimpleDiamondDifferentValue(boolean bool_param)57   private static int $noinline$testSimpleDiamondDifferentValue(boolean bool_param) {
58     int return_value;
59     if (bool_param) {
60       return_value = 10;
61     } else {
62       return_value = 20;
63     }
64     return return_value;
65   }
66 
67   // Check that we don't generate a select since we don't have no Phi (not even at the builder
68   // stage) since all values are the same.
69 
70   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValue(boolean, boolean) builder (after)
71   /// CHECK-NOT: Phi
72 
73   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValue(boolean, boolean) select_generator (before)
74   /// CHECK-NOT: Phi
75 
76   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValue(boolean, boolean) select_generator (after)
77   /// CHECK-NOT: Phi
78 
79   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValue(boolean, boolean) select_generator (after)
80   /// CHECK-NOT: Select
$noinline$testDoubleDiamondSameValue(boolean bool_param_1, boolean bool_param_2)81   private static int $noinline$testDoubleDiamondSameValue(boolean bool_param_1, boolean bool_param_2) {
82       int return_value;
83     if (bool_param_1) {
84       return_value = 10;
85     } else {
86       if (bool_param_2) {
87         return_value = 10;
88       } else {
89         return_value = 10;
90       }
91     }
92     return return_value;
93   }
94 
95   // Check that we generate a select for a double diamond pattern, with a different value in the outer branch.
96 
97   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllOuter(boolean, boolean) select_generator (before)
98   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
99   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
100   /// CHECK-DAG:   <<Phi:i\d+>>     Phi [<<Arg1:i\d+>>,<<Arg2:i\d+>>,<<Arg3:i\d+>>]
101   /// CHECK-DAG:                    Return [<<Phi>>]
102   /// CHECK-EVAL:  set(["<<Arg1>>","<<Arg2>>","<<Arg3>>"]) == set(["<<Const10>>","<<Const20>>","<<Const20>>"])
103 
104   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllOuter(boolean, boolean) select_generator (after)
105   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
106   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
107   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
108   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
109   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const20>>,<<Bool2>>]
110   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
111   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondSameValueButNotAllOuter(boolean bool_param_1, boolean bool_param_2)112   private static int $noinline$testDoubleDiamondSameValueButNotAllOuter(boolean bool_param_1, boolean bool_param_2) {
113       int return_value;
114     if (bool_param_1) {
115       return_value = 10;
116     } else {
117       if (bool_param_2) {
118         return_value = 20;
119       } else {
120         return_value = 20;
121       }
122     }
123     return return_value;
124   }
125 
126   // Check that we generate a select for a double diamond pattern, with a different value in the inner branch.
127 
128   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllInner(boolean, boolean) select_generator (before)
129   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
130   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
131   /// CHECK-DAG:   <<Phi:i\d+>>     Phi [<<Arg1:i\d+>>,<<Arg2:i\d+>>,<<Arg3:i\d+>>]
132   /// CHECK-DAG:                    Return [<<Phi>>]
133   /// CHECK-EVAL:  set(["<<Arg1>>","<<Arg2>>","<<Arg3>>"]) == set(["<<Const10>>","<<Const20>>","<<Const20>>"])
134 
135   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllInner(boolean, boolean) select_generator (after)
136   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
137   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
138   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
139   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
140   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const10>>,<<Bool2>>]
141   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const20>>,<<Bool1>>]
142   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondSameValueButNotAllInner(boolean bool_param_1, boolean bool_param_2)143   private static int $noinline$testDoubleDiamondSameValueButNotAllInner(boolean bool_param_1, boolean bool_param_2) {
144       int return_value;
145     if (bool_param_1) {
146       return_value = 20;
147     } else {
148       if (bool_param_2) {
149         return_value = 10;
150       } else {
151         return_value = 20;
152       }
153     }
154     return return_value;
155   }
156 
157   // Check that we generate a select for a double diamond pattern, with a all different values.
158 
159   /// CHECK-START: int Main.$noinline$testDoubleDiamondDifferentValue(boolean, boolean) select_generator (before)
160   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
161   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
162   /// CHECK-DAG:   <<Const30:i\d+>> IntConstant 30
163   /// CHECK-DAG:   <<Phi:i\d+>>     Phi [<<Arg1:i\d+>>,<<Arg2:i\d+>>,<<Arg3:i\d+>>]
164   /// CHECK-DAG:                    Return [<<Phi>>]
165   /// CHECK-EVAL:  set(["<<Arg1>>","<<Arg2>>","<<Arg3>>"]) == set(["<<Const10>>","<<Const20>>","<<Const30>>"])
166 
167   /// CHECK-START: int Main.$noinline$testDoubleDiamondDifferentValue(boolean, boolean) select_generator (after)
168   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
169   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
170   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
171   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
172   /// CHECK-DAG:   <<Const30:i\d+>> IntConstant 30
173   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const30>>,<<Const20>>,<<Bool2>>]
174   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
175   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondDifferentValue(boolean bool_param_1, boolean bool_param_2)176   private static int $noinline$testDoubleDiamondDifferentValue(boolean bool_param_1, boolean bool_param_2) {
177       int return_value;
178     if (bool_param_1) {
179       return_value = 10;
180     } else {
181       if (bool_param_2) {
182         return_value = 20;
183       } else {
184         return_value = 30;
185       }
186     }
187     return return_value;
188   }
189 
assertEquals(int expected, int actual)190   private static void assertEquals(int expected, int actual) {
191     if (expected != actual) {
192       throw new AssertionError("Expected " + expected + " got " + actual);
193     }
194   }
195 
196   // Check that we generate a select, which we collapse into a single return.
197 
198   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValueWithReturn(boolean) builder (after)
199   /// CHECK:       <<Const10:i\d+>> IntConstant 10
200   /// CHECK:       Return [<<Const10>>]
201   /// CHECK:       Return [<<Const10>>]
202 
203   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValueWithReturn(boolean) select_generator (after)
204   /// CHECK-DAG:   <<Bool:z\d+>>   ParameterValue
205   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
206   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const10>>,<<Const10>>,<<Bool>>]
207 
208   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValueWithReturn(boolean) instruction_simplifier$after_gvn (after)
209   /// CHECK:       <<Const10:i\d+>> IntConstant 10
210   /// CHECK:       Return [<<Const10>>]
211 
212   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValueWithReturn(boolean) instruction_simplifier$after_gvn (after)
213   /// CHECK:       Return
214   /// CHECK-NOT:   Return
$noinline$testSimpleDiamondSameValueWithReturn(boolean bool_param)215   private static int $noinline$testSimpleDiamondSameValueWithReturn(boolean bool_param) {
216     if (bool_param) {
217       return 10;
218     } else {
219       return 10;
220     }
221   }
222 
223   // Same as testSimpleDiamondDifferentValue, but branches return.
224 
225   /// CHECK-START: int Main.$noinline$testSimpleDiamondDifferentValueWithReturn(boolean) select_generator (before)
226   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
227   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
228   /// CHECK-DAG:                    Return [<<Const10>>]
229   /// CHECK-DAG:                    Return [<<Const20>>]
230 
231   /// CHECK-START: int Main.$noinline$testSimpleDiamondDifferentValueWithReturn(boolean) select_generator (after)
232   /// CHECK-DAG:   <<Bool:z\d+>>    ParameterValue
233   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
234   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
235   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const10>>,<<Bool>>]
236   /// CHECK-DAG:                    Return [<<Select>>]
$noinline$testSimpleDiamondDifferentValueWithReturn(boolean bool_param)237   private static int $noinline$testSimpleDiamondDifferentValueWithReturn(boolean bool_param) {
238     if (bool_param) {
239       return 10;
240     } else {
241       return 20;
242     }
243   }
244 
245   // Check that we generate a select, which we collapse into a single return.
246 
247   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueWithReturn(boolean, boolean) builder (after)
248   /// CHECK:       <<Const10:i\d+>> IntConstant 10
249   /// CHECK:       Return [<<Const10>>]
250   /// CHECK:       Return [<<Const10>>]
251 
252   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueWithReturn(boolean, boolean) select_generator (after)
253   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
254   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
255   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
256   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const10>>,<<Const10>>,<<Bool2>>]
257   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
258   /// CHECK-DAG:                    Return [<<Select2>>]
259 
260   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueWithReturn(boolean, boolean) instruction_simplifier$after_gvn (after)
261   /// CHECK:       <<Const10:i\d+>> IntConstant 10
262   /// CHECK:       Return [<<Const10>>]
263 
264   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueWithReturn(boolean, boolean) instruction_simplifier$after_gvn (after)
265   /// CHECK:       Return
266   /// CHECK-NOT:   Return
$noinline$testDoubleDiamondSameValueWithReturn(boolean bool_param_1, boolean bool_param_2)267   private static int $noinline$testDoubleDiamondSameValueWithReturn(boolean bool_param_1, boolean bool_param_2) {
268     if (bool_param_1) {
269       return 10;
270     } else {
271       if (bool_param_2) {
272         return 10;
273       } else {
274         return 10;
275       }
276     }
277   }
278 
279   // Same as testDoubleDiamondSameValueButNotAllOuter, but branches return.
280 
281   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean, boolean) select_generator (before)
282   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
283   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
284   /// CHECK-DAG:                    Return [<<Const10>>]
285   /// CHECK-DAG:                    Return [<<Const20>>]
286   /// CHECK-DAG:                    Return [<<Const20>>]
287 
288   // Note that we have 3 returns as D8 only merges when the line positions are equal.
289   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean, boolean) select_generator (before)
290   /// CHECK:                    Return
291   /// CHECK:                    Return
292   /// CHECK:                    Return
293 
294   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean, boolean) select_generator (after)
295   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
296   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
297   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
298   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
299   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const20>>,<<Bool2>>]
300   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
301   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean bool_param_1, boolean bool_param_2)302   private static int $noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean bool_param_1, boolean bool_param_2) {
303     if (bool_param_1) {
304       return 10;
305     } else {
306       if (bool_param_2) {
307         return 20;
308       } else {
309         return 20;
310       }
311     }
312   }
313 
314   // Same as testDoubleDiamondSameValueButNotAllInner, but branches return.
315 
316   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(boolean, boolean) select_generator (before)
317   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
318   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
319   /// CHECK-DAG:                    Return [<<Const10>>]
320   /// CHECK-DAG:                    Return [<<Const20>>]
321   /// CHECK-DAG:                    Return [<<Const20>>]
322 
323   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(boolean, boolean) select_generator (after)
324   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
325   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
326   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
327   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
328   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const10>>,<<Bool2>>]
329   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const20>>,<<Bool1>>]
330   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(boolean bool_param_1, boolean bool_param_2)331   private static int $noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(boolean bool_param_1, boolean bool_param_2) {
332     if (bool_param_1) {
333       return 20;
334     } else {
335       if (bool_param_2) {
336         return 10;
337       } else {
338         return 20;
339       }
340     }
341   }
342 
343   // Same as testDoubleDiamondDifferentValue, but branches return.
344 
345   /// CHECK-START: int Main.$noinline$testDoubleDiamondDifferentValueWithReturn(boolean, boolean) select_generator (before)
346   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
347   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
348   /// CHECK-DAG:   <<Const30:i\d+>> IntConstant 30
349   /// CHECK-DAG:                    Return [<<Const10>>]
350   /// CHECK-DAG:                    Return [<<Const20>>]
351   /// CHECK-DAG:                    Return [<<Const30>>]
352 
353   /// CHECK-START: int Main.$noinline$testDoubleDiamondDifferentValueWithReturn(boolean, boolean) select_generator (after)
354   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
355   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
356   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
357   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
358   /// CHECK-DAG:   <<Const30:i\d+>> IntConstant 30
359   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const30>>,<<Const20>>,<<Bool2>>]
360   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
361   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondDifferentValueWithReturn(boolean bool_param_1, boolean bool_param_2)362   private static int $noinline$testDoubleDiamondDifferentValueWithReturn(boolean bool_param_1, boolean bool_param_2) {
363     if (bool_param_1) {
364       return 10;
365     } else {
366       if (bool_param_2) {
367         return 20;
368       } else {
369         return 30;
370       }
371     }
372   }
373 
main(String[] args)374   public static void main(String[] args) throws Throwable {
375     // With phi
376     assertEquals(10, $noinline$testSimpleDiamondSameValue(false));
377     assertEquals(20, $noinline$testSimpleDiamondDifferentValue(false));
378     assertEquals(10, $noinline$testDoubleDiamondSameValue(false, false));
379     assertEquals(20, $noinline$testDoubleDiamondSameValueButNotAllOuter(false, false));
380     assertEquals(20, $noinline$testDoubleDiamondSameValueButNotAllInner(false, false));
381     assertEquals(30, $noinline$testDoubleDiamondDifferentValue(false, false));
382 
383     // With return
384     assertEquals(10, $noinline$testSimpleDiamondSameValueWithReturn(false));
385     assertEquals(20, $noinline$testSimpleDiamondDifferentValueWithReturn(false));
386     assertEquals(10, $noinline$testDoubleDiamondSameValueWithReturn(false, false));
387     assertEquals(20, $noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(false, false));
388     assertEquals(20, $noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(false, false));
389     assertEquals(30, $noinline$testDoubleDiamondDifferentValueWithReturn(false, false));
390   }
391 }
392