blob: 5ece2e295ed4a36b4b129454a135a6aa963b02b8 [file] [log] [blame]
Aart Bik18b36ab2016-04-13 16:41:35 -07001/*
2 * Copyright (C) 2015 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
17import java.util.Arrays;
18
19//
20// Test on array parameters with or without potential aliasing.
21//
22public class Main {
23
24 //
25 // Cross-over on parameters with potential aliasing on parameters.
26 // The arrays a and b may point to the same memory, which (without
27 // further runtime tests) prevents hoisting the seemingly invariant
28 // array reference.
29 //
30
31 /// CHECK-START: void Main.CrossOverLoop1(int[], int[]) licm (before)
32 /// CHECK-DAG: ArraySet loop:none
33 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
34 /// CHECK-DAG: ArraySet loop:{{B\d+}}
35 //
36 /// CHECK-START: void Main.CrossOverLoop1(int[], int[]) licm (after)
37 /// CHECK-DAG: ArraySet loop:none
38 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
39 /// CHECK-DAG: ArraySet loop:{{B\d+}}
40 private static void CrossOverLoop1(int a[], int b[]) {
41 b[20] = 99;
42 for (int i = 0; i < a.length; i++) {
43 a[i] = b[20] - 7;
44 }
45 }
46
47 /// CHECK-START: void Main.CrossOverLoop2(float[], float[]) licm (before)
48 /// CHECK-DAG: ArraySet loop:none
49 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
50 /// CHECK-DAG: ArraySet loop:{{B\d+}}
51 //
52 /// CHECK-START: void Main.CrossOverLoop2(float[], float[]) licm (after)
53 /// CHECK-DAG: ArraySet loop:none
54 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
55 /// CHECK-DAG: ArraySet loop:{{B\d+}}
56 private static void CrossOverLoop2(float a[], float b[]) {
57 b[20] = 99;
58 for (int i = 0; i < a.length; i++) {
59 a[i] = b[20] - 7;
60 }
61 }
62
63 /// CHECK-START: void Main.CrossOverLoop3(long[], long[]) licm (before)
64 /// CHECK-DAG: ArraySet loop:none
65 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
66 /// CHECK-DAG: ArraySet loop:{{B\d+}}
67 //
68 /// CHECK-START: void Main.CrossOverLoop3(long[], long[]) licm (after)
69 /// CHECK-DAG: ArraySet loop:none
70 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
71 /// CHECK-DAG: ArraySet loop:{{B\d+}}
72 private static void CrossOverLoop3(long a[], long b[]) {
73 b[20] = 99;
74 for (int i = 0; i < a.length; i++) {
75 a[i] = b[20] - 7;
76 }
77 }
78
79 /// CHECK-START: void Main.CrossOverLoop4(double[], double[]) licm (before)
80 /// CHECK-DAG: ArraySet loop:none
81 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
82 /// CHECK-DAG: ArraySet loop:{{B\d+}}
83 //
84 /// CHECK-START: void Main.CrossOverLoop4(double[], double[]) licm (after)
85 /// CHECK-DAG: ArraySet loop:none
86 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
87 /// CHECK-DAG: ArraySet loop:{{B\d+}}
88 private static void CrossOverLoop4(double a[], double b[]) {
89 b[20] = 99;
90 for (int i = 0; i < a.length; i++) {
91 a[i] = b[20] - 7;
92 }
93 }
94
95 //
96 // False cross-over on parameters. Parameters have same width (which used to
97 // cause a false type aliasing in an older version of the compiler), but since
98 // the types are different cannot be aliased. Thus, the invariant array
99 // reference can be hoisted.
100 //
101
102 /// CHECK-START: void Main.FalseCrossOverLoop1(int[], float[]) licm (before)
103 /// CHECK-DAG: ArraySet loop:none
104 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
105 /// CHECK-DAG: ArraySet loop:{{B\d+}}
106 //
107 /// CHECK-START: void Main.FalseCrossOverLoop1(int[], float[]) licm (after)
108 /// CHECK-DAG: ArraySet loop:none
109 /// CHECK-DAG: ArrayGet loop:none
110 /// CHECK-DAG: ArraySet loop:{{B\d+}}
111 private static void FalseCrossOverLoop1(int a[], float b[]) {
112 b[20] = -99;
113 for (int i = 0; i < a.length; i++) {
114 a[i] = (int) b[20] - 7;
115 }
116 }
117
118 /// CHECK-START: void Main.FalseCrossOverLoop2(float[], int[]) licm (before)
119 /// CHECK-DAG: ArraySet loop:none
120 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
121 /// CHECK-DAG: ArraySet loop:{{B\d+}}
122 //
123 /// CHECK-START: void Main.FalseCrossOverLoop2(float[], int[]) licm (after)
124 /// CHECK-DAG: ArraySet loop:none
125 /// CHECK-DAG: ArrayGet loop:none
126 /// CHECK-DAG: ArraySet loop:{{B\d+}}
127 private static void FalseCrossOverLoop2(float a[], int b[]) {
128 b[20] = -99;
129 for (int i = 0; i < a.length; i++) {
130 a[i] = b[20] - 7;
131 }
132 }
133
134 /// CHECK-START: void Main.FalseCrossOverLoop3(long[], double[]) licm (before)
135 /// CHECK-DAG: ArraySet loop:none
136 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
137 /// CHECK-DAG: ArraySet loop:{{B\d+}}
138 //
139 /// CHECK-START: void Main.FalseCrossOverLoop3(long[], double[]) licm (after)
140 /// CHECK-DAG: ArraySet loop:none
141 /// CHECK-DAG: ArrayGet loop:none
142 /// CHECK-DAG: ArraySet loop:{{B\d+}}
143 private static void FalseCrossOverLoop3(long a[], double b[]) {
144 b[20] = -99;
145 for (int i = 0; i < a.length; i++) {
146 a[i] = (long) b[20] - 7;
147 }
148 }
149
150 /// CHECK-START: void Main.FalseCrossOverLoop4(double[], long[]) licm (before)
151 /// CHECK-DAG: ArraySet loop:none
152 /// CHECK-DAG: ArrayGet loop:{{B\d+}}
153 /// CHECK-DAG: ArraySet loop:{{B\d+}}
154 //
155 /// CHECK-START: void Main.FalseCrossOverLoop4(double[], long[]) licm (after)
156 /// CHECK-DAG: ArraySet loop:none
157 /// CHECK-DAG: ArrayGet loop:none
158 /// CHECK-DAG: ArraySet loop:{{B\d+}}
159 private static void FalseCrossOverLoop4(double a[], long b[]) {
160 b[20] = -99;
161 for (int i = 0; i < a.length; i++) {
162 a[i] = b[20] - 7;
163 }
164 }
165
166 //
167 // Main driver and testers.
168 //
169
170 public static void main(String[] args) {
171 int[] aI = new int[100];
172 float[] aF = new float[100];
173 long[] aJ = new long[100];
174 double[] aD = new double[100];
175
176 // Type I.
177 CrossOverLoop1(aI, aI);
178 for (int i = 0; i < aI.length; i++) {
179 expectEquals(i <= 20 ? 92 : 85, aI[i]);
180 }
181 // Type F.
182 CrossOverLoop2(aF, aF);
183 for (int i = 0; i < aF.length; i++) {
184 expectEquals(i <= 20 ? 92 : 85, aF[i]);
185 }
186 // Type J.
187 CrossOverLoop3(aJ, aJ);
188 for (int i = 0; i < aJ.length; i++) {
189 expectEquals(i <= 20 ? 92 : 85, aJ[i]);
190 }
191 // Type D.
192 CrossOverLoop4(aD, aD);
193 for (int i = 0; i < aD.length; i++) {
194 expectEquals(i <= 20 ? 92 : 85, aD[i]);
195 }
196
197 // Type I vs F.
198 FalseCrossOverLoop1(aI, aF);
199 for (int i = 0; i < aI.length; i++) {
200 expectEquals(-106, aI[i]);
201 }
202 // Type F vs I.
203 FalseCrossOverLoop2(aF, aI);
204 for (int i = 0; i < aF.length; i++) {
205 expectEquals(-106, aF[i]);
206 }
207 // Type J vs D.
208 FalseCrossOverLoop3(aJ, aD);
209 for (int i = 0; i < aJ.length; i++) {
210 expectEquals(-106, aJ[i]);
211 }
212 // Type D vs J.
213 FalseCrossOverLoop4(aD, aJ);
214 for (int i = 0; i < aD.length; i++) {
215 expectEquals(-106, aD[i]);
216 }
217
218 // Real-world example where incorrect type assignment could introduce a bug.
219 // The library sorting algorithm is heavy on array reads and writes, and
220 // assigning the wrong J/D type to one of these would introduce errors.
221 for (int i = 0; i < aD.length; i++) {
222 aD[i] = aD.length - i - 1;
223 }
224 Arrays.sort(aD);
225 for (int i = 0; i < aD.length; i++) {
226 expectEquals((double) i, aD[i]);
227 }
228
229 System.out.println("passed");
230 }
231
232 private static void expectEquals(int expected, int result) {
233 if (expected != result) {
234 throw new Error("Expected: " + expected + ", found: " + result);
235 }
236 }
237
238 private static void expectEquals(long expected, long result) {
239 if (expected != result) {
240 throw new Error("Expected: " + expected + ", found: " + result);
241 }
242 }
243
244 private static void expectEquals(float expected, float result) {
245 if (expected != result) {
246 throw new Error("Expected: " + expected + ", found: " + result);
247 }
248 }
249
250 private static void expectEquals(double expected, double result) {
251 if (expected != result) {
252 throw new Error("Expected: " + expected + ", found: " + result);
253 }
254 }
255}