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$after_inlining (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:<<HeaderY:B\d+>>
33## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
34## CHECK-DAG:                    If [<<Cst1>>]                              loop:<<HeaderY>>
35## CHECK-DAG:     <<Add5>>       Add [<<PhiX>>,<<Cst5>>]                    loop:<<HeaderY>>
36## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
37## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
38
39## CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination$after_inlining (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:<<HeaderY:B\d+>>
44## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
45## CHECK-DAG:     <<AddX>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
46## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
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$after_inlining (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:<<HeaderY:B\d+>>
84## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
85## CHECK-DAG:                    If [<<ArgZ>>]                              loop:<<HeaderY>>
86## CHECK-DAG:                    If [<<Cst1>>]                              loop:<<HeaderY>>
87## CHECK-DAG:     <<Add5>>       Add [<<PhiX>>,<<Cst5>>]                    loop:<<HeaderY>>
88## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
89## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
90
91## CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination$after_inlining (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:<<HeaderY:B\d+>>
97## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
98## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
99## CHECK-DAG:                    If [<<ArgZ>>]                              loop:none
100## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
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$after_inlining (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:     <<Cst11:i\d+>> IntConstant 11
140## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
141## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
142## CHECK-DAG:     <<Mul9:i\d+>>  Mul [<<PhiX>>,<<Cst11>>]                   loop:<<HeaderY>>
143## CHECK-DAG:     <<PhiY:i\d+>>  Phi [<<PhiX>>,<<Mul9>>]                    loop:<<HeaderY>>
144## CHECK-DAG:                    If [<<Cst1>>]                              loop:<<HeaderY>>
145## CHECK-DAG:     <<Add5>>       Add [<<PhiY>>,<<Cst5>>]                    loop:<<HeaderY>>
146## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
147## CHECK-DAG:                    Return [<<PhiY>>]                          loop:none
148
149## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination$after_inlining (after)
150## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
151## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
152## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
153## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
154## CHECK-DAG:     <<Cst11:i\d+>> IntConstant 11
155## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add7:i\d+>>]               loop:<<HeaderY:B\d+>>
156## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
157## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
158## CHECK-DAG:     <<Mul9:i\d+>>  Mul [<<PhiX>>,<<Cst11>>]                   loop:none
159## CHECK-DAG:     <<Phi:i\d+>>   Phi [<<PhiX>>,<<Mul9>>]                    loop:none
160## CHECK-DAG:                    Return [<<Phi>>]                           loop:none
161
162## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination$after_inlining (after)
163## CHECK-NOT:                    IntConstant 5
164
165## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) select_generator (after)
166## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
167## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
168## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
169## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
170## CHECK-DAG:     <<Cst11:i\d+>> IntConstant 11
171## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add7:i\d+>>]               loop:<<HeaderY:B\d+>>
172## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
173## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
174## CHECK-DAG:     <<Mul9:i\d+>>  Mul [<<PhiX>>,<<Cst11>>]                   loop:none
175## CHECK-DAG:     <<SelX:i\d+>>  Select [<<PhiX>>,<<Mul9>>,<<ArgZ>>]        loop:none
176## CHECK-DAG:                    Return [<<SelX>>]                          loop:none
177
178.method public static testExitPredecessors(IZZ)I
179  .registers 4
180
181  # p0 = int X
182  # p1 = boolean Y
183  # p2 = boolean Z
184  # v0 = true
185
186  invoke-static {}, LTestCase;->$inline$True()Z
187  move-result v0
188
189  :loop_start
190  if-eqz p1, :loop_body   # cannot be determined statically
191
192  # Additional logic which will end up outside the loop
193  if-eqz p2, :skip_if
194  mul-int/lit8 p0, p0, 11
195  :skip_if
196
197  if-nez v0, :loop_end    # will always take the branch
198
199  # Dead block
200  add-int/lit8 p0, p0, 5
201  goto :loop_start
202
203  # Live block
204  :loop_body
205  add-int/lit8 p0, p0, 7
206  goto :loop_start
207
208  :loop_end
209  return p0
210.end method
211
212
213## CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination$after_inlining (before)
214## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
215## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
216## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
217## CHECK-DAG:     <<Cst0:i\d+>>  IntConstant 0
218## CHECK-DAG:     <<Cst1:i\d+>>  IntConstant 1
219## CHECK-DAG:     <<Cst5:i\d+>>  IntConstant 5
220## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
221#
222## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
223## CHECK-DAG:     <<PhiZ1:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>,<<PhiZ1>>]     loop:<<HeaderY>>
224## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
225#
226#                                ### Inner loop ###
227## CHECK-DAG:     <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<XorZ>>]                   loop:<<HeaderZ:B\d+>>
228## CHECK-DAG:     <<XorZ>>       Xor [<<PhiZ2>>,<<Cst1>>]                   loop:<<HeaderZ>>
229## CHECK-DAG:     <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>]                  loop:<<HeaderZ>>
230## CHECK-DAG:                    If [<<CondZ>>]                             loop:<<HeaderZ>>
231#
232## CHECK-DAG:     <<Add5>>       Add [<<PhiX>>,<<Cst5>>]                    loop:<<HeaderY>>
233## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
234## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
235
236## CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination$after_inlining (after)
237## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
238## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
239## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
240## CHECK-DAG:     <<Cst0:i\d+>>  IntConstant 0
241## CHECK-DAG:     <<Cst1:i\d+>>  IntConstant 1
242## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
243#
244## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add7:i\d+>>]               loop:<<HeaderY:B\d+>>
245## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
246## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
247#
248#                                ### Inner loop ###
249## CHECK-DAG:     <<PhiZ:i\d+>>  Phi [<<ArgZ>>,<<XorZ:i\d+>>]               loop:<<HeaderZ:B\d+>>
250## CHECK-DAG:     <<XorZ>>       Xor [<<PhiZ>>,<<Cst1>>]                    loop:<<HeaderZ>>
251## CHECK-DAG:     <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>]                  loop:<<HeaderZ>>
252## CHECK-DAG:                    If [<<CondZ>>]                             loop:<<HeaderZ>>
253#
254## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
255
256.method public static testInnerLoop(IZZ)I
257  .registers 4
258
259  # p0 = int X
260  # p1 = boolean Y
261  # p2 = boolean Z
262  # v0 = true
263
264  invoke-static {}, LTestCase;->$inline$True()Z
265  move-result v0
266
267  :loop_start
268  if-eqz p1, :loop_body   # cannot be determined statically
269
270  # Inner loop which will end up outside its parent
271  :inner_loop_start
272  xor-int/lit8 p2, p2, 1
273  if-eqz p2, :inner_loop_start
274
275  if-nez v0, :loop_end    # will always take the branch
276
277  # Dead block
278  add-int/lit8 p0, p0, 5
279  goto :loop_start
280
281  # Live block
282  :loop_body
283  add-int/lit8 p0, p0, 7
284  goto :loop_start
285
286  :loop_end
287  return p0
288.end method
289