1 /* 2 * Copyright (C) 2018 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 package other; 18 19 /** 20 * Tests for dot product idiom vectorization: char and short case. 21 */ 22 public class TestCharShort { 23 24 public static final int ARRAY_SIZE = 1024; 25 26 /// CHECK-START: int other.TestCharShort.testDotProdSimple(short[], short[]) loop_optimization (before) 27 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 28 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 29 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 30 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 31 /// CHECK-DAG: <<Get1:s\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 32 /// CHECK-DAG: <<Get2:s\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 33 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none 34 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 35 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 36 37 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdSimple(short[], short[]) loop_optimization (after) 38 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 39 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 40 /// CHECK-IF: hasIsaFeature("sve") 41 // 42 // 16-bit DotProd is not supported for SVE. 43 /// CHECK-NOT: VecDotProd 44 // 45 /// CHECK-ELSE: 46 // 47 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 loop:none 48 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 49 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 50 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 51 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 52 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 53 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Int16 loop:<<Loop>> outer_loop:none 54 /// CHECK-DAG: Add [<<Phi1>>,<<Const8>>] loop:<<Loop>> outer_loop:none 55 // 56 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 57 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none 58 // 59 /// CHECK-FI: testDotProdSimple(short[] a, short[] b)60 public static final int testDotProdSimple(short[] a, short[] b) { 61 int s = 1; 62 for (int i = 0; i < b.length; i++) { 63 int temp = a[i] * b[i]; 64 s += temp; 65 } 66 return s - 1; 67 } 68 69 /// CHECK-START: int other.TestCharShort.testDotProdComplex(short[], short[]) loop_optimization (before) 70 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 71 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 72 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 73 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 74 /// CHECK-DAG: <<Get1:s\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 75 /// CHECK-DAG: <<AddC1:i\d+>> Add [<<Get1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 76 /// CHECK-DAG: <<TypeC1:s\d+>> TypeConversion [<<AddC1>>] loop:<<Loop>> outer_loop:none 77 /// CHECK-DAG: <<Get2:s\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 78 /// CHECK-DAG: <<AddC2:i\d+>> Add [<<Get2>>,<<Const1>>] loop:<<Loop>> outer_loop:none 79 /// CHECK-DAG: <<TypeC2:s\d+>> TypeConversion [<<AddC2>>] loop:<<Loop>> outer_loop:none 80 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<TypeC1>>,<<TypeC2>>] loop:<<Loop>> outer_loop:none 81 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 82 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 83 84 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdComplex(short[], short[]) loop_optimization (after) 85 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 86 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 87 /// CHECK-IF: hasIsaFeature("sve") 88 // 89 // 16-bit DotProd is not supported for SVE. 90 /// CHECK-NOT: VecDotProd 91 // 92 /// CHECK-ELSE: 93 // 94 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 loop:none 95 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const1>>] loop:none 96 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 97 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 98 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 99 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 100 /// CHECK-DAG: <<VAdd1:d\d+>> VecAdd [<<Load1>>,<<Repl>>] loop:<<Loop>> outer_loop:none 101 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 102 /// CHECK-DAG: <<VAdd2:d\d+>> VecAdd [<<Load2>>,<<Repl>>] loop:<<Loop>> outer_loop:none 103 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<VAdd1>>,<<VAdd2>>] type:Int16 loop:<<Loop>> outer_loop:none 104 /// CHECK-DAG: Add [<<Phi1>>,<<Const8>>] loop:<<Loop>> outer_loop:none 105 // 106 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 107 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none 108 // 109 /// CHECK-FI: testDotProdComplex(short[] a, short[] b)110 public static final int testDotProdComplex(short[] a, short[] b) { 111 int s = 1; 112 for (int i = 0; i < b.length; i++) { 113 int temp = ((short)(a[i] + 1)) * ((short)(b[i] + 1)); 114 s += temp; 115 } 116 return s - 1; 117 } 118 119 /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsigned(char[], char[]) loop_optimization (before) 120 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 121 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 122 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 123 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 124 /// CHECK-DAG: <<Get1:c\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 125 /// CHECK-DAG: <<Get2:c\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 126 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none 127 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 128 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 129 130 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdSimpleUnsigned(char[], char[]) loop_optimization (after) 131 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 132 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 133 /// CHECK-IF: hasIsaFeature("sve") 134 // 135 // 16-bit DotProd is not supported for SVE. 136 /// CHECK-NOT: VecDotProd 137 // 138 /// CHECK-ELSE: 139 // 140 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 loop:none 141 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 142 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 143 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 144 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 145 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 146 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Uint16 loop:<<Loop>> outer_loop:none 147 /// CHECK-DAG: Add [<<Phi1>>,<<Const8>>] loop:<<Loop>> outer_loop:none 148 // 149 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 150 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none 151 // 152 /// CHECK-FI: testDotProdSimpleUnsigned(char[] a, char[] b)153 public static final int testDotProdSimpleUnsigned(char[] a, char[] b) { 154 int s = 1; 155 for (int i = 0; i < b.length; i++) { 156 int temp = a[i] * b[i]; 157 s += temp; 158 } 159 return s - 1; 160 } 161 162 /// CHECK-START: int other.TestCharShort.testDotProdComplexUnsigned(char[], char[]) loop_optimization (before) 163 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 164 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 165 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 166 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 167 /// CHECK-DAG: <<Get1:c\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 168 /// CHECK-DAG: <<AddC:i\d+>> Add [<<Get1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 169 /// CHECK-DAG: <<TypeC1:c\d+>> TypeConversion [<<AddC>>] loop:<<Loop>> outer_loop:none 170 /// CHECK-DAG: <<Get2:c\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 171 /// CHECK-DAG: <<AddGets:i\d+>> Add [<<Get2>>,<<Const1>>] loop:<<Loop>> outer_loop:none 172 /// CHECK-DAG: <<TypeC2:c\d+>> TypeConversion [<<AddGets>>] loop:<<Loop>> outer_loop:none 173 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<TypeC1>>,<<TypeC2>>] loop:<<Loop>> outer_loop:none 174 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 175 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 176 177 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdComplexUnsigned(char[], char[]) loop_optimization (after) 178 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 179 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 180 /// CHECK-IF: hasIsaFeature("sve") 181 // 182 // 16-bit DotProd is not supported for SVE. 183 /// CHECK-NOT: VecDotProd 184 // 185 /// CHECK-ELSE: 186 // 187 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 loop:none 188 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const1>>] loop:none 189 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 190 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 191 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 192 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 193 /// CHECK-DAG: <<VAdd1:d\d+>> VecAdd [<<Load1>>,<<Repl>>] loop:<<Loop>> outer_loop:none 194 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 195 /// CHECK-DAG: <<VAdd2:d\d+>> VecAdd [<<Load2>>,<<Repl>>] loop:<<Loop>> outer_loop:none 196 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<VAdd1>>,<<VAdd2>>] type:Uint16 loop:<<Loop>> outer_loop:none 197 /// CHECK-DAG: Add [<<Phi1>>,<<Const8>>] loop:<<Loop>> outer_loop:none 198 // 199 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 200 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none 201 // 202 /// CHECK-FI: testDotProdComplexUnsigned(char[] a, char[] b)203 public static final int testDotProdComplexUnsigned(char[] a, char[] b) { 204 int s = 1; 205 for (int i = 0; i < b.length; i++) { 206 int temp = ((char)(a[i] + 1)) * ((char)(b[i] + 1)); 207 s += temp; 208 } 209 return s - 1; 210 } 211 212 /// CHECK-START: int other.TestCharShort.testDotProdComplexUnsignedCastedToSigned(char[], char[]) loop_optimization (before) 213 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 214 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 215 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 216 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 217 /// CHECK-DAG: <<Get1:c\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 218 /// CHECK-DAG: <<AddC:i\d+>> Add [<<Get1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 219 /// CHECK-DAG: <<TypeC1:s\d+>> TypeConversion [<<AddC>>] loop:<<Loop>> outer_loop:none 220 /// CHECK-DAG: <<Get2:c\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 221 /// CHECK-DAG: <<AddGets:i\d+>> Add [<<Get2>>,<<Const1>>] loop:<<Loop>> outer_loop:none 222 /// CHECK-DAG: <<TypeC2:s\d+>> TypeConversion [<<AddGets>>] loop:<<Loop>> outer_loop:none 223 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<TypeC1>>,<<TypeC2>>] loop:<<Loop>> outer_loop:none 224 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 225 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 226 227 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdComplexUnsignedCastedToSigned(char[], char[]) loop_optimization (after) 228 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 229 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 230 /// CHECK-IF: hasIsaFeature("sve") 231 // 232 // 16-bit DotProd is not supported for SVE. 233 /// CHECK-NOT: VecDotProd 234 // 235 /// CHECK-ELSE: 236 // 237 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 loop:none 238 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const1>>] loop:none 239 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 240 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 241 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 242 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 243 /// CHECK-DAG: <<VAdd1:d\d+>> VecAdd [<<Load1>>,<<Repl>>] loop:<<Loop>> outer_loop:none 244 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 245 /// CHECK-DAG: <<VAdd2:d\d+>> VecAdd [<<Load2>>,<<Repl>>] loop:<<Loop>> outer_loop:none 246 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<VAdd1>>,<<VAdd2>>] type:Int16 loop:<<Loop>> outer_loop:none 247 /// CHECK-DAG: Add [<<Phi1>>,<<Const8>>] loop:<<Loop>> outer_loop:none 248 // 249 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 250 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none 251 // 252 /// CHECK-FI: testDotProdComplexUnsignedCastedToSigned(char[] a, char[] b)253 public static final int testDotProdComplexUnsignedCastedToSigned(char[] a, char[] b) { 254 int s = 1; 255 for (int i = 0; i < b.length; i++) { 256 int temp = ((short)(a[i] + 1)) * ((short)(b[i] + 1)); 257 s += temp; 258 } 259 return s - 1; 260 } 261 262 /// CHECK-START: int other.TestCharShort.testDotProdComplexSignedCastedToUnsigned(short[], short[]) loop_optimization (before) 263 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 264 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 265 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 266 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 267 /// CHECK-DAG: <<Get1:s\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 268 /// CHECK-DAG: <<AddC:i\d+>> Add [<<Get1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 269 /// CHECK-DAG: <<TypeC1:c\d+>> TypeConversion [<<AddC>>] loop:<<Loop>> outer_loop:none 270 /// CHECK-DAG: <<Get2:s\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 271 /// CHECK-DAG: <<AddGets:i\d+>> Add [<<Get2>>,<<Const1>>] loop:<<Loop>> outer_loop:none 272 /// CHECK-DAG: <<TypeC2:c\d+>> TypeConversion [<<AddGets>>] loop:<<Loop>> outer_loop:none 273 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<TypeC1>>,<<TypeC2>>] loop:<<Loop>> outer_loop:none 274 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 275 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 276 277 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdComplexSignedCastedToUnsigned(short[], short[]) loop_optimization (after) 278 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 279 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 280 /// CHECK-IF: hasIsaFeature("sve") 281 // 282 // 16-bit DotProd is not supported for SVE. 283 /// CHECK-NOT: VecDotProd 284 // 285 /// CHECK-ELSE: 286 // 287 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 loop:none 288 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const1>>] loop:none 289 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 290 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 291 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 292 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 293 /// CHECK-DAG: <<VAdd1:d\d+>> VecAdd [<<Load1>>,<<Repl>>] loop:<<Loop>> outer_loop:none 294 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 295 /// CHECK-DAG: <<VAdd2:d\d+>> VecAdd [<<Load2>>,<<Repl>>] loop:<<Loop>> outer_loop:none 296 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<VAdd1>>,<<VAdd2>>] type:Uint16 loop:<<Loop>> outer_loop:none 297 /// CHECK-DAG: Add [<<Phi1>>,<<Const8>>] loop:<<Loop>> outer_loop:none 298 // 299 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 300 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none 301 // 302 /// CHECK-FI: testDotProdComplexSignedCastedToUnsigned(short[] a, short[] b)303 public static final int testDotProdComplexSignedCastedToUnsigned(short[] a, short[] b) { 304 int s = 1; 305 for (int i = 0; i < b.length; i++) { 306 int temp = ((char)(a[i] + 1)) * ((char)(b[i] + 1)); 307 s += temp; 308 } 309 return s - 1; 310 } 311 312 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdSignedToInt(short[], short[]) loop_optimization (after) 313 /// CHECK-IF: hasIsaFeature("sve") 314 // 315 // 16-bit DotProd is not supported for SVE. 316 /// CHECK-NOT: VecDotProd 317 // 318 /// CHECK-ELSE: 319 // 320 /// CHECK-DAG: VecDotProd type:Int16 321 // 322 /// CHECK-FI: testDotProdSignedToInt(short[] a, short[] b)323 public static final int testDotProdSignedToInt(short[] a, short[] b) { 324 int s = 1; 325 for (int i = 0; i < b.length; i++) { 326 int temp = ((int)(a[i])) * ((int)(b[i])); 327 s += temp; 328 } 329 return s - 1; 330 } 331 332 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdParamSigned(int, short[]) loop_optimization (after) 333 /// CHECK-IF: hasIsaFeature("sve") 334 // 335 // 16-bit DotProd is not supported for SVE. 336 /// CHECK-NOT: VecDotProd 337 // 338 /// CHECK-ELSE: 339 // 340 /// CHECK-DAG: VecDotProd type:Int16 341 // 342 /// CHECK-FI: testDotProdParamSigned(int x, short[] b)343 public static final int testDotProdParamSigned(int x, short[] b) { 344 int s = 1; 345 for (int i = 0; i < b.length; i++) { 346 int temp = (short)(x) * b[i]; 347 s += temp; 348 } 349 return s - 1; 350 } 351 352 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdParamUnsigned(int, char[]) loop_optimization (after) 353 /// CHECK-IF: hasIsaFeature("sve") 354 // 355 // 16-bit DotProd is not supported for SVE. 356 /// CHECK-NOT: VecDotProd 357 // 358 /// CHECK-ELSE: 359 // 360 /// CHECK-DAG: VecDotProd type:Uint16 361 // 362 /// CHECK-FI: testDotProdParamUnsigned(int x, char[] b)363 public static final int testDotProdParamUnsigned(int x, char[] b) { 364 int s = 1; 365 for (int i = 0; i < b.length; i++) { 366 int temp = (char)(x) * b[i]; 367 s += temp; 368 } 369 return s - 1; 370 } 371 372 /// CHECK-START: int other.TestCharShort.testDotProdIntParam(int, short[]) loop_optimization (after) 373 /// CHECK-NOT: VecDotProd testDotProdIntParam(int x, short[] b)374 public static final int testDotProdIntParam(int x, short[] b) { 375 int s = 1; 376 for (int i = 0; i < b.length; i++) { 377 int temp = b[i] * (x); 378 s += temp; 379 } 380 return s - 1; 381 } 382 383 /// CHECK-START-{ARM64}: int other.TestCharShort.testDotProdSignedToChar(short[], short[]) loop_optimization (after) 384 /// CHECK-IF: hasIsaFeature("sve") 385 // 386 // 16-bit DotProd is not supported for SVE. 387 /// CHECK-NOT: VecDotProd 388 // 389 /// CHECK-ELSE: 390 // 391 /// CHECK-DAG: VecDotProd type:Uint16 392 // 393 /// CHECK-FI: testDotProdSignedToChar(short[] a, short[] b)394 public static final int testDotProdSignedToChar(short[] a, short[] b) { 395 int s = 1; 396 for (int i = 0; i < b.length; i++) { 397 int temp = ((char)(a[i])) * ((char)(b[i])); 398 s += temp; 399 } 400 return s - 1; 401 } 402 403 // Cases when result of Mul is type-converted are not supported. 404 405 /// CHECK-START: int other.TestCharShort.testDotProdSimpleMulCastedToSigned(short[], short[]) loop_optimization (after) 406 /// CHECK-NOT: VecDotProd type:Uint16 testDotProdSimpleMulCastedToSigned(short[] a, short[] b)407 public static final int testDotProdSimpleMulCastedToSigned(short[] a, short[] b) { 408 int s = 1; 409 for (int i = 0; i < b.length; i++) { 410 short temp = (short)(a[i] * b[i]); 411 s += temp; 412 } 413 return s - 1; 414 } 415 416 417 /// CHECK-START: int other.TestCharShort.testDotProdSimpleMulCastedToUnsigned(short[], short[]) loop_optimization (after) 418 /// CHECK-NOT: VecDotProd testDotProdSimpleMulCastedToUnsigned(short[] a, short[] b)419 public static final int testDotProdSimpleMulCastedToUnsigned(short[] a, short[] b) { 420 int s = 1; 421 for (int i = 0; i < b.length; i++) { 422 char temp = (char)(a[i] * b[i]); 423 s += temp; 424 } 425 return s - 1; 426 } 427 428 /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedMulCastedToSigned(char[], char[]) loop_optimization (after) 429 /// CHECK-NOT: VecDotProd testDotProdSimpleUnsignedMulCastedToSigned(char[] a, char[] b)430 public static final int testDotProdSimpleUnsignedMulCastedToSigned(char[] a, char[] b) { 431 int s = 1; 432 for (int i = 0; i < b.length; i++) { 433 short temp = (short)(a[i] * b[i]); 434 s += temp; 435 } 436 return s - 1; 437 } 438 439 /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedMulCastedToUnsigned(char[], char[]) loop_optimization (after) 440 /// CHECK-NOT: VecDotProd testDotProdSimpleUnsignedMulCastedToUnsigned(char[] a, char[] b)441 public static final int testDotProdSimpleUnsignedMulCastedToUnsigned(char[] a, char[] b) { 442 int s = 1; 443 for (int i = 0; i < b.length; i++) { 444 char temp = (char)(a[i] * b[i]); 445 s += temp; 446 } 447 return s - 1; 448 } 449 450 /// CHECK-START: int other.TestCharShort.testDotProdSimpleCastedToShort(short[], short[]) loop_optimization (after) 451 /// CHECK-NOT: VecDotProd testDotProdSimpleCastedToShort(short[] a, short[] b)452 public static final int testDotProdSimpleCastedToShort(short[] a, short[] b) { 453 int s = 1; 454 for (int i = 0; i < b.length; i++) { 455 short temp = (short)(a[i] * b[i]); 456 s += temp; 457 } 458 return s - 1; 459 } 460 461 /// CHECK-START: int other.TestCharShort.testDotProdSimpleCastedToChar(short[], short[]) loop_optimization (after) 462 /// CHECK-NOT: VecDotProd testDotProdSimpleCastedToChar(short[] a, short[] b)463 public static final int testDotProdSimpleCastedToChar(short[] a, short[] b) { 464 int s = 1; 465 for (int i = 0; i < b.length; i++) { 466 char temp = (char)(a[i] * b[i]); 467 s += temp; 468 } 469 return s - 1; 470 } 471 472 /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedCastedToShort(char[], char[]) loop_optimization (after) 473 /// CHECK-NOT: VecDotProd testDotProdSimpleUnsignedCastedToShort(char[] a, char[] b)474 public static final int testDotProdSimpleUnsignedCastedToShort(char[] a, char[] b) { 475 int s = 1; 476 for (int i = 0; i < b.length; i++) { 477 short temp = (short)(a[i] * b[i]); 478 s += temp; 479 } 480 return s - 1; 481 } 482 483 /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedCastedToChar(char[], char[]) loop_optimization (after) 484 /// CHECK-NOT: VecDotProd testDotProdSimpleUnsignedCastedToChar(char[] a, char[] b)485 public static final int testDotProdSimpleUnsignedCastedToChar(char[] a, char[] b) { 486 int s = 1; 487 for (int i = 0; i < b.length; i++) { 488 char temp = (char)(a[i] * b[i]); 489 s += temp; 490 } 491 return s - 1; 492 } 493 494 /// CHECK-START: int other.TestCharShort.testDotProdSimpleUnsignedCastedToLong(char[], char[]) loop_optimization (after) 495 /// CHECK-NOT: VecDotProd testDotProdSimpleUnsignedCastedToLong(char[] a, char[] b)496 public static final int testDotProdSimpleUnsignedCastedToLong(char[] a, char[] b) { 497 int s = 1; 498 for (int i = 0; i < b.length; i++) { 499 long temp = (long)(a[i] * b[i]); 500 s += temp; 501 } 502 return s - 1; 503 } 504 505 // Narrowing conversions. 506 507 /// CHECK-START: int other.TestCharShort.testDotProdSignedNarrowerSigned(short[], short[]) loop_optimization (after) 508 /// CHECK-NOT: VecDotProd testDotProdSignedNarrowerSigned(short[] a, short[] b)509 public static final int testDotProdSignedNarrowerSigned(short[] a, short[] b) { 510 int s = 1; 511 for (int i = 0; i < b.length; i++) { 512 int temp = ((byte)(a[i])) * ((byte)(b[i])); 513 s += temp; 514 } 515 return s - 1; 516 } 517 518 /// CHECK-START: int other.TestCharShort.testDotProdSignedNarrowerUnsigned(short[], short[]) loop_optimization (after) 519 /// CHECK-NOT: VecDotProd testDotProdSignedNarrowerUnsigned(short[] a, short[] b)520 public static final int testDotProdSignedNarrowerUnsigned(short[] a, short[] b) { 521 int s = 1; 522 for (int i = 0; i < b.length; i++) { 523 int temp = (a[i] & 0xff) * (b[i] & 0xff); 524 s += temp; 525 } 526 return s - 1; 527 } 528 529 /// CHECK-START: int other.TestCharShort.testDotProdUnsignedNarrowerSigned(char[], char[]) loop_optimization (after) 530 /// CHECK-NOT: VecDotProd testDotProdUnsignedNarrowerSigned(char[] a, char[] b)531 public static final int testDotProdUnsignedNarrowerSigned(char[] a, char[] b) { 532 int s = 1; 533 for (int i = 0; i < b.length; i++) { 534 int temp = ((byte)(a[i])) * ((byte)(b[i])); 535 s += temp; 536 } 537 return s - 1; 538 } 539 540 /// CHECK-START: int other.TestCharShort.testDotProdUnsignedNarrowerUnsigned(char[], char[]) loop_optimization (after) 541 /// CHECK-NOT: VecDotProd testDotProdUnsignedNarrowerUnsigned(char[] a, char[] b)542 public static final int testDotProdUnsignedNarrowerUnsigned(char[] a, char[] b) { 543 int s = 1; 544 for (int i = 0; i < b.length; i++) { 545 int temp = (a[i] & 0xff) * (b[i] & 0xff); 546 s += temp; 547 } 548 return s - 1; 549 } 550 551 /// CHECK-START: int other.TestCharShort.testDotProdUnsignedSigned(char[], short[]) loop_optimization (after) 552 /// CHECK-NOT: VecDotProd testDotProdUnsignedSigned(char[] a, short[] b)553 public static final int testDotProdUnsignedSigned(char[] a, short[] b) { 554 int s = 1; 555 for (int i = 0; i < b.length; i++) { 556 int temp = a[i] * b[i]; 557 s += temp; 558 } 559 return s - 1; 560 } 561 expectEquals(int expected, int result)562 private static void expectEquals(int expected, int result) { 563 if (expected != result) { 564 throw new Error("Expected: " + expected + ", found: " + result); 565 } 566 } 567 testDotProd(short[] s1, short[] s2, char[] c1, char[] c2, int[] results)568 private static void testDotProd(short[] s1, short[] s2, char[] c1, char[] c2, int[] results) { 569 expectEquals(results[0], testDotProdSimple(s1, s2)); 570 expectEquals(results[1], testDotProdComplex(s1, s2)); 571 expectEquals(results[2], testDotProdSimpleUnsigned(c1, c2)); 572 expectEquals(results[3], testDotProdComplexUnsigned(c1, c2)); 573 expectEquals(results[4], testDotProdComplexUnsignedCastedToSigned(c1, c2)); 574 expectEquals(results[5], testDotProdComplexSignedCastedToUnsigned(s1, s2)); 575 expectEquals(results[6], testDotProdSignedToInt(s1, s2)); 576 expectEquals(results[7], testDotProdParamSigned(-32768, s2)); 577 expectEquals(results[8], testDotProdParamUnsigned(-32768, c2)); 578 expectEquals(results[9], testDotProdIntParam(-32768, s2)); 579 expectEquals(results[10], testDotProdSignedToChar(s1, s2)); 580 expectEquals(results[11], testDotProdSimpleMulCastedToSigned(s1, s2)); 581 expectEquals(results[12], testDotProdSimpleMulCastedToUnsigned(s1, s2)); 582 expectEquals(results[13], testDotProdSimpleUnsignedMulCastedToSigned(c1, c2)); 583 expectEquals(results[14], testDotProdSimpleUnsignedMulCastedToUnsigned(c1, c2)); 584 expectEquals(results[15], testDotProdSimpleCastedToShort(s1, s2)); 585 expectEquals(results[16], testDotProdSimpleCastedToChar(s1, s2)); 586 expectEquals(results[17], testDotProdSimpleUnsignedCastedToShort(c1, c2)); 587 expectEquals(results[18], testDotProdSimpleUnsignedCastedToChar(c1, c2)); 588 expectEquals(results[19], testDotProdSimpleUnsignedCastedToLong(c1, c2)); 589 expectEquals(results[20], testDotProdSignedNarrowerSigned(s1, s2)); 590 expectEquals(results[21], testDotProdSignedNarrowerUnsigned(s1, s2)); 591 expectEquals(results[22], testDotProdUnsignedNarrowerSigned(c1, c2)); 592 expectEquals(results[23], testDotProdUnsignedNarrowerUnsigned(c1, c2)); 593 expectEquals(results[24], testDotProdUnsignedSigned(c1, s2)); 594 } 595 run()596 public static void run() { 597 final short MAX_S = Short.MAX_VALUE; 598 final short MIN_S = Short.MAX_VALUE; 599 600 short[] s1_1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S }; 601 short[] s2_1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S }; 602 char[] c1_1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S }; 603 char[] c2_1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S }; 604 int[] results_1 = { 2147352578, -2147483634, 2147352578, -2147483634, -2147483634, -2147483634, 605 2147352578, -2147418112, 2147418112, -2147418112, 2147352578, 606 2, 2, 2, 2, 2, 2, 2, 2, 2147352578, 2, 130050, 2, 130050, 2147352578 }; 607 testDotProd(s1_1, s2_1, c1_1, c2_1, results_1); 608 609 short[] s1_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S, MAX_S, MAX_S }; 610 short[] s2_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S, MAX_S, MAX_S }; 611 char[] c1_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S, MAX_S, MAX_S }; 612 char[] c2_2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S, MAX_S, MAX_S }; 613 int[] results_2 = { -262140, 12, -262140, 12, 12, 12, -262140, 131072, -131072, 131072, 614 -262140, 4, 4, 4, 4, 4, 4, 4, 4, -262140, 4, 260100, 4, 260100, -262140 }; 615 testDotProd(s1_2, s2_2, c1_2, c2_2, results_2); 616 617 short[] s1_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 618 short[] s2_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S }; 619 char[] c1_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 620 char[] c2_3 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MAX_S, MAX_S }; 621 int[] results_3 = { 2147352578, -2147483634, 2147352578, -2147483634, -2147483634, 622 -2147483634, 2147352578, -2147418112, 2147418112, -2147418112, 623 2147352578, 2, 2, 2, 2, 2, 2, 2, 2, 2147352578, 2, 130050, 2, 624 130050, 2147352578}; 625 testDotProd(s1_3, s2_3, c1_3, c2_3, results_3); 626 627 628 short[] s1_4 = { MIN_S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 629 short[] s2_4 = { MIN_S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 630 char[] c1_4 = { MIN_S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 631 char[] c2_4 = { MIN_S, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 632 int[] results_4 = { -1073938429, -1073741811, -1073938429, -1073741811, -1073741811, 633 -1073741811, -1073938429, 1073840128, -1073840128, 1073840128, 634 -1073938429, 3, 3, 3, 3, 3, 3, 3, 3, -1073938429, 3, 195075, 3, 635 195075, -1073938429 }; 636 testDotProd(s1_4, s2_4, c1_4, c2_4, results_4); 637 } 638 main(String[] args)639 public static void main(String[] args) { 640 run(); 641 } 642 } 643