1# Copyright (C) 2016 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 LSmaliTests;
16.super Ljava/lang/Object;
17
18## CHECK-START: int SmaliTests.EqualTrueRhs(boolean) instruction_simplifier (before)
19## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
20## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
21## CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Arg>>,<<Const1>>]
22## CHECK-DAG:                       If [<<Cond>>]
23
24## CHECK-START: int SmaliTests.EqualTrueRhs(boolean) instruction_simplifier (after)
25## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
26## CHECK-DAG:                       If [<<Arg>>]
27
28.method public static EqualTrueRhs(Z)I
29  .registers 3
30
31  const v0, 0x1
32  const v1, 0x5
33  if-eq p0, v0, :return
34  const v1, 0x3
35  :return
36  return v1
37
38.end method
39
40## CHECK-START: int SmaliTests.EqualTrueLhs(boolean) instruction_simplifier (before)
41## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
42## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
43## CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Const1>>,<<Arg>>]
44## CHECK-DAG:                       If [<<Cond>>]
45
46## CHECK-START: int SmaliTests.EqualTrueLhs(boolean) instruction_simplifier (after)
47## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
48## CHECK-DAG:                       If [<<Arg>>]
49
50.method public static EqualTrueLhs(Z)I
51  .registers 3
52
53  const v0, 0x1
54  const v1, 0x5
55  if-eq v0, p0, :return
56  const v1, 0x3
57  :return
58  return v1
59
60.end method
61
62## CHECK-START: int SmaliTests.EqualFalseRhs(boolean) instruction_simplifier (before)
63## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
64## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
65## CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Arg>>,<<Const0>>]
66## CHECK-DAG:                       If [<<Cond>>]
67
68## CHECK-START: int SmaliTests.EqualFalseRhs(boolean) instruction_simplifier (after)
69## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
70## CHECK-DAG:                       If [<<Arg>>]
71
72.method public static EqualFalseRhs(Z)I
73  .registers 3
74
75  const v0, 0x0
76  const v1, 0x3
77  if-eq p0, v0, :return
78  const v1, 0x5
79  :return
80  return v1
81
82.end method
83
84## CHECK-START: int SmaliTests.EqualFalseLhs(boolean) instruction_simplifier (before)
85## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
86## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
87## CHECK-DAG:     <<Cond:z\d+>>     Equal [<<Const0>>,<<Arg>>]
88## CHECK-DAG:                       If [<<Cond>>]
89
90## CHECK-START: int SmaliTests.EqualFalseLhs(boolean) instruction_simplifier (after)
91## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
92## CHECK-DAG:                       If [<<Arg>>]
93
94.method public static EqualFalseLhs(Z)I
95  .registers 3
96
97  const v0, 0x0
98  const v1, 0x3
99  if-eq v0, p0, :return
100  const v1, 0x5
101  :return
102  return v1
103
104.end method
105
106## CHECK-START: int SmaliTests.NotEqualTrueRhs(boolean) instruction_simplifier (before)
107## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
108## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
109## CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Arg>>,<<Const1>>]
110## CHECK-DAG:                       If [<<Cond>>]
111
112## CHECK-START: int SmaliTests.NotEqualTrueRhs(boolean) instruction_simplifier (after)
113## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
114## CHECK-DAG:                       If [<<Arg>>]
115
116.method public static NotEqualTrueRhs(Z)I
117  .registers 3
118
119  const v0, 0x1
120  const v1, 0x3
121  if-ne p0, v0, :return
122  const v1, 0x5
123  :return
124  return v1
125
126.end method
127
128## CHECK-START: int SmaliTests.NotEqualTrueLhs(boolean) instruction_simplifier (before)
129## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
130## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
131## CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Const1>>,<<Arg>>]
132## CHECK-DAG:                       If [<<Cond>>]
133
134## CHECK-START: int SmaliTests.NotEqualTrueLhs(boolean) instruction_simplifier (after)
135## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
136## CHECK-DAG:                       If [<<Arg>>]
137
138.method public static NotEqualTrueLhs(Z)I
139  .registers 3
140
141  const v0, 0x1
142  const v1, 0x3
143  if-ne v0, p0, :return
144  const v1, 0x5
145  :return
146  return v1
147
148.end method
149
150## CHECK-START: int SmaliTests.NotEqualFalseRhs(boolean) instruction_simplifier (before)
151## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
152## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
153## CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Arg>>,<<Const0>>]
154## CHECK-DAG:                       If [<<Cond>>]
155
156## CHECK-START: int SmaliTests.NotEqualFalseRhs(boolean) instruction_simplifier (after)
157## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
158## CHECK-DAG:                       If [<<Arg>>]
159
160.method public static NotEqualFalseRhs(Z)I
161  .registers 3
162
163  const v0, 0x0
164  const v1, 0x5
165  if-ne p0, v0, :return
166  const v1, 0x3
167  :return
168  return v1
169
170.end method
171
172## CHECK-START: int SmaliTests.NotEqualFalseLhs(boolean) instruction_simplifier (before)
173## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
174## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
175## CHECK-DAG:     <<Cond:z\d+>>     NotEqual [<<Const0>>,<<Arg>>]
176## CHECK-DAG:                       If [<<Cond>>]
177
178## CHECK-START: int SmaliTests.NotEqualFalseLhs(boolean) instruction_simplifier (after)
179## CHECK-DAG:     <<Arg:z\d+>>      ParameterValue
180## CHECK-DAG:                       If [<<Arg>>]
181
182.method public static NotEqualFalseLhs(Z)I
183  .registers 3
184
185  const v0, 0x0
186  const v1, 0x5
187  if-ne v0, p0, :return
188  const v1, 0x3
189  :return
190  return v1
191
192.end method
193
194## CHECK-START: int SmaliTests.AddSubConst(int) instruction_simplifier (before)
195## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
196## CHECK-DAG:     <<Const7:i\d+>>    IntConstant 7
197## CHECK-DAG:     <<Const8:i\d+>>    IntConstant 8
198## CHECK-DAG:     <<Add:i\d+>>       Add [<<ArgValue>>,<<Const7>>]
199## CHECK-DAG:     <<Sub:i\d+>>       Sub [<<Add>>,<<Const8>>]
200## CHECK-DAG:                        Return [<<Sub>>]
201
202## CHECK-START: int SmaliTests.AddSubConst(int) instruction_simplifier (after)
203## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
204## CHECK-DAG:     <<ConstM1:i\d+>>   IntConstant -1
205## CHECK-DAG:     <<Add:i\d+>>       Add [<<ArgValue>>,<<ConstM1>>]
206## CHECK-DAG:                        Return [<<Add>>]
207
208.method public static AddSubConst(I)I
209    .registers 3
210
211    .prologue
212    add-int/lit8 v0, p0, 7
213
214    const/16 v1, 8
215
216    sub-int v0, v0, v1
217
218    return v0
219.end method
220
221## CHECK-START: int SmaliTests.SubAddConst(int) instruction_simplifier (before)
222## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
223## CHECK-DAG:     <<Const3:i\d+>>    IntConstant 3
224## CHECK-DAG:     <<Const4:i\d+>>    IntConstant 4
225## CHECK-DAG:     <<Sub:i\d+>>       Sub [<<ArgValue>>,<<Const3>>]
226## CHECK-DAG:     <<Add:i\d+>>       Add [<<Sub>>,<<Const4>>]
227## CHECK-DAG:                        Return [<<Add>>]
228
229## CHECK-START: int SmaliTests.SubAddConst(int) instruction_simplifier (after)
230## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
231## CHECK-DAG:     <<Const1:i\d+>>    IntConstant 1
232## CHECK-DAG:     <<Add:i\d+>>       Add [<<ArgValue>>,<<Const1>>]
233## CHECK-DAG:                        Return [<<Add>>]
234
235.method public static SubAddConst(I)I
236    .registers 2
237
238    .prologue
239    const/4 v0, 3
240
241    sub-int v0, p0, v0
242
243    add-int/lit8 v0, v0, 4
244
245    return v0
246.end method
247
248## CHECK-START: int SmaliTests.SubSubConst1(int) instruction_simplifier (before)
249## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
250## CHECK-DAG:     <<Const9:i\d+>>    IntConstant 9
251## CHECK-DAG:     <<Const10:i\d+>>   IntConstant 10
252## CHECK-DAG:     <<Sub1:i\d+>>      Sub [<<ArgValue>>,<<Const9>>]
253## CHECK-DAG:     <<Sub2:i\d+>>      Sub [<<Sub1>>,<<Const10>>]
254## CHECK-DAG:                        Return [<<Sub2>>]
255
256## CHECK-START: int SmaliTests.SubSubConst1(int) instruction_simplifier (after)
257## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
258## CHECK-DAG:     <<ConstM19:i\d+>>  IntConstant -19
259## CHECK-DAG:     <<Add:i\d+>>       Add [<<ArgValue>>,<<ConstM19>>]
260## CHECK-DAG:                        Return [<<Add>>]
261
262.method public static SubSubConst1(I)I
263    .registers 3
264
265    .prologue
266    const/16 v1, 9
267
268    sub-int v0, p0, v1
269
270    const/16 v1, 10
271
272    sub-int v0, v0, v1
273
274    return v0
275.end method
276
277## CHECK-START: int SmaliTests.SubSubConst2(int) instruction_simplifier (before)
278## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
279## CHECK-DAG:     <<Const11:i\d+>>   IntConstant 11
280## CHECK-DAG:     <<Const12:i\d+>>   IntConstant 12
281## CHECK-DAG:     <<Sub1:i\d+>>      Sub [<<Const11>>,<<ArgValue>>]
282## CHECK-DAG:     <<Sub2:i\d+>>      Sub [<<Sub1>>,<<Const12>>]
283## CHECK-DAG:                        Return [<<Sub2>>]
284
285## CHECK-START: int SmaliTests.SubSubConst2(int) instruction_simplifier (after)
286## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
287## CHECK-DAG:     <<ConstM1:i\d+>>   IntConstant -1
288## CHECK-DAG:     <<Sub:i\d+>>       Sub [<<ConstM1>>,<<ArgValue>>]
289## CHECK-DAG:                        Return [<<Sub>>]
290
291.method public static SubSubConst2(I)I
292    .registers 3
293
294    .prologue
295    rsub-int/lit8 v0, p0, 11
296
297    const/16 v1, 12
298
299    sub-int v0, v0, v1
300
301    return v0
302.end method
303
304## CHECK-START: int SmaliTests.SubSubConst3(int) instruction_simplifier (before)
305## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
306## CHECK-DAG:     <<Const15:i\d+>>   IntConstant 15
307## CHECK-DAG:     <<Const16:i\d+>>   IntConstant 16
308## CHECK-DAG:     <<Sub1:i\d+>>      Sub [<<ArgValue>>,<<Const16>>]
309## CHECK-DAG:     <<Sub2:i\d+>>      Sub [<<Const15>>,<<Sub1>>]
310## CHECK-DAG:                        Return [<<Sub2>>]
311
312## CHECK-START: int SmaliTests.SubSubConst3(int) instruction_simplifier (after)
313## CHECK-DAG:     <<ArgValue:i\d+>>  ParameterValue
314## CHECK-DAG:     <<Const31:i\d+>>   IntConstant 31
315## CHECK-DAG:     <<Sub:i\d+>>       Sub [<<Const31>>,<<ArgValue>>]
316## CHECK-DAG:                        Return [<<Sub>>]
317
318.method public static SubSubConst3(I)I
319    .registers 2
320
321    .prologue
322    const/16 v0, 16
323
324    sub-int v0, p0, v0
325
326    rsub-int/lit8 v0, v0, 15
327
328    return v0
329.end method
330
331# Test simplification of the `~~var` pattern.
332# The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
333
334## CHECK-START: long SmaliTests.$noinline$NotNot1(long) instruction_simplifier (before)
335## CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
336## CHECK-DAG:     <<Not1:j\d+>>     Not [<<Arg>>]
337## CHECK-DAG:     <<Not2:j\d+>>     Not [<<Not1>>]
338## CHECK-DAG:                       Return [<<Not2>>]
339
340## CHECK-START: long SmaliTests.$noinline$NotNot1(long) instruction_simplifier (after)
341## CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
342## CHECK-DAG:                       Return [<<Arg>>]
343
344## CHECK-START: long SmaliTests.$noinline$NotNot1(long) instruction_simplifier (after)
345## CHECK-NOT:                       Not
346
347.method public static $noinline$NotNot1(J)J
348    .registers 4
349    .param p0, "arg"    # J
350
351    .prologue
352
353    # return ~~arg
354    not-long v0, p0
355    not-long v0, v0
356    return-wide v0
357.end method
358
359## CHECK-START: int SmaliTests.$noinline$NotNot2(int) instruction_simplifier (before)
360## CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
361## CHECK-DAG:     <<Not1:i\d+>>     Not [<<Arg>>]
362## CHECK-DAG:     <<Not2:i\d+>>     Not [<<Not1>>]
363## CHECK-DAG:     <<Add:i\d+>>      Add [<<Not2>>,<<Not1>>]
364## CHECK-DAG:                       Return [<<Add>>]
365
366## CHECK-START: int SmaliTests.$noinline$NotNot2(int) instruction_simplifier (after)
367## CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
368## CHECK-DAG:     <<Not:i\d+>>      Not [<<Arg>>]
369## CHECK-DAG:     <<Add:i\d+>>      Add [<<Arg>>,<<Not>>]
370## CHECK-DAG:                       Return [<<Add>>]
371
372## CHECK-START: int SmaliTests.$noinline$NotNot2(int) instruction_simplifier (after)
373## CHECK:                           Not
374## CHECK-NOT:                       Not
375
376.method public static $noinline$NotNot2(I)I
377    .registers 3
378    .param p0, "arg"    # I
379
380    .prologue
381
382    # temp = ~arg; return temp + ~temp;
383    not-int v0, p0
384    not-int v1, v0
385    add-int/2addr v1, v0
386
387    return v1
388.end method
389
390# Test simplification of double Boolean negation. Note that sometimes
391# both negations can be removed but we only expect the simplifier to
392# remove the second.
393
394## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) instruction_simplifier (before)
395## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
396## CHECK-DAG:     <<Const1:i\d+>>    IntConstant 1
397## CHECK-DAG:     <<Result:z\d+>>    InvokeStaticOrDirect
398## CHECK-DAG:     <<NotResult:i\d+>> Xor [<<Result>>,<<Const1>>]
399## CHECK-DAG:                        Return [<<NotResult>>]
400
401## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) instruction_simplifier (after)
402## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
403## CHECK-DAG:     <<Result:z\d+>>    InvokeStaticOrDirect
404## CHECK-DAG:     <<NotResult:z\d+>> BooleanNot [<<Result>>]
405## CHECK-DAG:                        Return [<<NotResult>>]
406
407## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) instruction_simplifier$after_inlining (before)
408## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
409## CHECK-DAG:     <<NotArg:z\d+>>    BooleanNot [<<Arg>>]
410## CHECK-DAG:     <<NotNotArg:z\d+>> BooleanNot [<<NotArg>>]
411## CHECK-DAG:                        Return [<<NotNotArg>>]
412
413## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) instruction_simplifier$after_inlining (after)
414## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
415## CHECK-DAG:     <<NotArg:z\d+>>    BooleanNot [<<Arg>>]
416## CHECK-DAG:                        Return [<<Arg>>]
417
418## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) dead_code_elimination$final (after)
419## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
420## CHECK-DAG:                        Return [<<Arg>>]
421
422.method public static NegateValue(Z)Z
423    .registers 2
424    .param p0, "arg"    # Z
425
426    .prologue
427
428    # return !arg
429    xor-int/lit8 v0, p0, 0x1
430    return v0
431.end method
432
433
434.method public static $noinline$NotNotBool(Z)Z
435    .registers 2
436    .param p0, "arg"    # Z
437
438    .prologue
439
440    # return !Negate(arg)
441    invoke-static {p0}, LSmaliTests;->NegateValue(Z)Z
442    move-result v0
443    xor-int/lit8 v0, v0, 0x1
444
445    return v0
446.end method
447