blob: 0ea7d34043b7c8add283d7762b7b7fd14053cb14 [file] [log] [blame]
Nicolas Geoffray03971632016-03-17 10:44:24 +00001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010017class Test1 {
18 int[] iarr;
19}
20
21class Test2 {
22 float[] farr;
23}
24
Nicolas Geoffray03971632016-03-17 10:44:24 +000025public class Main {
26 public static Object[] getObjectArray() { return null; }
27 public static long[] getLongArray() { return null; }
Nicolas Geoffrayb1d91572016-03-18 16:25:38 +000028 public static Object getNull() { return null; }
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010029 public static Test1 getNullTest1() { return null; }
30 public static Test2 getNullTest2() { return null; }
Nicolas Geoffray03971632016-03-17 10:44:24 +000031
32 public static void main(String[] args) {
33 try {
34 foo();
35 throw new Error("Expected NullPointerException");
36 } catch (NullPointerException e) {
37 // Expected.
38 }
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010039 try {
40 bar();
41 throw new Error("Expected NullPointerException");
42 } catch (NullPointerException e) {
43 // Expected.
44 }
45 try {
46 test1();
47 throw new Error("Expected NullPointerException");
48 } catch (NullPointerException e) {
49 // Expected.
50 }
Nicolas Geoffray03971632016-03-17 10:44:24 +000051 }
52
53 /// CHECK-START: void Main.foo() load_store_elimination (after)
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010054 /// CHECK-DAG: <<Null:l\d+>> NullConstant
55 /// CHECK-DAG: <<Check:l\d+>> NullCheck [<<Null>>]
56 /// CHECK-DAG: <<Get1:j\d+>> ArrayGet [<<Check>>,{{i\d+}}]
57 /// CHECK-DAG: <<Get2:l\d+>> ArrayGet [<<Check>>,{{i\d+}}]
Nicolas Geoffray03971632016-03-17 10:44:24 +000058 public static void foo() {
59 longField = getLongArray()[0];
60 objectField = getObjectArray()[0];
61 }
62
Nicolas Geoffrayb1d91572016-03-18 16:25:38 +000063 /// CHECK-START: void Main.bar() load_store_elimination (after)
64 /// CHECK-DAG: <<Null:l\d+>> NullConstant
65 /// CHECK-DAG: <<BoundType:l\d+>> BoundType [<<Null>>]
66 /// CHECK-DAG: <<CheckL:l\d+>> NullCheck [<<BoundType>>]
67 /// CHECK-DAG: <<GetL0:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
68 /// CHECK-DAG: <<GetL1:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
69 /// CHECK-DAG: <<GetL2:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
70 /// CHECK-DAG: <<GetL3:l\d+>> ArrayGet [<<CheckL>>,{{i\d+}}]
71 /// CHECK-DAG: <<CheckJ:l\d+>> NullCheck [<<Null>>]
72 /// CHECK-DAG: <<GetJ0:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
73 /// CHECK-DAG: <<GetJ1:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
74 /// CHECK-DAG: <<GetJ2:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
75 /// CHECK-DAG: <<GetJ3:j\d+>> ArrayGet [<<CheckJ>>,{{i\d+}}]
76 public static void bar() {
77 // We create multiple accesses that will lead the bounds check
78 // elimination pass to add a HDeoptimize. Not having the bounds check helped
79 // the load store elimination think it could merge two ArrayGet with different
80 // types.
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010081 String[] array = (String[])getNull();
Nicolas Geoffrayb1d91572016-03-18 16:25:38 +000082 objectField = array[0];
83 objectField = array[1];
84 objectField = array[2];
85 objectField = array[3];
86 long[] longArray = getLongArray();
87 longField = longArray[0];
88 longField = longArray[1];
89 longField = longArray[2];
90 longField = longArray[3];
91 }
92
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +010093 /// CHECK-START: float Main.test1() load_store_elimination (after)
94 /// CHECK-DAG: <<Null:l\d+>> NullConstant
95 /// CHECK-DAG: <<Check1:l\d+>> NullCheck [<<Null>>]
96 /// CHECK-DAG: <<FieldGet1:l\d+>> InstanceFieldGet [<<Check1>>] field_name:Test1.iarr
97 /// CHECK-DAG: <<Check2:l\d+>> NullCheck [<<FieldGet1>>]
98 /// CHECK-DAG: <<ArrayGet1:i\d+>> ArrayGet [<<Check2>>,{{i\d+}}]
99 /// CHECK-DAG: <<ArrayGet2:f\d+>> ArrayGet [<<Check2>>,{{i\d+}}]
100 /// CHECK-DAG: Return [<<ArrayGet2>>]
101 public static float test1() {
102 Test1 test1 = getNullTest1();
Mathieu Chartier6beced42016-11-15 15:51:31 -0800103 Test2 test2 = getNullTest2();
Nicolas Geoffraybb2c93b2016-05-04 14:00:12 +0100104 int[] iarr = test1.iarr;
105 float[] farr = test2.farr;
106 iarr[0] = iarr[1];
107 return farr[0];
108 }
109
Nicolas Geoffray03971632016-03-17 10:44:24 +0000110 public static long longField;
111 public static Object objectField;
112}