1 /* 2 * Copyright (C) 2017 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 17 /** 18 * Tests for ABS vectorization. 19 */ 20 public class Main { 21 22 private static final int SPQUIET = 1 << 22; 23 private static final long DPQUIET = 1L << 51; 24 25 /// CHECK-START: void Main.doitInt(int[]) loop_optimization (before) 26 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 27 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 28 /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop>> outer_loop:none 29 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 30 // 31 /// CHECK-START-ARM64: void Main.doitInt(int[]) loop_optimization (after) 32 /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none 33 /// CHECK-DAG: VecLoad loop:<<Loop1>> outer_loop:none 34 /// CHECK-DAG: VecAbs loop:<<Loop1>> outer_loop:none 35 /// CHECK-DAG: VecStore loop:<<Loop1>> outer_loop:none 36 /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:none 37 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:none 38 /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>> outer_loop:none 39 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:none 40 // 41 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" doitInt(int[] x)42 private static void doitInt(int[] x) { 43 for (int i = 0; i < x.length; i++) { 44 x[i] = Math.abs(x[i]); 45 } 46 } 47 48 /// CHECK-START: void Main.doitLong(long[]) loop_optimization (before) 49 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 50 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 51 /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsLong loop:<<Loop>> outer_loop:none 52 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 53 // 54 /// CHECK-START-ARM64: void Main.doitLong(long[]) loop_optimization (after) 55 // 56 // TODO: Not supported yet. doitLong(long[] x)57 private static void doitLong(long[] x) { 58 for (int i = 0; i < x.length; i++) { 59 x[i] = Math.abs(x[i]); 60 } 61 } 62 63 /// CHECK-START: void Main.doitFloat(float[]) loop_optimization (before) 64 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 65 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 66 /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsFloat loop:<<Loop>> outer_loop:none 67 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 68 // 69 /// CHECK-START-ARM64: void Main.doitFloat(float[]) loop_optimization (after) 70 /// CHECK-DAG: Phi loop:<<Loop1:B\d+>> outer_loop:none 71 /// CHECK-DAG: VecLoad loop:<<Loop1>> outer_loop:none 72 /// CHECK-DAG: VecAbs loop:<<Loop1>> outer_loop:none 73 /// CHECK-DAG: VecStore loop:<<Loop1>> outer_loop:none 74 /// CHECK-DAG: Phi loop:<<Loop2:B\d+>> outer_loop:none 75 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:none 76 /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsFloat loop:<<Loop2>> outer_loop:none 77 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:none 78 // 79 /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>" doitFloat(float[] x)80 private static void doitFloat(float[] x) { 81 for (int i = 0; i < x.length; i++) { 82 x[i] = Math.abs(x[i]); 83 } 84 } 85 86 /// CHECK-START: void Main.doitDouble(double[]) loop_optimization (before) 87 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> outer_loop:none 88 /// CHECK-DAG: ArrayGet loop:<<Loop>> outer_loop:none 89 /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsDouble loop:<<Loop>> outer_loop:none 90 /// CHECK-DAG: ArraySet loop:<<Loop>> outer_loop:none 91 // 92 /// CHECK-START-ARM64: void Main.doitDouble(double[]) loop_optimization (after) 93 // 94 // TODO: Not supported yet. doitDouble(double[] x)95 private static void doitDouble(double[] x) { 96 for (int i = 0; i < x.length; i++) { 97 x[i] = Math.abs(x[i]); 98 } 99 } 100 main(String[] args)101 public static void main(String[] args) { 102 // Set up minint32, maxint32 and some others. 103 int[] xi = new int[8]; 104 xi[0] = 0x80000000; 105 xi[1] = 0x7fffffff; 106 xi[2] = 0x80000001; 107 xi[3] = -13; 108 xi[4] = -1; 109 xi[5] = 0; 110 xi[6] = 1; 111 xi[7] = 999; 112 doitInt(xi); 113 expectEquals32(0x80000000, xi[0]); 114 expectEquals32(0x7fffffff, xi[1]); 115 expectEquals32(0x7fffffff, xi[2]); 116 expectEquals32(13, xi[3]); 117 expectEquals32(1, xi[4]); 118 expectEquals32(0, xi[5]); 119 expectEquals32(1, xi[6]); 120 expectEquals32(999, xi[7]); 121 122 // Set up minint64, maxint64 and some others. 123 long[] xl = new long[8]; 124 xl[0] = 0x8000000000000000L; 125 xl[1] = 0x7fffffffffffffffL; 126 xl[2] = 0x8000000000000001L; 127 xl[3] = -13; 128 xl[4] = -1; 129 xl[5] = 0; 130 xl[6] = 1; 131 xl[7] = 999; 132 doitLong(xl); 133 expectEquals64(0x8000000000000000L, xl[0]); 134 expectEquals64(0x7fffffffffffffffL, xl[1]); 135 expectEquals64(0x7fffffffffffffffL, xl[2]); 136 expectEquals64(13, xl[3]); 137 expectEquals64(1, xl[4]); 138 expectEquals64(0, xl[5]); 139 expectEquals64(1, xl[6]); 140 expectEquals64(999, xl[7]); 141 142 // Set up float NaN and some others. 143 float[] xf = new float[16]; 144 xf[0] = Float.intBitsToFloat(0x7f800001); 145 xf[1] = Float.intBitsToFloat(0x7fa00000); 146 xf[2] = Float.intBitsToFloat(0x7fc00000); 147 xf[3] = Float.intBitsToFloat(0x7fffffff); 148 xf[4] = Float.intBitsToFloat(0xff800001); 149 xf[5] = Float.intBitsToFloat(0xffa00000); 150 xf[6] = Float.intBitsToFloat(0xffc00000); 151 xf[7] = Float.intBitsToFloat(0xffffffff); 152 xf[8] = Float.NEGATIVE_INFINITY; 153 xf[9] = -99.2f; 154 xf[10] = -1.0f; 155 xf[11] = -0.0f; 156 xf[12] = +0.0f; 157 xf[13] = +1.0f; 158 xf[14] = +99.2f; 159 xf[15] = Float.POSITIVE_INFINITY; 160 doitFloat(xf); 161 expectEqualsNaN32(0x7f800001, Float.floatToRawIntBits(xf[0])); 162 expectEqualsNaN32(0x7fa00000, Float.floatToRawIntBits(xf[1])); 163 expectEqualsNaN32(0x7fc00000, Float.floatToRawIntBits(xf[2])); 164 expectEqualsNaN32(0x7fffffff, Float.floatToRawIntBits(xf[3])); 165 expectEqualsNaN32(0x7f800001, Float.floatToRawIntBits(xf[4])); 166 expectEqualsNaN32(0x7fa00000, Float.floatToRawIntBits(xf[5])); 167 expectEqualsNaN32(0x7fc00000, Float.floatToRawIntBits(xf[6])); 168 expectEqualsNaN32(0x7fffffff, Float.floatToRawIntBits(xf[7])); 169 expectEquals32( 170 Float.floatToRawIntBits(Float.POSITIVE_INFINITY), 171 Float.floatToRawIntBits(xf[8])); 172 expectEquals32( 173 Float.floatToRawIntBits(99.2f), 174 Float.floatToRawIntBits(xf[9])); 175 expectEquals32( 176 Float.floatToRawIntBits(1.0f), 177 Float.floatToRawIntBits(xf[10])); 178 expectEquals32(0, Float.floatToRawIntBits(xf[11])); 179 expectEquals32(0, Float.floatToRawIntBits(xf[12])); 180 expectEquals32( 181 Float.floatToRawIntBits(1.0f), 182 Float.floatToRawIntBits(xf[13])); 183 expectEquals32( 184 Float.floatToRawIntBits(99.2f), 185 Float.floatToRawIntBits(xf[14])); 186 expectEquals32( 187 Float.floatToRawIntBits(Float.POSITIVE_INFINITY), 188 Float.floatToRawIntBits(xf[15])); 189 190 // Set up double NaN and some others. 191 double[] xd = new double[16]; 192 xd[0] = Double.longBitsToDouble(0x7ff0000000000001L); 193 xd[1] = Double.longBitsToDouble(0x7ff4000000000000L); 194 xd[2] = Double.longBitsToDouble(0x7ff8000000000000L); 195 xd[3] = Double.longBitsToDouble(0x7fffffffffffffffL); 196 xd[4] = Double.longBitsToDouble(0xfff0000000000001L); 197 xd[5] = Double.longBitsToDouble(0xfff4000000000000L); 198 xd[6] = Double.longBitsToDouble(0xfff8000000000000L); 199 xd[7] = Double.longBitsToDouble(0xffffffffffffffffL); 200 xd[8] = Double.NEGATIVE_INFINITY; 201 xd[9] = -99.2f; 202 xd[10] = -1.0f; 203 xd[11] = -0.0f; 204 xd[12] = +0.0f; 205 xd[13] = +1.0f; 206 xd[14] = +99.2f; 207 xd[15] = Double.POSITIVE_INFINITY; 208 doitDouble(xd); 209 expectEqualsNaN64(0x7ff0000000000001L, Double.doubleToRawLongBits(xd[0])); 210 expectEqualsNaN64(0x7ff4000000000000L, Double.doubleToRawLongBits(xd[1])); 211 expectEqualsNaN64(0x7ff8000000000000L, Double.doubleToRawLongBits(xd[2])); 212 expectEqualsNaN64(0x7fffffffffffffffL, Double.doubleToRawLongBits(xd[3])); 213 expectEqualsNaN64(0x7ff0000000000001L, Double.doubleToRawLongBits(xd[4])); 214 expectEqualsNaN64(0x7ff4000000000000L, Double.doubleToRawLongBits(xd[5])); 215 expectEqualsNaN64(0x7ff8000000000000L, Double.doubleToRawLongBits(xd[6])); 216 expectEqualsNaN64(0x7fffffffffffffffL, Double.doubleToRawLongBits(xd[7])); 217 expectEquals64( 218 Double.doubleToRawLongBits(Double.POSITIVE_INFINITY), 219 Double.doubleToRawLongBits(xd[8])); 220 expectEquals64( 221 Double.doubleToRawLongBits(99.2f), 222 Double.doubleToRawLongBits(xd[9])); 223 expectEquals64( 224 Double.doubleToRawLongBits(1.0f), 225 Double.doubleToRawLongBits(xd[10])); 226 expectEquals64(0, Double.doubleToRawLongBits(xd[11])); 227 expectEquals64(0, Double.doubleToRawLongBits(xd[12])); 228 expectEquals64( 229 Double.doubleToRawLongBits(1.0f), 230 Double.doubleToRawLongBits(xd[13])); 231 expectEquals64( 232 Double.doubleToRawLongBits(99.2f), 233 Double.doubleToRawLongBits(xd[14])); 234 expectEquals64( 235 Double.doubleToRawLongBits(Double.POSITIVE_INFINITY), 236 Double.doubleToRawLongBits(xd[15])); 237 238 System.out.println("passed"); 239 } 240 expectEquals32(int expected, int result)241 private static void expectEquals32(int expected, int result) { 242 if (expected != result) { 243 throw new Error("Expected: " + expected + ", found: " + result); 244 } 245 } 246 expectEquals64(long expected, long result)247 private static void expectEquals64(long expected, long result) { 248 if (expected != result) { 249 throw new Error("Expected: " + expected + ", found: " + result); 250 } 251 } 252 253 // We allow that an expected NaN result has become quiet. expectEqualsNaN32(int expected, int result)254 private static void expectEqualsNaN32(int expected, int result) { 255 if (expected != result && (expected | SPQUIET) != result) { 256 throw new Error("Expected: 0x" + Integer.toHexString(expected) 257 + ", found: 0x" + Integer.toHexString(result)); 258 } 259 } 260 261 // We allow that an expected NaN result has become quiet. expectEqualsNaN64(long expected, long result)262 private static void expectEqualsNaN64(long expected, long result) { 263 if (expected != result && (expected | DPQUIET) != result) { 264 throw new Error("Expected: 0x" + Long.toHexString(expected) 265 + ", found: 0x" + Long.toHexString(result)); 266 } 267 } 268 } 269