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 LArrayGet; 16.super Ljava/lang/Object; 17 18 19# Test phi with fixed-type ArrayGet as an input and a matching second input. 20# The phi should be typed accordingly. 21 22## CHECK-START: void ArrayGet.matchingFixedType(float[], float) builder (after) 23## CHECK-NOT: Phi 24 25## CHECK-START-DEBUGGABLE: void ArrayGet.matchingFixedType(float[], float) builder (after) 26## CHECK-DAG: <<Arg1:f\d+>> ParameterValue 27## CHECK-DAG: <<Aget:f\d+>> ArrayGet 28## CHECK-DAG: {{f\d+}} Phi [<<Aget>>,<<Arg1>>] reg:0 29.method public static matchingFixedType([FF)V 30 .registers 8 31 32 const v0, 0x0 33 const v1, 0x1 34 35 aget v0, p0, v0 # read value 36 add-float v2, v0, v1 # float use fixes type 37 38 float-to-int v2, p1 39 if-eqz v2, :after 40 move v0, p1 41 :after 42 # v0 = Phi [ArrayGet, Arg1] => float 43 44 invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use 45 return-void 46.end method 47 48 49# Test phi with fixed-type ArrayGet as an input and a conflicting second input. 50# The phi should be eliminated due to the conflict. 51 52## CHECK-START: void ArrayGet.conflictingFixedType(float[], int) builder (after) 53## CHECK-NOT: Phi 54 55## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType(float[], int) builder (after) 56## CHECK-NOT: Phi 57.method public static conflictingFixedType([FI)V 58 .registers 8 59 60 const v0, 0x0 61 const v1, 0x1 62 63 aget v0, p0, v0 # read value 64 add-float v2, v0, v1 # float use fixes type 65 66 if-eqz p1, :after 67 move v0, p1 68 :after 69 # v0 = Phi [ArrayGet, Arg1] => conflict 70 71 invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use 72 return-void 73.end method 74 75 76# Same test as the one above, only this time tests that type of ArrayGet is not 77# changed. 78 79## CHECK-START: void ArrayGet.conflictingFixedType2(int[], float) builder (after) 80## CHECK-NOT: Phi 81 82## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType2(int[], float) builder (after) 83## CHECK-NOT: Phi 84 85## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType2(int[], float) builder (after) 86## CHECK: {{i\d+}} ArrayGet 87.method public static conflictingFixedType2([IF)V 88 .registers 8 89 90 const v0, 0x0 91 const v1, 0x1 92 93 aget v0, p0, v0 # read value 94 add-int v2, v0, v1 # int use fixes type 95 96 float-to-int v2, p1 97 if-eqz v2, :after 98 move v0, p1 99 :after 100 # v0 = Phi [ArrayGet, Arg1] => conflict 101 102 invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use 103 return-void 104.end method 105 106 107# Test phi with free-type ArrayGet as an input and a matching second input. 108# The phi should be typed accordingly. 109 110## CHECK-START: void ArrayGet.matchingFreeType(float[], float) builder (after) 111## CHECK-NOT: Phi 112 113## CHECK-START-DEBUGGABLE: void ArrayGet.matchingFreeType(float[], float) builder (after) 114## CHECK-DAG: <<Arg1:f\d+>> ParameterValue 115## CHECK-DAG: <<Aget:f\d+>> ArrayGet 116## CHECK-DAG: ArraySet [{{l\d+}},{{i\d+}},<<Aget>>] 117## CHECK-DAG: {{f\d+}} Phi [<<Aget>>,<<Arg1>>] reg:0 118.method public static matchingFreeType([FF)V 119 .registers 8 120 121 const v0, 0x0 122 const v1, 0x1 123 124 aget v0, p0, v0 # read value, should be float but has no typed use 125 aput v0, p0, v1 # aput does not disambiguate the type 126 127 float-to-int v2, p1 128 if-eqz v2, :after 129 move v0, p1 130 :after 131 # v0 = Phi [ArrayGet, Arg1] => float 132 133 invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use 134 return-void 135.end method 136 137 138# Test phi with free-type ArrayGet as an input and a conflicting second input. 139# The phi will be kept and typed according to the second input despite the 140# conflict. 141 142## CHECK-START: void ArrayGet.conflictingFreeType(int[], float) builder (after) 143## CHECK-NOT: Phi 144 145## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFreeType(int[], float) builder (after) 146## CHECK-NOT: Phi 147 148.method public static conflictingFreeType([IF)V 149 .registers 8 150 151 const v0, 0x0 152 const v1, 0x1 153 154 aget v0, p0, v0 # read value, should be int but has no typed use 155 aput v0, p0, v1 156 157 float-to-int v2, p1 158 if-eqz v2, :after 159 move v0, p1 160 :after 161 # v0 = Phi [ArrayGet, Arg1] => float 162 163 invoke-static {}, Ljava/lang/System;->nanoTime()J # create an env use 164 return-void 165.end method 166 167 168# Test that real use of ArrayGet is propagated through phis. The following test 169# case uses ArrayGet indirectly through two phis. It also creates an unused 170# conflicting phi which should not be preserved. 171 172## CHECK-START: void ArrayGet.conflictingPhiUses(int[], float, boolean, boolean, boolean) builder (after) 173## CHECK: InvokeStaticOrDirect env:[[{{i\d+}},{{i\d+}},_,{{i\d+}},{{.*}} 174 175.method public static conflictingPhiUses([IFZZZ)V 176 .registers 10 177 178 const v0, 0x0 179 180 # Create v1 = Phi [0x0, int ArrayGet] 181 move v1, v0 182 if-eqz p2, :else1 183 aget v1, p0, v0 184 :else1 185 186 # Create v2 = Phi [v1, float] 187 move v2, v1 188 if-eqz p3, :else2 189 move v2, p1 190 :else2 191 192 # Create v3 = Phi [v1, int] 193 move v3, v1 194 if-eqz p4, :else3 195 move v3, v0 196 :else3 197 198 # Use v3 as int. 199 add-int/lit8 v4, v3, 0x2a 200 201 # Create env uses. 202 invoke-static {}, Ljava/lang/System;->nanoTime()J 203 204 return-void 205.end method 206 207# Test that the right ArrayGet equivalent is always selected. The following test 208# case uses ArrayGet as float through one phi and as an indeterminate type through 209# another. The situation needs to be resolved so that only one instruction 210# remains. 211 212## CHECK-START: void ArrayGet.typedVsUntypedPhiUse(float[], float, boolean, boolean) builder (after) 213## CHECK: {{f\d+}} ArrayGet 214 215## CHECK-START: void ArrayGet.typedVsUntypedPhiUse(float[], float, boolean, boolean) builder (after) 216## CHECK-NOT: {{i\d+}} ArrayGet 217 218.method public static typedVsUntypedPhiUse([FFZZ)V 219 .registers 10 220 221 const v0, 0x0 222 223 # v1 = float ArrayGet 224 aget v1, p0, v0 225 226 # Create v2 = Phi [v1, 0.0f] 227 move v2, v1 228 if-eqz p2, :else1 229 move v2, v0 230 :else1 231 232 # Use v2 as float 233 cmpl-float v2, v2, p1 234 235 # Create v3 = Phi [v1, 0.0f] 236 move v3, v1 237 if-eqz p3, :else2 238 move v3, v0 239 :else2 240 241 # Use v3 without a determinate type. 242 aput v3, p0, v0 243 244 return-void 245.end method 246