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