1# Copyright (C) 2015 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15.class public LTestCase;
16
17.super Ljava/lang/Object;
18
19.method public static $inline$True()Z
20  .registers 1
21  const/4 v0, 1
22  return v0
23.end method
24
25
26# CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (before)
27# CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
28# CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
29# CHECK-DAG:     [[Cst1:i\d+]]  IntConstant 1
30# CHECK-DAG:     [[Cst5:i\d+]]  IntConstant 5
31# CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
32# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]]
33# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
34# CHECK-DAG:                    If [ [[Cst1]] ]                              loop_header:[[HeaderY]]
35# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop_header:[[HeaderY]]
36# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
37# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
38
39# CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (after)
40# CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
41# CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
42# CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
43# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[AddX:i\d+]] ]               loop_header:[[HeaderY:B\d+]]
44# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
45# CHECK-DAG:     [[AddX]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
46# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
47
48.method public static testSingleExit(IZ)I
49  .registers 3
50
51  # p0 = int X
52  # p1 = boolean Y
53  # v0 = true
54
55  invoke-static {}, LTestCase;->$inline$True()Z
56  move-result v0
57
58  :loop_start
59  if-eqz p1, :loop_body   # cannot be determined statically
60  if-nez v0, :loop_end    # will always exit
61
62  # Dead block
63  add-int/lit8 p0, p0, 5
64  goto :loop_start
65
66  # Live block
67  :loop_body
68  add-int/lit8 p0, p0, 7
69  goto :loop_start
70
71  :loop_end
72  return p0
73.end method
74
75
76# CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (before)
77# CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
78# CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
79# CHECK-DAG:     [[ArgZ:z\d+]]  ParameterValue
80# CHECK-DAG:     [[Cst1:i\d+]]  IntConstant 1
81# CHECK-DAG:     [[Cst5:i\d+]]  IntConstant 5
82# CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
83# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]]
84# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
85# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop_header:[[HeaderY]]
86# CHECK-DAG:                    If [ [[Cst1]] ]                              loop_header:[[HeaderY]]
87# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop_header:[[HeaderY]]
88# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
89# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
90
91# CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (after)
92# CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
93# CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
94# CHECK-DAG:     [[ArgZ:z\d+]]  ParameterValue
95# CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
96# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop_header:[[HeaderY:B\d+]]
97# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
98# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
99# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop_header:null
100# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
101
102.method public static testMultipleExits(IZZ)I
103  .registers 4
104
105  # p0 = int X
106  # p1 = boolean Y
107  # p2 = boolean Z
108  # v0 = true
109
110  invoke-static {}, LTestCase;->$inline$True()Z
111  move-result v0
112
113  :loop_start
114  if-eqz p1, :loop_body   # cannot be determined statically
115  if-nez p2, :loop_end    # may exit
116  if-nez v0, :loop_end    # will always exit
117
118  # Dead block
119  add-int/lit8 p0, p0, 5
120  goto :loop_start
121
122  # Live block
123  :loop_body
124  add-int/lit8 p0, p0, 7
125  goto :loop_start
126
127  :loop_end
128  return p0
129.end method
130
131
132# CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (before)
133# CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
134# CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
135# CHECK-DAG:     [[ArgZ:z\d+]]  ParameterValue
136# CHECK-DAG:     [[Cst1:i\d+]]  IntConstant 1
137# CHECK-DAG:     [[Cst5:i\d+]]  IntConstant 5
138# CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
139# CHECK-DAG:     [[Cst9:i\d+]]  IntConstant 9
140# CHECK-DAG:     [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]]
141# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
142# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop_header:[[HeaderY]]
143# CHECK-DAG:     [[Mul9:i\d+]]  Mul [ [[PhiX1]] [[Cst9]] ]                   loop_header:[[HeaderY]]
144# CHECK-DAG:     [[PhiX2:i\d+]] Phi [ [[PhiX1]] [[Mul9]] ]                   loop_header:[[HeaderY]]
145# CHECK-DAG:                    If [ [[Cst1]] ]                              loop_header:[[HeaderY]]
146# CHECK-DAG:     [[Add5]]       Add [ [[PhiX2]] [[Cst5]] ]                   loop_header:[[HeaderY]]
147# CHECK-DAG:     [[Add7]]       Add [ [[PhiX1]] [[Cst7]] ]                   loop_header:[[HeaderY]]
148# CHECK-DAG:                    Return [ [[PhiX2]] ]                         loop_header:null
149
150# CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (after)
151# CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
152# CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
153# CHECK-DAG:     [[ArgZ:z\d+]]  ParameterValue
154# CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
155# CHECK-DAG:     [[Cst9:i\d+]]  IntConstant 9
156# CHECK-DAG:     [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop_header:[[HeaderY:B\d+]]
157# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
158# CHECK-DAG:     [[Add7]]       Add [ [[PhiX1]] [[Cst7]] ]                   loop_header:[[HeaderY]]
159# CHECK-DAG:                    If [ [[ArgZ]] ]                              loop_header:null
160# CHECK-DAG:     [[Mul9:i\d+]]  Mul [ [[PhiX1]] [[Cst9]] ]                   loop_header:null
161# CHECK-DAG:     [[PhiX2:i\d+]] Phi [ [[PhiX1]] [[Mul9]] ]                   loop_header:null
162# CHECK-DAG:                    Return [ [[PhiX2]] ]                         loop_header:null
163
164.method public static testExitPredecessors(IZZ)I
165  .registers 4
166
167  # p0 = int X
168  # p1 = boolean Y
169  # p2 = boolean Z
170  # v0 = true
171
172  invoke-static {}, LTestCase;->$inline$True()Z
173  move-result v0
174
175  :loop_start
176  if-eqz p1, :loop_body   # cannot be determined statically
177
178  # Additional logic which will end up outside the loop
179  if-eqz p2, :skip_if
180  mul-int/lit8 p0, p0, 9
181  :skip_if
182
183  if-nez v0, :loop_end    # will always take the branch
184
185  # Dead block
186  add-int/lit8 p0, p0, 5
187  goto :loop_start
188
189  # Live block
190  :loop_body
191  add-int/lit8 p0, p0, 7
192  goto :loop_start
193
194  :loop_end
195  return p0
196.end method
197
198
199# CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (before)
200# CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
201# CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
202# CHECK-DAG:     [[ArgZ:z\d+]]  ParameterValue
203# CHECK-DAG:     [[Cst0:i\d+]]  IntConstant 0
204# CHECK-DAG:     [[Cst1:i\d+]]  IntConstant 1
205# CHECK-DAG:     [[Cst5:i\d+]]  IntConstant 5
206# CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
207#
208# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]]
209# CHECK-DAG:     [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[XorZ:i\d+]] [[PhiZ1]] ]     loop_header:[[HeaderY]]
210# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
211#
212#                               ### Inner loop ###
213# CHECK-DAG:     [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ]] ]                   loop_header:[[HeaderZ:B\d+]]
214# CHECK-DAG:     [[XorZ]]       Xor [ [[PhiZ2]] [[Cst1]] ]                   loop_header:[[HeaderZ]]
215# CHECK-DAG:     [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ]                  loop_header:[[HeaderZ]]
216# CHECK-DAG:                    If [ [[CondZ]] ]                             loop_header:[[HeaderZ]]
217#
218# CHECK-DAG:     [[Add5]]       Add [ [[PhiX]] [[Cst5]] ]                    loop_header:[[HeaderY]]
219# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
220# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
221
222# CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (after)
223# CHECK-DAG:     [[ArgX:i\d+]]  ParameterValue
224# CHECK-DAG:     [[ArgY:z\d+]]  ParameterValue
225# CHECK-DAG:     [[ArgZ:z\d+]]  ParameterValue
226# CHECK-DAG:     [[Cst0:i\d+]]  IntConstant 0
227# CHECK-DAG:     [[Cst1:i\d+]]  IntConstant 1
228# CHECK-DAG:     [[Cst7:i\d+]]  IntConstant 7
229#
230# CHECK-DAG:     [[PhiX:i\d+]]  Phi [ [[ArgX]] [[Add7:i\d+]] ]               loop_header:[[HeaderY:B\d+]]
231# CHECK-DAG:     [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[PhiZ1]] ]                   loop_header:[[HeaderY]]
232# CHECK-DAG:                    If [ [[ArgY]] ]                              loop_header:[[HeaderY]]
233# CHECK-DAG:     [[Add7]]       Add [ [[PhiX]] [[Cst7]] ]                    loop_header:[[HeaderY]]
234#
235#                               ### Inner loop ###
236# CHECK-DAG:     [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ:i\d+]] ]              loop_header:[[HeaderZ:B\d+]]
237# CHECK-DAG:     [[XorZ]]       Xor [ [[PhiZ2]] [[Cst1]] ]                   loop_header:[[HeaderZ]]
238# CHECK-DAG:     [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ]                  loop_header:[[HeaderZ]]
239# CHECK-DAG:                    If [ [[CondZ]] ]                             loop_header:[[HeaderZ]]
240#
241# CHECK-DAG:                    Return [ [[PhiX]] ]                          loop_header:null
242
243.method public static testInnerLoop(IZZ)I
244  .registers 4
245
246  # p0 = int X
247  # p1 = boolean Y
248  # p2 = boolean Z
249  # v0 = true
250
251  invoke-static {}, LTestCase;->$inline$True()Z
252  move-result v0
253
254  :loop_start
255  if-eqz p1, :loop_body   # cannot be determined statically
256
257  # Inner loop which will end up outside its parent
258  :inner_loop_start
259  xor-int/lit8 p2, p2, 1
260  if-eqz p2, :inner_loop_start
261
262  if-nez v0, :loop_end    # will always take the branch
263
264  # Dead block
265  add-int/lit8 p0, p0, 5
266  goto :loop_start
267
268  # Live block
269  :loop_body
270  add-int/lit8 p0, p0, 7
271  goto :loop_start
272
273  :loop_end
274  return p0
275.end method
276