1*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2017 The Android Open Source Project 2*795d594fSAndroid Build Coastguard Worker# 3*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*795d594fSAndroid Build Coastguard Worker# 7*795d594fSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*795d594fSAndroid Build Coastguard Worker# 9*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*795d594fSAndroid Build Coastguard Worker# limitations under the License. 14*795d594fSAndroid Build Coastguard Worker 15*795d594fSAndroid Build Coastguard Worker.class public LSmaliTests; 16*795d594fSAndroid Build Coastguard Worker.super Ljava/lang/Object; 17*795d594fSAndroid Build Coastguard Worker 18*795d594fSAndroid Build Coastguard Worker## CHECK-START: void SmaliTests.bar() load_store_elimination (after) 19*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<Null:l\d+>> NullConstant 20*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<BoundType:l\d+>> BoundType [<<Null>>] 21*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<CheckL:l\d+>> NullCheck [<<BoundType>>] 22*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetL0:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] 23*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetL1:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] 24*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetL2:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] 25*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetL3:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] 26*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<CheckJ:l\d+>> NullCheck [<<Null>>] 27*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetJ0:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] 28*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetJ1:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] 29*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetJ2:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] 30*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetJ3:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] 31*795d594fSAndroid Build Coastguard Worker.method public static bar()V 32*795d594fSAndroid Build Coastguard Worker .registers 7 33*795d594fSAndroid Build Coastguard Worker 34*795d594fSAndroid Build Coastguard Worker .prologue 35*795d594fSAndroid Build Coastguard Worker const/4 v6, 0x3 36*795d594fSAndroid Build Coastguard Worker const/4 v5, 0x2 37*795d594fSAndroid Build Coastguard Worker const/4 v4, 0x1 38*795d594fSAndroid Build Coastguard Worker const/4 v3, 0x0 39*795d594fSAndroid Build Coastguard Worker 40*795d594fSAndroid Build Coastguard Worker # We create multiple accesses that will lead the bounds check 41*795d594fSAndroid Build Coastguard Worker # elimination pass to add a HDeoptimize. Not having the bounds check helped 42*795d594fSAndroid Build Coastguard Worker # the load store elimination think it could merge two ArrayGet with different 43*795d594fSAndroid Build Coastguard Worker # types. 44*795d594fSAndroid Build Coastguard Worker 45*795d594fSAndroid Build Coastguard Worker # String[] array = (String[])getNull(); 46*795d594fSAndroid Build Coastguard Worker invoke-static {}, LMain;->getNull()Ljava/lang/Object; 47*795d594fSAndroid Build Coastguard Worker move-result-object v0 48*795d594fSAndroid Build Coastguard Worker check-cast v0, [Ljava/lang/String; 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker # objectField = array[0]; 51*795d594fSAndroid Build Coastguard Worker aget-object v2, v0, v3 52*795d594fSAndroid Build Coastguard Worker sput-object v2, LMain;->objectField:Ljava/lang/Object; 53*795d594fSAndroid Build Coastguard Worker # objectField = array[1]; 54*795d594fSAndroid Build Coastguard Worker aget-object v2, v0, v4 55*795d594fSAndroid Build Coastguard Worker sput-object v2, LMain;->objectField:Ljava/lang/Object; 56*795d594fSAndroid Build Coastguard Worker # objectField = array[2]; 57*795d594fSAndroid Build Coastguard Worker aget-object v2, v0, v5 58*795d594fSAndroid Build Coastguard Worker sput-object v2, LMain;->objectField:Ljava/lang/Object; 59*795d594fSAndroid Build Coastguard Worker # objectField = array[3]; 60*795d594fSAndroid Build Coastguard Worker aget-object v2, v0, v6 61*795d594fSAndroid Build Coastguard Worker sput-object v2, LMain;->objectField:Ljava/lang/Object; 62*795d594fSAndroid Build Coastguard Worker 63*795d594fSAndroid Build Coastguard Worker # long[] longArray = getLongArray(); 64*795d594fSAndroid Build Coastguard Worker invoke-static {}, LMain;->getLongArray()[J 65*795d594fSAndroid Build Coastguard Worker move-result-object v1 66*795d594fSAndroid Build Coastguard Worker 67*795d594fSAndroid Build Coastguard Worker # longField = longArray[0]; 68*795d594fSAndroid Build Coastguard Worker aget-wide v2, v1, v3 69*795d594fSAndroid Build Coastguard Worker sput-wide v2, LMain;->longField:J 70*795d594fSAndroid Build Coastguard Worker # longField = longArray[1]; 71*795d594fSAndroid Build Coastguard Worker aget-wide v2, v1, v4 72*795d594fSAndroid Build Coastguard Worker sput-wide v2, LMain;->longField:J 73*795d594fSAndroid Build Coastguard Worker # longField = longArray[2]; 74*795d594fSAndroid Build Coastguard Worker aget-wide v2, v1, v5 75*795d594fSAndroid Build Coastguard Worker sput-wide v2, LMain;->longField:J 76*795d594fSAndroid Build Coastguard Worker # longField = longArray[3]; 77*795d594fSAndroid Build Coastguard Worker aget-wide v2, v1, v6 78*795d594fSAndroid Build Coastguard Worker sput-wide v2, LMain;->longField:J 79*795d594fSAndroid Build Coastguard Worker 80*795d594fSAndroid Build Coastguard Worker return-void 81*795d594fSAndroid Build Coastguard Worker.end method 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker# This is indentical to bar() except that it has two check-casts 84*795d594fSAndroid Build Coastguard Worker# that DX tends to generate. 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker## CHECK-START: void SmaliTests.bar2() load_store_elimination (after) 87*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<Null:l\d+>> NullConstant 88*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<BoundFirst:l\d+>> BoundType [<<Null>>] 89*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<BoundType:l\d+>> BoundType [<<BoundFirst>>] 90*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<CheckL:l\d+>> NullCheck [<<BoundType>>] 91*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetL0:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] 92*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetL1:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] 93*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetL2:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] 94*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetL3:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}] 95*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<CheckJ:l\d+>> NullCheck [<<Null>>] 96*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetJ0:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] 97*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetJ1:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] 98*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetJ2:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] 99*795d594fSAndroid Build Coastguard Worker## CHECK-DAG: <<GetJ3:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}] 100*795d594fSAndroid Build Coastguard Worker.method public static bar2()V 101*795d594fSAndroid Build Coastguard Worker .registers 7 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker .prologue 104*795d594fSAndroid Build Coastguard Worker const/4 v6, 0x3 105*795d594fSAndroid Build Coastguard Worker const/4 v5, 0x2 106*795d594fSAndroid Build Coastguard Worker const/4 v4, 0x1 107*795d594fSAndroid Build Coastguard Worker const/4 v3, 0x0 108*795d594fSAndroid Build Coastguard Worker 109*795d594fSAndroid Build Coastguard Worker # We create multiple accesses that will lead the bounds check 110*795d594fSAndroid Build Coastguard Worker # elimination pass to add a HDeoptimize. Not having the bounds check helped 111*795d594fSAndroid Build Coastguard Worker # the load store elimination think it could merge two ArrayGet with different 112*795d594fSAndroid Build Coastguard Worker # types. 113*795d594fSAndroid Build Coastguard Worker 114*795d594fSAndroid Build Coastguard Worker # String[] array = (String[])getNull(); 115*795d594fSAndroid Build Coastguard Worker invoke-static {}, LMain;->getNull()Ljava/lang/Object; 116*795d594fSAndroid Build Coastguard Worker move-result-object v2 117*795d594fSAndroid Build Coastguard Worker check-cast v2, [Ljava/lang/String; 118*795d594fSAndroid Build Coastguard Worker 119*795d594fSAndroid Build Coastguard Worker move-object v0, v2 120*795d594fSAndroid Build Coastguard Worker check-cast v0, [Ljava/lang/String; 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker # objectField = array[0]; 123*795d594fSAndroid Build Coastguard Worker aget-object v2, v0, v3 124*795d594fSAndroid Build Coastguard Worker sput-object v2, LMain;->objectField:Ljava/lang/Object; 125*795d594fSAndroid Build Coastguard Worker # objectField = array[1]; 126*795d594fSAndroid Build Coastguard Worker aget-object v2, v0, v4 127*795d594fSAndroid Build Coastguard Worker sput-object v2, LMain;->objectField:Ljava/lang/Object; 128*795d594fSAndroid Build Coastguard Worker # objectField = array[2]; 129*795d594fSAndroid Build Coastguard Worker aget-object v2, v0, v5 130*795d594fSAndroid Build Coastguard Worker sput-object v2, LMain;->objectField:Ljava/lang/Object; 131*795d594fSAndroid Build Coastguard Worker # objectField = array[3]; 132*795d594fSAndroid Build Coastguard Worker aget-object v2, v0, v6 133*795d594fSAndroid Build Coastguard Worker sput-object v2, LMain;->objectField:Ljava/lang/Object; 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker # long[] longArray = getLongArray(); 136*795d594fSAndroid Build Coastguard Worker invoke-static {}, LMain;->getLongArray()[J 137*795d594fSAndroid Build Coastguard Worker move-result-object v1 138*795d594fSAndroid Build Coastguard Worker 139*795d594fSAndroid Build Coastguard Worker # longField = longArray[0]; 140*795d594fSAndroid Build Coastguard Worker aget-wide v2, v1, v3 141*795d594fSAndroid Build Coastguard Worker sput-wide v2, LMain;->longField:J 142*795d594fSAndroid Build Coastguard Worker # longField = longArray[1]; 143*795d594fSAndroid Build Coastguard Worker aget-wide v2, v1, v4 144*795d594fSAndroid Build Coastguard Worker sput-wide v2, LMain;->longField:J 145*795d594fSAndroid Build Coastguard Worker # longField = longArray[2]; 146*795d594fSAndroid Build Coastguard Worker aget-wide v2, v1, v5 147*795d594fSAndroid Build Coastguard Worker sput-wide v2, LMain;->longField:J 148*795d594fSAndroid Build Coastguard Worker # longField = longArray[3]; 149*795d594fSAndroid Build Coastguard Worker aget-wide v2, v1, v6 150*795d594fSAndroid Build Coastguard Worker sput-wide v2, LMain;->longField:J 151*795d594fSAndroid Build Coastguard Worker 152*795d594fSAndroid Build Coastguard Worker return-void 153*795d594fSAndroid Build Coastguard Worker.end method 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker# static fields 156*795d594fSAndroid Build Coastguard Worker.field static doThrow:Z # boolean 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker# direct methods 159*795d594fSAndroid Build Coastguard Worker.method static constructor <clinit>()V 160*795d594fSAndroid Build Coastguard Worker .registers 1 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker .prologue 163*795d594fSAndroid Build Coastguard Worker # doThrow = false 164*795d594fSAndroid Build Coastguard Worker const/4 v0, 0x0 165*795d594fSAndroid Build Coastguard Worker sput-boolean v0, LSmaliTests;->doThrow:Z 166*795d594fSAndroid Build Coastguard Worker return-void 167*795d594fSAndroid Build Coastguard Worker.end method 168