1# Copyright (C) 2017 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: void SmaliTests.bar() load_store_elimination (after)
19## CHECK-DAG: <<Null:l\d+>>       NullConstant
20## CHECK-DAG: <<BoundType:l\d+>>  BoundType [<<Null>>]
21## CHECK-DAG: <<CheckL:l\d+>>     NullCheck [<<BoundType>>]
22## CHECK-DAG: <<GetL0:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
23## CHECK-DAG: <<GetL1:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
24## CHECK-DAG: <<GetL2:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
25## CHECK-DAG: <<GetL3:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
26## CHECK-DAG: <<CheckJ:l\d+>>     NullCheck [<<Null>>]
27## CHECK-DAG: <<GetJ0:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
28## CHECK-DAG: <<GetJ1:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
29## CHECK-DAG: <<GetJ2:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
30## CHECK-DAG: <<GetJ3:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
31.method public static bar()V
32    .registers 7
33
34    .prologue
35    const/4 v6, 0x3
36    const/4 v5, 0x2
37    const/4 v4, 0x1
38    const/4 v3, 0x0
39
40    # We create multiple accesses that will lead the bounds check
41    # elimination pass to add a HDeoptimize. Not having the bounds check helped
42    # the load store elimination think it could merge two ArrayGet with different
43    # types.
44
45    # String[] array = (String[])getNull();
46    invoke-static {}, LMain;->getNull()Ljava/lang/Object;
47    move-result-object v0
48    check-cast v0, [Ljava/lang/String;
49
50    # objectField = array[0];
51    aget-object v2, v0, v3
52    sput-object v2, LMain;->objectField:Ljava/lang/Object;
53    # objectField = array[1];
54    aget-object v2, v0, v4
55    sput-object v2, LMain;->objectField:Ljava/lang/Object;
56    # objectField = array[2];
57    aget-object v2, v0, v5
58    sput-object v2, LMain;->objectField:Ljava/lang/Object;
59    # objectField = array[3];
60    aget-object v2, v0, v6
61    sput-object v2, LMain;->objectField:Ljava/lang/Object;
62
63    # long[] longArray = getLongArray();
64    invoke-static {}, LMain;->getLongArray()[J
65    move-result-object v1
66
67    # longField = longArray[0];
68    aget-wide v2, v1, v3
69    sput-wide v2, LMain;->longField:J
70    # longField = longArray[1];
71    aget-wide v2, v1, v4
72    sput-wide v2, LMain;->longField:J
73    # longField = longArray[2];
74    aget-wide v2, v1, v5
75    sput-wide v2, LMain;->longField:J
76    # longField = longArray[3];
77    aget-wide v2, v1, v6
78    sput-wide v2, LMain;->longField:J
79
80    return-void
81.end method
82
83#   This is indentical to bar() except that it has two check-casts
84#   that DX tends to generate.
85
86##  CHECK-START: void SmaliTests.bar2() load_store_elimination (after)
87##  CHECK-DAG: <<Null:l\d+>>       NullConstant
88##  CHECK-DAG: <<BoundFirst:l\d+>> BoundType [<<Null>>]
89##  CHECK-DAG: <<BoundType:l\d+>>  BoundType [<<BoundFirst>>]
90##  CHECK-DAG: <<CheckL:l\d+>>     NullCheck [<<BoundType>>]
91##  CHECK-DAG: <<GetL0:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
92##  CHECK-DAG: <<GetL1:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
93##  CHECK-DAG: <<GetL2:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
94##  CHECK-DAG: <<GetL3:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
95##  CHECK-DAG: <<CheckJ:l\d+>>     NullCheck [<<Null>>]
96##  CHECK-DAG: <<GetJ0:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
97##  CHECK-DAG: <<GetJ1:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
98##  CHECK-DAG: <<GetJ2:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
99##  CHECK-DAG: <<GetJ3:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
100.method public static bar2()V
101    .registers 7
102
103    .prologue
104    const/4 v6, 0x3
105    const/4 v5, 0x2
106    const/4 v4, 0x1
107    const/4 v3, 0x0
108
109    # We create multiple accesses that will lead the bounds check
110    # elimination pass to add a HDeoptimize. Not having the bounds check helped
111    # the load store elimination think it could merge two ArrayGet with different
112    # types.
113
114    # String[] array = (String[])getNull();
115    invoke-static {}, LMain;->getNull()Ljava/lang/Object;
116    move-result-object v2
117    check-cast v2, [Ljava/lang/String;
118
119    move-object v0, v2
120    check-cast v0, [Ljava/lang/String;
121
122    # objectField = array[0];
123    aget-object v2, v0, v3
124    sput-object v2, LMain;->objectField:Ljava/lang/Object;
125    # objectField = array[1];
126    aget-object v2, v0, v4
127    sput-object v2, LMain;->objectField:Ljava/lang/Object;
128    # objectField = array[2];
129    aget-object v2, v0, v5
130    sput-object v2, LMain;->objectField:Ljava/lang/Object;
131    # objectField = array[3];
132    aget-object v2, v0, v6
133    sput-object v2, LMain;->objectField:Ljava/lang/Object;
134
135    # long[] longArray = getLongArray();
136    invoke-static {}, LMain;->getLongArray()[J
137    move-result-object v1
138
139    # longField = longArray[0];
140    aget-wide v2, v1, v3
141    sput-wide v2, LMain;->longField:J
142    # longField = longArray[1];
143    aget-wide v2, v1, v4
144    sput-wide v2, LMain;->longField:J
145    # longField = longArray[2];
146    aget-wide v2, v1, v5
147    sput-wide v2, LMain;->longField:J
148    # longField = longArray[3];
149    aget-wide v2, v1, v6
150    sput-wide v2, LMain;->longField:J
151
152    return-void
153.end method
154
155# static fields
156.field static doThrow:Z # boolean
157
158# direct methods
159.method static constructor <clinit>()V
160    .registers 1
161
162    .prologue
163    # doThrow = false
164    const/4 v0, 0x0
165    sput-boolean v0, LSmaliTests;->doThrow:Z
166    return-void
167.end method
168