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. 21 */ 22 public class TestVarious { 23 24 /// CHECK-START: int other.TestVarious.testDotProdConstRight(byte[]) loop_optimization (before) 25 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 26 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 27 /// CHECK-DAG: <<Const89:i\d+>> IntConstant 89 loop:none 28 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 29 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 30 /// CHECK-DAG: <<Get1:b\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 31 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Get1>>,<<Const89>>] loop:<<Loop>> outer_loop:none 32 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 33 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 34 35 /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdConstRight(byte[]) loop_optimization (after) 36 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 37 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 38 /// CHECK-DAG: <<Const16:i\d+>> IntConstant 16 loop:none 39 /// CHECK-DAG: <<Const89:i\d+>> IntConstant 89 loop:none 40 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 41 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const89>>] loop:none 42 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 43 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 44 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 45 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>] type:Int8 loop:<<Loop>> outer_loop:none 46 /// CHECK-DAG: Add [<<Phi1>>,<<Const16>>] loop:<<Loop>> outer_loop:none 47 // 48 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 49 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none testDotProdConstRight(byte[] b)50 public static final int testDotProdConstRight(byte[] b) { 51 int s = 1; 52 for (int i = 0; i < b.length; i++) { 53 int temp = b[i] * 89; 54 s += temp; 55 } 56 return s; 57 } 58 59 /// CHECK-START: int other.TestVarious.testDotProdConstLeft(byte[]) loop_optimization (before) 60 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 61 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 62 /// CHECK-DAG: <<Const89:i\d+>> IntConstant 89 loop:none 63 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 64 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 65 /// CHECK-DAG: <<Get1:a\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 66 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Get1>>,<<Const89>>] loop:<<Loop>> outer_loop:none 67 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 68 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 69 70 /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdConstLeft(byte[]) loop_optimization (after) 71 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 72 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 73 /// CHECK-DAG: <<Const16:i\d+>> IntConstant 16 loop:none 74 /// CHECK-DAG: <<Const89:i\d+>> IntConstant 89 loop:none 75 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 76 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const89>>] loop:none 77 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 78 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 79 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 80 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>] type:Uint8 loop:<<Loop>> outer_loop:none 81 /// CHECK-DAG: Add [<<Phi1>>,<<Const16>>] loop:<<Loop>> outer_loop:none 82 // 83 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 84 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none testDotProdConstLeft(byte[] b)85 public static final int testDotProdConstLeft(byte[] b) { 86 int s = 1; 87 for (int i = 0; i < b.length; i++) { 88 int temp = 89 * (b[i] & 0xff); 89 s += temp; 90 } 91 return s; 92 } 93 94 /// CHECK-START: int other.TestVarious.testDotProdLoopInvariantConvRight(byte[], int) loop_optimization (before) 95 /// CHECK-DAG: <<Param:i\d+>> ParameterValue loop:none 96 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 97 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 98 /// CHECK-DAG: <<ConstL:i\d+>> IntConstant 129 loop:none 99 /// CHECK-DAG: <<AddP:i\d+>> Add [<<Param>>,<<ConstL>>] loop:none 100 /// CHECK-DAG: <<TypeCnv:b\d+>> TypeConversion [<<AddP>>] loop:none 101 // 102 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 103 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 104 /// CHECK-DAG: <<Get1:b\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 105 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Get1>>,<<TypeCnv>>] loop:<<Loop>> outer_loop:none 106 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 107 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 108 109 /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdLoopInvariantConvRight(byte[], int) loop_optimization (after) 110 /// CHECK-DAG: <<Param:i\d+>> ParameterValue loop:none 111 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 112 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 113 /// CHECK-DAG: <<Const16:i\d+>> IntConstant 16 loop:none 114 /// CHECK-DAG: <<ConstL:i\d+>> IntConstant 129 loop:none 115 /// CHECK-DAG: <<AddP:i\d+>> Add [<<Param>>,<<ConstL>>] loop:none 116 /// CHECK-DAG: <<TypeCnv:b\d+>> TypeConversion [<<AddP>>] loop:none 117 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 118 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<TypeCnv>>] loop:none 119 // 120 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 121 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 122 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 123 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>] type:Int8 loop:<<Loop>> outer_loop:none 124 /// CHECK-DAG: Add [<<Phi1>>,<<Const16>>] loop:<<Loop>> outer_loop:none 125 // 126 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 127 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none testDotProdLoopInvariantConvRight(byte[] b, int param)128 public static final int testDotProdLoopInvariantConvRight(byte[] b, int param) { 129 int s = 1; 130 for (int i = 0; i < b.length; i++) { 131 int temp = b[i] * ((byte)(param + 129)); 132 s += temp; 133 } 134 return s; 135 } 136 137 /// CHECK-START: int other.TestVarious.testDotProdByteToChar(char[], char[]) loop_optimization (after) 138 /// CHECK-NOT: VecDotProd testDotProdByteToChar(char[] a, char[] b)139 public static final int testDotProdByteToChar(char[] a, char[] b) { 140 int s = 1; 141 for (int i = 0; i < b.length; i++) { 142 int temp = ((char)((byte)(a[i] + 129))) * b[i]; 143 s += temp; 144 } 145 return s; 146 } 147 148 /// CHECK-START: int other.TestVarious.testDotProdMixedSize(byte[], short[]) loop_optimization (after) 149 /// CHECK-NOT: VecDotProd testDotProdMixedSize(byte[] a, short[] b)150 public static final int testDotProdMixedSize(byte[] a, short[] b) { 151 int s = 1; 152 for (int i = 0; i < b.length; i++) { 153 int temp = a[i] * b[i]; 154 s += temp; 155 } 156 return s; 157 } 158 159 /// CHECK-START: int other.TestVarious.testDotProdMixedSizeAndSign(byte[], char[]) loop_optimization (after) 160 /// CHECK-NOT: VecDotProd testDotProdMixedSizeAndSign(byte[] a, char[] b)161 public static final int testDotProdMixedSizeAndSign(byte[] a, char[] b) { 162 int s = 1; 163 for (int i = 0; i < b.length; i++) { 164 int temp = a[i] * b[i]; 165 s += temp; 166 } 167 return s; 168 } 169 170 /// CHECK-START: int other.TestVarious.testDotProdInt32(int[], int[]) loop_optimization (before) 171 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 172 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 173 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 174 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 175 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 176 /// CHECK-DAG: <<Get2:i\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 177 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none 178 /// CHECK-DAG: Add [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 179 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 180 181 /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdInt32(int[], int[]) loop_optimization (after) 182 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 183 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 184 /// CHECK-DAG: <<Set:d\d+>> VecSetScalars [<<Const1>>] loop:none 185 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 186 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 187 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 188 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 189 /// CHECK-DAG: <<Mul:d\d+>> VecMul [<<Load1>>,<<Load2>>] loop:<<Loop>> outer_loop:none 190 /// CHECK-DAG: VecAdd [<<Phi2>>,<<Mul>>] loop:<<Loop>> outer_loop:none 191 // 192 /// CHECK-DAG: <<Reduce:d\d+>> VecReduce [<<Phi2>>] loop:none 193 /// CHECK-DAG: VecExtractScalar [<<Reduce>>] loop:none testDotProdInt32(int[] a, int[] b)194 public static final int testDotProdInt32(int[] a, int[] b) { 195 int s = 1; 196 for (int i = 0; i < b.length; i++) { 197 int temp = a[i] * b[i]; 198 s += temp; 199 } 200 return s; 201 } 202 203 /// CHECK-START: int other.TestVarious.testDotProdBothSignedUnsigned1(byte[], byte[]) loop_optimization (before) 204 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 205 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 206 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 207 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 208 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 209 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const2>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 210 /// CHECK-DAG: <<Get1:b\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 211 /// CHECK-DAG: <<Get2:b\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 212 /// CHECK-DAG: <<Mul1:i\d+>> Mul [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none 213 /// CHECK-DAG: Add [<<Phi2>>,<<Mul1>>] loop:<<Loop>> outer_loop:none 214 /// CHECK-DAG: <<TypeC1:a\d+>> TypeConversion [<<Get1>>] loop:<<Loop>> outer_loop:none 215 /// CHECK-DAG: <<TypeC2:a\d+>> TypeConversion [<<Get2>>] loop:<<Loop>> outer_loop:none 216 /// CHECK-DAG: <<Mul2:i\d+>> Mul [<<TypeC1>>,<<TypeC2>>] loop:<<Loop>> outer_loop:none 217 /// CHECK-DAG: Add [<<Phi3>>,<<Mul2>>] loop:<<Loop>> outer_loop:none 218 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 219 220 /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdBothSignedUnsigned1(byte[], byte[]) loop_optimization (after) 221 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 222 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 223 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 224 /// CHECK-DAG: <<Const16:i\d+>> IntConstant 16 loop:none 225 /// CHECK-DAG: <<Set1:d\d+>> VecSetScalars [<<Const1>>] loop:none 226 /// CHECK-DAG: <<Set2:d\d+>> VecSetScalars [<<Const2>>] loop:none 227 // 228 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 229 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set1>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 230 /// CHECK-DAG: <<Phi3:d\d+>> Phi [<<Set2>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 231 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 232 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 233 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Int8 loop:<<Loop>> outer_loop:none 234 /// CHECK-DAG: VecDotProd [<<Phi3>>,<<Load1>>,<<Load2>>] type:Uint8 loop:<<Loop>> outer_loop:none 235 /// CHECK-DAG: Add [<<Phi1>>,<<Const16>>] loop:<<Loop>> outer_loop:none testDotProdBothSignedUnsigned1(byte[] a, byte[] b)236 public static final int testDotProdBothSignedUnsigned1(byte[] a, byte[] b) { 237 int s1 = 1; 238 int s2 = 2; 239 for (int i = 0; i < b.length; i++) { 240 byte a_val = a[i]; 241 byte b_val = b[i]; 242 s1 += a_val * b_val; 243 s2 += (a_val & 0xff) * (b_val & 0xff); 244 } 245 return s1 + s2; 246 } 247 248 /// CHECK-START: int other.TestVarious.testDotProdBothSignedUnsigned2(byte[], byte[]) loop_optimization (before) 249 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 250 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 251 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 252 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 loop:none 253 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 254 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 255 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const2>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 256 /// CHECK-DAG: <<Get1:b\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 257 /// CHECK-DAG: <<Get2:a\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 258 /// CHECK-DAG: <<TypeC1:a\d+>> TypeConversion [<<Get1>>] loop:<<Loop>> outer_loop:none 259 /// CHECK-DAG: <<Mul1:i\d+>> Mul [<<Get2>>,<<TypeC1>>] loop:<<Loop>> outer_loop:none 260 /// CHECK-DAG: Add [<<Phi3>>,<<Mul1>>] loop:<<Loop>> outer_loop:none 261 /// CHECK-DAG: <<Mul2:i\d+>> Mul [<<Get1>>,<<Const42>>] loop:<<Loop>> outer_loop:none 262 /// CHECK-DAG: Add [<<Phi2>>,<<Mul2>>] loop:<<Loop>> outer_loop:none 263 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 264 265 /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdBothSignedUnsigned2(byte[], byte[]) loop_optimization (after) 266 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 267 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 268 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 269 /// CHECK-DAG: <<Const16:i\d+>> IntConstant 16 loop:none 270 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 loop:none 271 /// CHECK-DAG: <<Repl:d\d+>> VecReplicateScalar [<<Const42>>] loop:none 272 /// CHECK-DAG: <<Set1:d\d+>> VecSetScalars [<<Const1>>] loop:none 273 /// CHECK-DAG: <<Set2:d\d+>> VecSetScalars [<<Const2>>] loop:none 274 // 275 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 276 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set1>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 277 /// CHECK-DAG: <<Phi3:d\d+>> Phi [<<Set2>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 278 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 279 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 280 /// CHECK-DAG: VecDotProd [<<Phi3>>,<<Load2>>,<<Load1>>] type:Uint8 loop:<<Loop>> outer_loop:none 281 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Repl>>] type:Int8 loop:<<Loop>> outer_loop:none 282 /// CHECK-DAG: Add [<<Phi1>>,<<Const16>>] loop:<<Loop>> outer_loop:none testDotProdBothSignedUnsigned2(byte[] a, byte[] b)283 public static final int testDotProdBothSignedUnsigned2(byte[] a, byte[] b) { 284 int s1 = 1; 285 int s2 = 2; 286 for (int i = 0; i < b.length; i++) { 287 byte a_val = a[i]; 288 byte b_val = b[i]; 289 s2 += (a_val & 0xff) * (b_val & 0xff); 290 s1 += a_val * 42; 291 } 292 return s1 + s2; 293 } 294 295 /// CHECK-START: int other.TestVarious.testDotProdBothSignedUnsignedDoubleLoad(byte[], byte[]) loop_optimization (before) 296 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 297 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 298 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 299 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 300 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 301 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const2>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 302 /// CHECK-DAG: <<GetB1:b\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 303 /// CHECK-DAG: <<GetB2:b\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 304 /// CHECK-DAG: <<Mul1:i\d+>> Mul [<<GetB1>>,<<GetB2>>] loop:<<Loop>> outer_loop:none 305 /// CHECK-DAG: Add [<<Phi2>>,<<Mul1>>] loop:<<Loop>> outer_loop:none 306 /// CHECK-DAG: <<GetA1:a\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 307 /// CHECK-DAG: <<GetA2:a\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 308 /// CHECK-DAG: <<Mul2:i\d+>> Mul [<<GetA1>>,<<GetA2>>] loop:<<Loop>> outer_loop:none 309 /// CHECK-DAG: Add [<<Phi3>>,<<Mul2>>] loop:<<Loop>> outer_loop:none 310 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 311 312 /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdBothSignedUnsignedDoubleLoad(byte[], byte[]) loop_optimization (after) 313 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 314 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 315 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 316 /// CHECK-DAG: <<Const16:i\d+>> IntConstant 16 loop:none 317 /// CHECK-DAG: <<Set1:d\d+>> VecSetScalars [<<Const1>>] loop:none 318 /// CHECK-DAG: <<Set2:d\d+>> VecSetScalars [<<Const2>>] loop:none 319 // 320 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 321 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set1>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 322 /// CHECK-DAG: <<Phi3:d\d+>> Phi [<<Set2>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 323 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 324 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 325 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Int8 loop:<<Loop>> outer_loop:none 326 /// CHECK-DAG: <<Load3:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 327 /// CHECK-DAG: <<Load4:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 328 /// CHECK-DAG: VecDotProd [<<Phi3>>,<<Load3>>,<<Load4>>] type:Uint8 loop:<<Loop>> outer_loop:none 329 /// CHECK-DAG: Add [<<Phi1>>,<<Const16>>] loop:<<Loop>> outer_loop:none testDotProdBothSignedUnsignedDoubleLoad(byte[] a, byte[] b)330 public static final int testDotProdBothSignedUnsignedDoubleLoad(byte[] a, byte[] b) { 331 int s1 = 1; 332 int s2 = 2; 333 for (int i = 0; i < b.length; i++) { 334 s1 += a[i] * b[i]; 335 s2 += (a[i] & 0xff) * (b[i] & 0xff); 336 } 337 return s1 + s2; 338 } 339 340 /// CHECK-START: int other.TestVarious.testDotProdBothSignedUnsignedChar(char[], char[]) loop_optimization (before) 341 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 342 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 343 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 344 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 345 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const1>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 346 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const2>>,{{i\d+}}] loop:<<Loop>> outer_loop:none 347 /// CHECK-DAG: <<Get1:c\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 348 /// CHECK-DAG: <<Get2:c\d+>> ArrayGet [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 349 /// CHECK-DAG: <<TypeS1:s\d+>> TypeConversion [<<Get1>>] loop:<<Loop>> outer_loop:none 350 /// CHECK-DAG: <<TypeS2:s\d+>> TypeConversion [<<Get2>>] loop:<<Loop>> outer_loop:none 351 /// CHECK-DAG: <<Mul1:i\d+>> Mul [<<TypeS1>>,<<TypeS2>>] loop:<<Loop>> outer_loop:none 352 /// CHECK-DAG: Add [<<Phi3>>,<<Mul1>>] loop:<<Loop>> outer_loop:none 353 /// CHECK-DAG: <<Mul2:i\d+>> Mul [<<Get1>>,<<Get2>>] loop:<<Loop>> outer_loop:none 354 /// CHECK-DAG: Add [<<Phi2>>,<<Mul2>>] loop:<<Loop>> outer_loop:none 355 /// CHECK-DAG: Add [<<Phi1>>,<<Const1>>] loop:<<Loop>> outer_loop:none 356 357 /// CHECK-START-{ARM64}: int other.TestVarious.testDotProdBothSignedUnsignedChar(char[], char[]) loop_optimization (after) 358 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 359 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 360 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 loop:none 361 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8 loop:none 362 /// CHECK-DAG: <<Set1:d\d+>> VecSetScalars [<<Const1>>] loop:none 363 /// CHECK-DAG: <<Set2:d\d+>> VecSetScalars [<<Const2>>] loop:none 364 // 365 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop:B\d+>> outer_loop:none 366 /// CHECK-DAG: <<Phi2:d\d+>> Phi [<<Set1>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 367 /// CHECK-DAG: <<Phi3:d\d+>> Phi [<<Set2>>,{{d\d+}}] loop:<<Loop>> outer_loop:none 368 /// CHECK-DAG: <<Load1:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 369 /// CHECK-DAG: <<Load2:d\d+>> VecLoad [{{l\d+}},<<Phi1>>] loop:<<Loop>> outer_loop:none 370 /// CHECK-DAG: VecDotProd [<<Phi3>>,<<Load1>>,<<Load2>>] type:Int16 loop:<<Loop>> outer_loop:none 371 /// CHECK-DAG: VecDotProd [<<Phi2>>,<<Load1>>,<<Load2>>] type:Uint16 loop:<<Loop>> outer_loop:none 372 /// CHECK-DAG: Add [<<Phi1>>,<<Const8>>] loop:<<Loop>> outer_loop:none testDotProdBothSignedUnsignedChar(char[] a, char[] b)373 public static final int testDotProdBothSignedUnsignedChar(char[] a, char[] b) { 374 int s1 = 1; 375 int s2 = 2; 376 for (int i = 0; i < b.length; i++) { 377 char a_val = a[i]; 378 char b_val = b[i]; 379 s2 += ((short)a_val) * ((short)b_val); 380 s1 += a_val * b_val; 381 } 382 return s1 + s2; 383 } 384 expectEquals(int expected, int result)385 private static void expectEquals(int expected, int result) { 386 if (expected != result) { 387 throw new Error("Expected: " + expected + ", found: " + result); 388 } 389 } 390 run()391 public static void run() { 392 final short MAX_S = Short.MAX_VALUE; 393 final short MIN_S = Short.MAX_VALUE; 394 395 byte[] b1 = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, -128, -128, -128 }; 396 byte[] b2 = { 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127 }; 397 398 char[] c1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 399 char[] c2 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 400 401 int[] i1 = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -128, -128, -128, -128 }; 402 int[] i2 = { 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127 }; 403 404 short[] s1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, MIN_S, MIN_S }; 405 406 expectEquals(56516, testDotProdConstRight(b2)); 407 expectEquals(56516, testDotProdConstLeft(b2)); 408 expectEquals(1271, testDotProdLoopInvariantConvRight(b2, 129)); 409 expectEquals(-8519423, testDotProdByteToChar(c1, c2)); 410 expectEquals(-8388351, testDotProdMixedSize(b1, s1)); 411 expectEquals(-8388351, testDotProdMixedSizeAndSign(b1, c2)); 412 expectEquals(-81279, testDotProdInt32(i1, i2)); 413 expectEquals(3, testDotProdBothSignedUnsigned1(b1, b2)); 414 expectEquals(54403, testDotProdBothSignedUnsigned2(b1, b2)); 415 expectEquals(3, testDotProdBothSignedUnsignedDoubleLoad(b1, b2)); 416 expectEquals(-262137, testDotProdBothSignedUnsignedChar(c1, c2)); 417 } 418 main(String[] args)419 public static void main(String[] args) { 420 run(); 421 } 422 } 423