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