• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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) control_flow_simplifier (before)
25   /// CHECK-NOT: Phi
26 
27   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValue(boolean) control_flow_simplifier (after)
28   /// CHECK-NOT: Phi
29 
30   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValue(boolean) control_flow_simplifier (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) control_flow_simplifier (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) control_flow_simplifier (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) control_flow_simplifier (before)
74   /// CHECK-NOT: Phi
75 
76   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValue(boolean, boolean) control_flow_simplifier (after)
77   /// CHECK-NOT: Phi
78 
79   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValue(boolean, boolean) control_flow_simplifier (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) control_flow_simplifier (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) control_flow_simplifier (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>>,<<Const10>>,<<Bool1>>]
110   /// CHECK-DAG:                    Return [<<Select>>]
$noinline$testDoubleDiamondSameValueButNotAllOuter(boolean bool_param_1, boolean bool_param_2)111   private static int $noinline$testDoubleDiamondSameValueButNotAllOuter(boolean bool_param_1, boolean bool_param_2) {
112       int return_value;
113     if (bool_param_1) {
114       return_value = 10;
115     } else {
116       if (bool_param_2) {
117         return_value = 20;
118       } else {
119         return_value = 20;
120       }
121     }
122     return return_value;
123   }
124 
125   // Check that we generate a select for a double diamond pattern, with a different value in the inner branch.
126 
127   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllInner(boolean, boolean) control_flow_simplifier (before)
128   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
129   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
130   /// CHECK-DAG:   <<Phi:i\d+>>     Phi [<<Arg1:i\d+>>,<<Arg2:i\d+>>,<<Arg3:i\d+>>]
131   /// CHECK-DAG:                    Return [<<Phi>>]
132   /// CHECK-EVAL:  set(["<<Arg1>>","<<Arg2>>","<<Arg3>>"]) == set(["<<Const10>>","<<Const20>>","<<Const20>>"])
133 
134   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllInner(boolean, boolean) control_flow_simplifier (after)
135   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
136   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
137   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
138   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
139   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const10>>,<<Bool2>>]
140   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const20>>,<<Bool1>>]
141   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondSameValueButNotAllInner(boolean bool_param_1, boolean bool_param_2)142   private static int $noinline$testDoubleDiamondSameValueButNotAllInner(boolean bool_param_1, boolean bool_param_2) {
143       int return_value;
144     if (bool_param_1) {
145       return_value = 20;
146     } else {
147       if (bool_param_2) {
148         return_value = 10;
149       } else {
150         return_value = 20;
151       }
152     }
153     return return_value;
154   }
155 
156   // Check that we generate a select for a double diamond pattern, with a all different values.
157 
158   /// CHECK-START: int Main.$noinline$testDoubleDiamondDifferentValue(boolean, boolean) control_flow_simplifier (before)
159   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
160   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
161   /// CHECK-DAG:   <<Const30:i\d+>> IntConstant 30
162   /// CHECK-DAG:   <<Phi:i\d+>>     Phi [<<Arg1:i\d+>>,<<Arg2:i\d+>>,<<Arg3:i\d+>>]
163   /// CHECK-DAG:                    Return [<<Phi>>]
164   /// CHECK-EVAL:  set(["<<Arg1>>","<<Arg2>>","<<Arg3>>"]) == set(["<<Const10>>","<<Const20>>","<<Const30>>"])
165 
166   /// CHECK-START: int Main.$noinline$testDoubleDiamondDifferentValue(boolean, boolean) control_flow_simplifier (after)
167   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
168   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
169   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
170   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
171   /// CHECK-DAG:   <<Const30:i\d+>> IntConstant 30
172   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const30>>,<<Const20>>,<<Bool2>>]
173   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
174   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondDifferentValue(boolean bool_param_1, boolean bool_param_2)175   private static int $noinline$testDoubleDiamondDifferentValue(boolean bool_param_1, boolean bool_param_2) {
176       int return_value;
177     if (bool_param_1) {
178       return_value = 10;
179     } else {
180       if (bool_param_2) {
181         return_value = 20;
182       } else {
183         return_value = 30;
184       }
185     }
186     return return_value;
187   }
188 
assertEquals(int expected, int actual)189   private static void assertEquals(int expected, int actual) {
190     if (expected != actual) {
191       throw new AssertionError("Expected " + expected + " got " + actual);
192     }
193   }
194 
195   // Check that we generate a select, which we collapse into a single return.
196 
197   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValueWithReturn(boolean) builder (after)
198   /// CHECK:       <<Const10:i\d+>> IntConstant 10
199   /// CHECK:       Return [<<Const10>>]
200   /// CHECK:       Return [<<Const10>>]
201 
202   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValueWithReturn(boolean) control_flow_simplifier (after)
203   /// CHECK-DAG:   <<Bool:z\d+>>   ParameterValue
204   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
205   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const10>>,<<Const10>>,<<Bool>>]
206 
207   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValueWithReturn(boolean) instruction_simplifier$after_gvn (after)
208   /// CHECK:       <<Const10:i\d+>> IntConstant 10
209   /// CHECK:       Return [<<Const10>>]
210 
211   /// CHECK-START: int Main.$noinline$testSimpleDiamondSameValueWithReturn(boolean) instruction_simplifier$after_gvn (after)
212   /// CHECK:       Return
213   /// CHECK-NOT:   Return
$noinline$testSimpleDiamondSameValueWithReturn(boolean bool_param)214   private static int $noinline$testSimpleDiamondSameValueWithReturn(boolean bool_param) {
215     if (bool_param) {
216       return 10;
217     } else {
218       return 10;
219     }
220   }
221 
222   // Same as testSimpleDiamondDifferentValue, but branches return.
223 
224   /// CHECK-START: int Main.$noinline$testSimpleDiamondDifferentValueWithReturn(boolean) control_flow_simplifier (before)
225   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
226   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
227   /// CHECK-DAG:                    Return [<<Const10>>]
228   /// CHECK-DAG:                    Return [<<Const20>>]
229 
230   /// CHECK-START: int Main.$noinline$testSimpleDiamondDifferentValueWithReturn(boolean) control_flow_simplifier (after)
231   /// CHECK-DAG:   <<Bool:z\d+>>    ParameterValue
232   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
233   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
234   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const10>>,<<Bool>>]
235   /// CHECK-DAG:                    Return [<<Select>>]
$noinline$testSimpleDiamondDifferentValueWithReturn(boolean bool_param)236   private static int $noinline$testSimpleDiamondDifferentValueWithReturn(boolean bool_param) {
237     if (bool_param) {
238       return 10;
239     } else {
240       return 20;
241     }
242   }
243 
244   // Check that we generate a select, which we collapse into a single return.
245 
246   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueWithReturn(boolean, boolean) builder (after)
247   /// CHECK:       <<Const10:i\d+>> IntConstant 10
248   /// CHECK:       Return [<<Const10>>]
249   /// CHECK:       Return [<<Const10>>]
250 
251   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueWithReturn(boolean, boolean) control_flow_simplifier (after)
252   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
253   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
254   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
255   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const10>>,<<Const10>>,<<Bool2>>]
256   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
257   /// CHECK-DAG:                    Return [<<Select2>>]
258 
259   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueWithReturn(boolean, boolean) instruction_simplifier$after_gvn (after)
260   /// CHECK:       <<Const10:i\d+>> IntConstant 10
261   /// CHECK:       Return [<<Const10>>]
262 
263   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueWithReturn(boolean, boolean) instruction_simplifier$after_gvn (after)
264   /// CHECK:       Return
265   /// CHECK-NOT:   Return
$noinline$testDoubleDiamondSameValueWithReturn(boolean bool_param_1, boolean bool_param_2)266   private static int $noinline$testDoubleDiamondSameValueWithReturn(boolean bool_param_1, boolean bool_param_2) {
267     if (bool_param_1) {
268       return 10;
269     } else {
270       if (bool_param_2) {
271         return 10;
272       } else {
273         return 10;
274       }
275     }
276   }
277 
278   // Same as testDoubleDiamondSameValueButNotAllOuter, but branches return.
279 
280   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean, boolean) control_flow_simplifier (before)
281   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
282   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
283   /// CHECK-DAG:                    Return [<<Const10>>]
284   /// CHECK-DAG:                    Return [<<Const20>>]
285   /// CHECK-DAG:                    Return [<<Const20>>]
286 
287   // Note that we have 3 returns as D8 only merges when the line positions are equal.
288   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean, boolean) control_flow_simplifier (before)
289   /// CHECK:                    Return
290   /// CHECK:                    Return
291   /// CHECK:                    Return
292 
293   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean, boolean) control_flow_simplifier (after)
294   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
295   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
296   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
297   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
298   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const20>>,<<Bool2>>]
299   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
300   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean bool_param_1, boolean bool_param_2)301   private static int $noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(boolean bool_param_1, boolean bool_param_2) {
302     if (bool_param_1) {
303       return 10;
304     } else {
305       if (bool_param_2) {
306         return 20;
307       } else {
308         return 20;
309       }
310     }
311   }
312 
313   // Same as testDoubleDiamondSameValueButNotAllInner, but branches return.
314 
315   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(boolean, boolean) control_flow_simplifier (before)
316   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
317   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
318   /// CHECK-DAG:                    Return [<<Const10>>]
319   /// CHECK-DAG:                    Return [<<Const20>>]
320   /// CHECK-DAG:                    Return [<<Const20>>]
321 
322   /// CHECK-START: int Main.$noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(boolean, boolean) control_flow_simplifier (after)
323   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
324   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
325   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
326   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
327   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const20>>,<<Const10>>,<<Bool2>>]
328   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const20>>,<<Bool1>>]
329   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(boolean bool_param_1, boolean bool_param_2)330   private static int $noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(boolean bool_param_1, boolean bool_param_2) {
331     if (bool_param_1) {
332       return 20;
333     } else {
334       if (bool_param_2) {
335         return 10;
336       } else {
337         return 20;
338       }
339     }
340   }
341 
342   // Same as testDoubleDiamondDifferentValue, but branches return.
343 
344   /// CHECK-START: int Main.$noinline$testDoubleDiamondDifferentValueWithReturn(boolean, boolean) control_flow_simplifier (before)
345   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
346   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
347   /// CHECK-DAG:   <<Const30:i\d+>> IntConstant 30
348   /// CHECK-DAG:                    Return [<<Const10>>]
349   /// CHECK-DAG:                    Return [<<Const20>>]
350   /// CHECK-DAG:                    Return [<<Const30>>]
351 
352   /// CHECK-START: int Main.$noinline$testDoubleDiamondDifferentValueWithReturn(boolean, boolean) control_flow_simplifier (after)
353   /// CHECK-DAG:   <<Bool1:z\d+>>   ParameterValue
354   /// CHECK-DAG:   <<Bool2:z\d+>>   ParameterValue
355   /// CHECK-DAG:   <<Const10:i\d+>> IntConstant 10
356   /// CHECK-DAG:   <<Const20:i\d+>> IntConstant 20
357   /// CHECK-DAG:   <<Const30:i\d+>> IntConstant 30
358   /// CHECK-DAG:   <<Select:i\d+>>  Select [<<Const30>>,<<Const20>>,<<Bool2>>]
359   /// CHECK-DAG:   <<Select2:i\d+>> Select [<<Select>>,<<Const10>>,<<Bool1>>]
360   /// CHECK-DAG:                    Return [<<Select2>>]
$noinline$testDoubleDiamondDifferentValueWithReturn(boolean bool_param_1, boolean bool_param_2)361   private static int $noinline$testDoubleDiamondDifferentValueWithReturn(boolean bool_param_1, boolean bool_param_2) {
362     if (bool_param_1) {
363       return 10;
364     } else {
365       if (bool_param_2) {
366         return 20;
367       } else {
368         return 30;
369       }
370     }
371   }
372 
main(String[] args)373   public static void main(String[] args) throws Throwable {
374     // With phi
375     assertEquals(10, $noinline$testSimpleDiamondSameValue(false));
376     assertEquals(20, $noinline$testSimpleDiamondDifferentValue(false));
377     assertEquals(10, $noinline$testDoubleDiamondSameValue(false, false));
378     assertEquals(20, $noinline$testDoubleDiamondSameValueButNotAllOuter(false, false));
379     assertEquals(20, $noinline$testDoubleDiamondSameValueButNotAllInner(false, false));
380     assertEquals(30, $noinline$testDoubleDiamondDifferentValue(false, false));
381 
382     // With return
383     assertEquals(10, $noinline$testSimpleDiamondSameValueWithReturn(false));
384     assertEquals(20, $noinline$testSimpleDiamondDifferentValueWithReturn(false));
385     assertEquals(10, $noinline$testDoubleDiamondSameValueWithReturn(false, false));
386     assertEquals(20, $noinline$testDoubleDiamondSameValueButNotAllOuterWithReturn(false, false));
387     assertEquals(20, $noinline$testDoubleDiamondSameValueButNotAllInnerWithReturn(false, false));
388     assertEquals(30, $noinline$testDoubleDiamondDifferentValueWithReturn(false, false));
389   }
390 }
391