1 /* 2 * Copyright (C) 2015 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 public class Main { 18 19 // A dummy value to defeat inlining of these routines. 20 static boolean doThrow = false; 21 22 public static void assertByteEquals(byte expected, byte result) { 23 if (expected != result) { 24 throw new Error("Expected: " + expected + ", found: " + result); 25 } 26 } 27 28 public static void assertCharEquals(char expected, char result) { 29 if (expected != result) { 30 throw new Error("Expected: " + expected + ", found: " + result); 31 } 32 } 33 34 public static void assertShortEquals(short expected, short result) { 35 if (expected != result) { 36 throw new Error("Expected: " + expected + ", found: " + result); 37 } 38 } 39 40 public static void assertIntEquals(int expected, int result) { 41 if (expected != result) { 42 throw new Error("Expected: " + expected + ", found: " + result); 43 } 44 } 45 46 public static void assertLongEquals(long expected, long result) { 47 if (expected != result) { 48 throw new Error("Expected: " + expected + ", found: " + result); 49 } 50 } 51 52 // Non-inlinable type-casting helpers. 53 static char $noinline$byteToChar (byte v) { if (doThrow) throw new Error(); return (char)v; } 54 static short $noinline$byteToShort (byte v) { if (doThrow) throw new Error(); return (short)v; } 55 static int $noinline$byteToInt (byte v) { if (doThrow) throw new Error(); return (int)v; } 56 static long $noinline$byteToLong (byte v) { if (doThrow) throw new Error(); return (long)v; } 57 static byte $noinline$charToByte (char v) { if (doThrow) throw new Error(); return (byte)v; } 58 static short $noinline$charToShort (char v) { if (doThrow) throw new Error(); return (short)v; } 59 static int $noinline$charToInt (char v) { if (doThrow) throw new Error(); return (int)v; } 60 static long $noinline$charToLong (char v) { if (doThrow) throw new Error(); return (long)v; } 61 static byte $noinline$shortToByte (short v) { if (doThrow) throw new Error(); return (byte)v; } 62 static char $noinline$shortToChar (short v) { if (doThrow) throw new Error(); return (char)v; } 63 static int $noinline$shortToInt (short v) { if (doThrow) throw new Error(); return (int)v; } 64 static long $noinline$shortToLong (short v) { if (doThrow) throw new Error(); return (long)v; } 65 static byte $noinline$intToByte (int v) { if (doThrow) throw new Error(); return (byte)v; } 66 static char $noinline$intToChar (int v) { if (doThrow) throw new Error(); return (char)v; } 67 static short $noinline$intToShort (int v) { if (doThrow) throw new Error(); return (short)v; } 68 static long $noinline$intToLong (int v) { if (doThrow) throw new Error(); return (long)v; } 69 static byte $noinline$longToByte (long v) { if (doThrow) throw new Error(); return (byte)v; } 70 static char $noinline$longToChar (long v) { if (doThrow) throw new Error(); return (char)v; } 71 static short $noinline$longToShort (long v) { if (doThrow) throw new Error(); return (short)v; } 72 static int $noinline$longToInt (long v) { if (doThrow) throw new Error(); return (int)v; } 73 74 /** 75 * Basic test merging a bitfield move operation (here a type conversion) into 76 * the shifter operand. 77 */ 78 79 /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (before) 80 /// CHECK-DAG: <<l:j\d+>> ParameterValue 81 /// CHECK-DAG: <<b:b\d+>> ParameterValue 82 /// CHECK: <<tmp:j\d+>> TypeConversion [<<b>>] 83 /// CHECK: Sub [<<l>>,<<tmp>>] 84 85 /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (after) 86 /// CHECK-DAG: <<l:j\d+>> ParameterValue 87 /// CHECK-DAG: <<b:b\d+>> ParameterValue 88 /// CHECK: DataProcWithShifterOp [<<l>>,<<b>>] kind:Sub+SXTB 89 90 /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm (after) 91 /// CHECK-NOT: TypeConversion 92 /// CHECK-NOT: Sub 93 94 /// CHECK-START-ARM: long Main.$opt$noinline$translate(long, byte) disassembly (after) 95 /// CHECK: subs r{{\d+}}, r{{\d+}}, r{{\d+}} 96 /// CHECK: sbc r{{\d+}}, r{{\d+}}, r{{\d+}}, asr #31 97 98 /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (before) 99 /// CHECK-DAG: <<l:j\d+>> ParameterValue 100 /// CHECK-DAG: <<b:b\d+>> ParameterValue 101 /// CHECK: <<tmp:j\d+>> TypeConversion [<<b>>] 102 /// CHECK: Sub [<<l>>,<<tmp>>] 103 104 /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (after) 105 /// CHECK-DAG: <<l:j\d+>> ParameterValue 106 /// CHECK-DAG: <<b:b\d+>> ParameterValue 107 /// CHECK: DataProcWithShifterOp [<<l>>,<<b>>] kind:Sub+SXTB 108 109 /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) instruction_simplifier_arm64 (after) 110 /// CHECK-NOT: TypeConversion 111 /// CHECK-NOT: Sub 112 113 /// CHECK-START-ARM64: long Main.$opt$noinline$translate(long, byte) disassembly (after) 114 /// CHECK: sub x{{\d+}}, x{{\d+}}, w{{\d+}}, sxtb 115 116 public static long $opt$noinline$translate(long l, byte b) { 117 if (doThrow) throw new Error(); 118 long tmp = (long)b; 119 return l - tmp; 120 } 121 122 123 /** 124 * Test that we do not merge into the shifter operand when the left and right 125 * inputs are the the IR. 126 */ 127 128 /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (before) 129 /// CHECK: <<a:i\d+>> ParameterValue 130 /// CHECK: <<Const2:i\d+>> IntConstant 2 131 /// CHECK: <<tmp:i\d+>> Shl [<<a>>,<<Const2>>] 132 /// CHECK: Add [<<tmp>>,<<tmp>>] 133 134 /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (after) 135 /// CHECK-DAG: <<a:i\d+>> ParameterValue 136 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 137 /// CHECK: <<Shl:i\d+>> Shl [<<a>>,<<Const2>>] 138 /// CHECK: Add [<<Shl>>,<<Shl>>] 139 140 /// CHECK-START-ARM: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm (after) 141 /// CHECK-NOT: DataProcWithShifterOp 142 143 /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (before) 144 /// CHECK: <<a:i\d+>> ParameterValue 145 /// CHECK: <<Const2:i\d+>> IntConstant 2 146 /// CHECK: <<tmp:i\d+>> Shl [<<a>>,<<Const2>>] 147 /// CHECK: Add [<<tmp>>,<<tmp>>] 148 149 /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (after) 150 /// CHECK-DAG: <<a:i\d+>> ParameterValue 151 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 152 /// CHECK: <<Shl:i\d+>> Shl [<<a>>,<<Const2>>] 153 /// CHECK: Add [<<Shl>>,<<Shl>>] 154 155 /// CHECK-START-ARM64: int Main.$opt$noinline$sameInput(int) instruction_simplifier_arm64 (after) 156 /// CHECK-NOT: DataProcWithShifterOp 157 158 public static int $opt$noinline$sameInput(int a) { 159 if (doThrow) throw new Error(); 160 int tmp = a << 2; 161 return tmp + tmp; 162 } 163 164 /** 165 * Check that we perform the merge for multiple uses. 166 */ 167 168 /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (before) 169 /// CHECK: <<arg:i\d+>> ParameterValue 170 /// CHECK: <<Const23:i\d+>> IntConstant 23 171 /// CHECK: <<tmp:i\d+>> Shl [<<arg>>,<<Const23>>] 172 /// CHECK: Add [<<tmp>>,{{i\d+}}] 173 /// CHECK: Add [<<tmp>>,{{i\d+}}] 174 /// CHECK: Add [<<tmp>>,{{i\d+}}] 175 /// CHECK: Add [<<tmp>>,{{i\d+}}] 176 /// CHECK: Add [<<tmp>>,{{i\d+}}] 177 178 /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (after) 179 /// CHECK: <<arg:i\d+>> ParameterValue 180 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 181 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 182 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 183 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 184 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 185 186 /// CHECK-START-ARM: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm (after) 187 /// CHECK-NOT: Shl 188 /// CHECK-NOT: Add 189 190 /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (before) 191 /// CHECK: <<arg:i\d+>> ParameterValue 192 /// CHECK: <<Const23:i\d+>> IntConstant 23 193 /// CHECK: <<tmp:i\d+>> Shl [<<arg>>,<<Const23>>] 194 /// CHECK: Add [<<tmp>>,{{i\d+}}] 195 /// CHECK: Add [<<tmp>>,{{i\d+}}] 196 /// CHECK: Add [<<tmp>>,{{i\d+}}] 197 /// CHECK: Add [<<tmp>>,{{i\d+}}] 198 /// CHECK: Add [<<tmp>>,{{i\d+}}] 199 200 /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (after) 201 /// CHECK: <<arg:i\d+>> ParameterValue 202 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 203 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 204 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 205 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 206 /// CHECK: DataProcWithShifterOp [{{i\d+}},<<arg>>] kind:Add+LSL shift:23 207 208 /// CHECK-START-ARM64: int Main.$opt$noinline$multipleUses(int) instruction_simplifier_arm64 (after) 209 /// CHECK-NOT: Shl 210 /// CHECK-NOT: Add 211 212 public static int $opt$noinline$multipleUses(int arg) { 213 if (doThrow) throw new Error(); 214 int tmp = arg << 23; 215 switch (arg) { 216 case 1: return (arg | 1) + tmp; 217 case 2: return (arg | 2) + tmp; 218 case 3: return (arg | 3) + tmp; 219 case 4: return (arg | 4) + tmp; 220 case (1 << 20): return (arg | 5) + tmp; 221 default: return 0; 222 } 223 } 224 225 /** 226 * Logical instructions cannot take 'extend' operations into the shift 227 * operand, so test that only the shifts are merged. 228 */ 229 230 /// CHECK-START-ARM: void Main.$opt$noinline$testAnd(long, long) instruction_simplifier_arm (after) 231 /// CHECK: DataProcWithShifterOp 232 /// CHECK-NOT: DataProcWithShifterOp 233 234 /// CHECK-START-ARM: void Main.$opt$noinline$testAnd(long, long) disassembly (after) 235 /// CHECK: and lsl 236 /// CHECK: sbfx 237 /// CHECK: asr{{s?}} 238 /// CHECK: and{{s?}} 239 240 /// CHECK-START-ARM64: void Main.$opt$noinline$testAnd(long, long) instruction_simplifier_arm64 (after) 241 /// CHECK: DataProcWithShifterOp 242 /// CHECK-NOT: DataProcWithShifterOp 243 244 /// CHECK-START-ARM64: void Main.$opt$noinline$testAnd(long, long) disassembly (after) 245 /// CHECK: and lsl 246 /// CHECK: sxtb 247 /// CHECK: and 248 249 static void $opt$noinline$testAnd(long a, long b) { 250 if (doThrow) throw new Error(); 251 assertLongEquals((a & $noinline$LongShl(b, 5)) | (a & $noinline$longToByte(b)), 252 (a & (b << 5)) | (a & (byte)b)); 253 } 254 255 /// CHECK-START-ARM: void Main.$opt$noinline$testOr(int, int) instruction_simplifier_arm (after) 256 /// CHECK: DataProcWithShifterOp 257 /// CHECK-NOT: DataProcWithShifterOp 258 259 /// CHECK-START-ARM: void Main.$opt$noinline$testOr(int, int) disassembly (after) 260 /// CHECK: orr asr 261 /// CHECK: ubfx 262 /// CHECK: orr{{s?}} 263 264 /// CHECK-START-ARM64: void Main.$opt$noinline$testOr(int, int) instruction_simplifier_arm64 (after) 265 /// CHECK: DataProcWithShifterOp 266 /// CHECK-NOT: DataProcWithShifterOp 267 268 /// CHECK-START-ARM64: void Main.$opt$noinline$testOr(int, int) disassembly (after) 269 /// CHECK: orr asr 270 /// CHECK: uxth 271 /// CHECK: orr 272 273 static void $opt$noinline$testOr(int a, int b) { 274 if (doThrow) throw new Error(); 275 assertIntEquals((a | $noinline$IntShr(b, 6)) | (a | $noinline$intToChar(b)), 276 (a | (b >> 6)) | (a | (char)b)); 277 } 278 279 /// CHECK-START-ARM: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm (after) 280 /// CHECK: DataProcWithShifterOp 281 /// CHECK-NOT: DataProcWithShifterOp 282 283 /// CHECK-START-ARM: void Main.$opt$noinline$testXor(long, long) disassembly (after) 284 /// CHECK: eor lsr 285 /// CHECK: asr{{s?}} 286 /// CHECK: eor{{s?}} 287 288 /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm64 (after) 289 /// CHECK: DataProcWithShifterOp 290 /// CHECK-NOT: DataProcWithShifterOp 291 292 /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) disassembly (after) 293 /// CHECK: eor lsr 294 /// CHECK: sxtw 295 /// CHECK: eor 296 297 static void $opt$noinline$testXor(long a, long b) { 298 if (doThrow) throw new Error(); 299 assertLongEquals((a ^ $noinline$LongUshr(b, 7)) | (a ^ $noinline$longToInt(b)), 300 (a ^ (b >>> 7)) | (a ^ (int)b)); 301 } 302 303 /// CHECK-START-ARM: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm (after) 304 /// CHECK-NOT: DataProcWithShifterOp 305 306 /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm64 (after) 307 /// CHECK: DataProcWithShifterOp 308 /// CHECK-NOT: DataProcWithShifterOp 309 310 /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) disassembly (after) 311 /// CHECK: neg lsl 312 /// CHECK: sxth 313 /// CHECK: neg 314 315 static void $opt$noinline$testNeg(int a) { 316 if (doThrow) throw new Error(); 317 assertIntEquals(-$noinline$IntShl(a, 8) | -$noinline$intToShort(a), 318 (-(a << 8)) | (-(short)a)); 319 } 320 321 /** 322 * The functions below are used to compare the result of optimized operations 323 * to non-optimized operations. 324 * On the left-hand side we use a non-inlined function call to ensure the 325 * optimization does not occur. The checker tests ensure that the optimization 326 * does occur on the right-hand. 327 */ 328 329 /// CHECK-START-ARM: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm (after) 330 /// CHECK: DataProcWithShifterOp 331 /// CHECK-NOT: DataProcWithShifterOp 332 333 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after) 334 /// CHECK: DataProcWithShifterOp 335 /// CHECK-NOT: DataProcWithShifterOp 336 337 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm64 (after) 338 /// CHECK-NOT: TypeConversion 339 340 public static void $opt$validateExtendByteInt1(int a, byte b) { 341 assertIntEquals(a + $noinline$byteToChar (b), a + (char)b); 342 // Conversions byte->short and short->int are implicit; nothing to merge. 343 assertIntEquals(a + $noinline$byteToShort(b), a + (short)b); 344 } 345 346 /// CHECK-START-ARM: void Main.$opt$validateExtendByteInt2(int, byte) instruction_simplifier_arm (after) 347 /// CHECK-NOT: DataProcWithShifterOp 348 349 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteInt2(int, byte) instruction_simplifier_arm64 (after) 350 /// CHECK-NOT: DataProcWithShifterOp 351 352 public static void $opt$validateExtendByteInt2(int a, byte b) { 353 // The conversion to `int` has been optimized away, so there is nothing to merge. 354 assertIntEquals (a + $noinline$byteToInt (b), a + (int)b); 355 // There is an environment use for `(long)b`, preventing the merge. 356 assertLongEquals(a + $noinline$byteToLong(b), a + (long)b); 357 } 358 359 /// CHECK-START-ARM: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm (after) 360 /// CHECK: DataProcWithShifterOp 361 /// CHECK: DataProcWithShifterOp 362 /// CHECK: DataProcWithShifterOp 363 /// CHECK: DataProcWithShifterOp 364 /// CHECK: DataProcWithShifterOp 365 /// CHECK-NOT: DataProcWithShifterOp 366 367 /// CHECK-START-ARM: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm (after) 368 /// CHECK: TypeConversion 369 /// CHECK-NOT: TypeConversion 370 371 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after) 372 /// CHECK: DataProcWithShifterOp 373 /// CHECK: DataProcWithShifterOp 374 /// CHECK: DataProcWithShifterOp 375 /// CHECK: DataProcWithShifterOp 376 /// CHECK: DataProcWithShifterOp 377 /// CHECK-NOT: DataProcWithShifterOp 378 379 /// CHECK-START-ARM64: void Main.$opt$validateExtendByteLong(long, byte) instruction_simplifier_arm64 (after) 380 /// CHECK: TypeConversion 381 /// CHECK-NOT: TypeConversion 382 383 public static void $opt$validateExtendByteLong(long a, byte b) { 384 // In each of the following tests, there will be a merge on the LHS. 385 386 // The first test has an explicit byte->char conversion on RHS, 387 // followed by a conversion that is merged with the Add. 388 assertLongEquals(a + $noinline$byteToChar (b), a + (char)b); 389 // Since conversions byte->short and byte->int are implicit, the RHS 390 // for the two tests below is the same and one is eliminated by GVN. 391 // The other is then merged to a shifter operand instruction. 392 assertLongEquals(a + $noinline$byteToShort(b), a + (short)b); 393 assertLongEquals(a + $noinline$byteToInt (b), a + (int)b); 394 } 395 396 public static void $opt$validateExtendByte(long a, byte b) { 397 $opt$validateExtendByteInt1((int)a, b); 398 $opt$validateExtendByteInt2((int)a, b); 399 $opt$validateExtendByteLong(a, b); 400 } 401 402 /// CHECK-START-ARM: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm (after) 403 /// CHECK: DataProcWithShifterOp 404 /// CHECK: DataProcWithShifterOp 405 /// CHECK-NOT: DataProcWithShifterOp 406 407 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after) 408 /// CHECK: DataProcWithShifterOp 409 /// CHECK: DataProcWithShifterOp 410 411 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after) 412 /// CHECK-NOT: TypeConversion 413 414 public static void $opt$validateExtendCharInt1(int a, char b) { 415 assertIntEquals(a + $noinline$charToByte (b), a + (byte)b); 416 assertIntEquals(a + $noinline$charToShort(b), a + (short)b); 417 } 418 419 /// CHECK-START-ARM: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm (after) 420 /// CHECK-NOT: DataProcWithShifterOp 421 422 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm64 (after) 423 /// CHECK-NOT: DataProcWithShifterOp 424 425 public static void $opt$validateExtendCharInt2(int a, char b) { 426 // The conversion to `int` has been optimized away, so there is nothing to merge. 427 assertIntEquals (a + $noinline$charToInt (b), a + (int)b); 428 // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge. 429 assertLongEquals(a + $noinline$charToLong(b), a + (long)b); 430 } 431 432 /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after) 433 /// CHECK: DataProcWithShifterOp 434 /// CHECK: DataProcWithShifterOp 435 /// CHECK: DataProcWithShifterOp 436 /// CHECK: DataProcWithShifterOp 437 /// CHECK: DataProcWithShifterOp 438 /// CHECK: DataProcWithShifterOp 439 /// CHECK-NOT: DataProcWithShifterOp 440 441 /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after) 442 /// CHECK: TypeConversion 443 /// CHECK: TypeConversion 444 /// CHECK-NOT: TypeConversion 445 446 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after) 447 /// CHECK: DataProcWithShifterOp 448 /// CHECK: DataProcWithShifterOp 449 /// CHECK: DataProcWithShifterOp 450 /// CHECK: DataProcWithShifterOp 451 /// CHECK: DataProcWithShifterOp 452 /// CHECK: DataProcWithShifterOp 453 /// CHECK-NOT: DataProcWithShifterOp 454 455 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after) 456 /// CHECK: TypeConversion 457 /// CHECK: TypeConversion 458 /// CHECK-NOT: TypeConversion 459 460 public static void $opt$validateExtendCharLong(long a, char b) { 461 // The first two tests have a type conversion. 462 assertLongEquals(a + $noinline$charToByte (b), a + (byte)b); 463 assertLongEquals(a + $noinline$charToShort(b), a + (short)b); 464 // On ARM64 this test does not because the conversion to `int` is optimized away. 465 assertLongEquals(a + $noinline$charToInt (b), a + (int)b); 466 } 467 468 public static void $opt$validateExtendChar(long a, char b) { 469 $opt$validateExtendCharInt1((int)a, b); 470 $opt$validateExtendCharInt2((int)a, b); 471 $opt$validateExtendCharLong(a, b); 472 } 473 474 /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm (after) 475 /// CHECK: DataProcWithShifterOp 476 /// CHECK: DataProcWithShifterOp 477 /// CHECK-NOT: DataProcWithShifterOp 478 479 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after) 480 /// CHECK: DataProcWithShifterOp 481 /// CHECK: DataProcWithShifterOp 482 483 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after) 484 /// CHECK-NOT: TypeConversion 485 486 public static void $opt$validateExtendShortInt1(int a, short b) { 487 assertIntEquals(a + $noinline$shortToByte (b), a + (byte)b); 488 assertIntEquals(a + $noinline$shortToChar (b), a + (char)b); 489 } 490 491 /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm (after) 492 /// CHECK-NOT: DataProcWithShifterOp 493 494 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm64 (after) 495 /// CHECK-NOT: DataProcWithShifterOp 496 497 public static void $opt$validateExtendShortInt2(int a, short b) { 498 // The conversion to `int` has been optimized away, so there is nothing to merge. 499 assertIntEquals (a + $noinline$shortToInt (b), a + (int)b); 500 // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge. 501 assertLongEquals(a + $noinline$shortToLong (b), a + (long)b); 502 } 503 504 /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after) 505 /// CHECK: DataProcWithShifterOp 506 /// CHECK: DataProcWithShifterOp 507 /// CHECK: DataProcWithShifterOp 508 /// CHECK: DataProcWithShifterOp 509 /// CHECK: DataProcWithShifterOp 510 /// CHECK: DataProcWithShifterOp 511 /// CHECK-NOT: DataProcWithShifterOp 512 513 /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after) 514 /// CHECK: TypeConversion 515 /// CHECK: TypeConversion 516 /// CHECK-NOT: TypeConversion 517 518 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after) 519 /// CHECK: DataProcWithShifterOp 520 /// CHECK: DataProcWithShifterOp 521 /// CHECK: DataProcWithShifterOp 522 /// CHECK: DataProcWithShifterOp 523 /// CHECK: DataProcWithShifterOp 524 /// CHECK: DataProcWithShifterOp 525 /// CHECK-NOT: DataProcWithShifterOp 526 527 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after) 528 /// CHECK: TypeConversion 529 /// CHECK: TypeConversion 530 /// CHECK-NOT: TypeConversion 531 532 public static void $opt$validateExtendShortLong(long a, short b) { 533 // The first two tests have a type conversion. 534 assertLongEquals(a + $noinline$shortToByte(b), a + (byte)b); 535 assertLongEquals(a + $noinline$shortToChar(b), a + (char)b); 536 // On ARM64 this test does not because the conversion to `int` is optimized away. 537 assertLongEquals(a + $noinline$shortToInt (b), a + (int)b); 538 } 539 540 public static void $opt$validateExtendShort(long a, short b) { 541 $opt$validateExtendShortInt1((int)a, b); 542 $opt$validateExtendShortInt2((int)a, b); 543 $opt$validateExtendShortLong(a, b); 544 } 545 546 /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after) 547 /// CHECK: DataProcWithShifterOp 548 /// CHECK: DataProcWithShifterOp 549 /// CHECK: DataProcWithShifterOp 550 /// CHECK: DataProcWithShifterOp 551 /// CHECK: DataProcWithShifterOp 552 /// CHECK: DataProcWithShifterOp 553 /// CHECK: DataProcWithShifterOp 554 /// CHECK-NOT: DataProcWithShifterOp 555 556 /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after) 557 /// CHECK: TypeConversion 558 /// CHECK: TypeConversion 559 /// CHECK: TypeConversion 560 /// CHECK-NOT: TypeConversion 561 562 /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after) 563 /// CHECK: DataProcWithShifterOp 564 /// CHECK: DataProcWithShifterOp 565 /// CHECK: DataProcWithShifterOp 566 /// CHECK: DataProcWithShifterOp 567 /// CHECK: DataProcWithShifterOp 568 /// CHECK: DataProcWithShifterOp 569 /// CHECK: DataProcWithShifterOp 570 /// CHECK-NOT: DataProcWithShifterOp 571 572 /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after) 573 /// CHECK: TypeConversion 574 /// CHECK: TypeConversion 575 /// CHECK: TypeConversion 576 /// CHECK-NOT: TypeConversion 577 578 public static void $opt$validateExtendInt(long a, int b) { 579 // All tests have a conversion to `long`. The first three tests also have a 580 // conversion from `int` to the specified type. For each test the conversion 581 // to `long` is merged into the shifter operand. 582 assertLongEquals(a + $noinline$intToByte (b), a + (byte)b); 583 assertLongEquals(a + $noinline$intToChar (b), a + (char)b); 584 assertLongEquals(a + $noinline$intToShort(b), a + (short)b); 585 assertLongEquals(a + $noinline$intToLong (b), a + (long)b); 586 } 587 588 /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after) 589 /// CHECK: DataProcWithShifterOp 590 /// CHECK: DataProcWithShifterOp 591 /// CHECK: DataProcWithShifterOp 592 /// CHECK: DataProcWithShifterOp 593 /// CHECK: DataProcWithShifterOp 594 /// CHECK: DataProcWithShifterOp 595 /// CHECK: DataProcWithShifterOp 596 /// CHECK: DataProcWithShifterOp 597 /// CHECK-NOT: DataProcWithShifterOp 598 599 /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after) 600 /// CHECK: TypeConversion 601 /// CHECK: TypeConversion 602 /// CHECK: TypeConversion 603 /// CHECK: TypeConversion 604 /// CHECK-NOT: TypeConversion 605 606 /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after) 607 /// CHECK: DataProcWithShifterOp 608 /// CHECK: DataProcWithShifterOp 609 /// CHECK: DataProcWithShifterOp 610 /// CHECK: DataProcWithShifterOp 611 /// CHECK: DataProcWithShifterOp 612 /// CHECK: DataProcWithShifterOp 613 /// CHECK: DataProcWithShifterOp 614 /// CHECK: DataProcWithShifterOp 615 /// CHECK-NOT: DataProcWithShifterOp 616 617 /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after) 618 /// CHECK: TypeConversion 619 /// CHECK: TypeConversion 620 /// CHECK: TypeConversion 621 /// CHECK: TypeConversion 622 /// CHECK-NOT: TypeConversion 623 624 public static void $opt$validateExtendLong(long a, long b) { 625 // Each test has two conversions, from `long` and then back to `long`. The 626 // conversions to `long` are merged. 627 assertLongEquals(a + $noinline$longToByte (b), a + (byte)b); 628 assertLongEquals(a + $noinline$longToChar (b), a + (char)b); 629 assertLongEquals(a + $noinline$longToShort(b), a + (short)b); 630 assertLongEquals(a + $noinline$longToInt (b), a + (int)b); 631 } 632 633 634 static int $noinline$IntShl(int b, int c) { 635 if (doThrow) throw new Error(); 636 return b << c; 637 } 638 static int $noinline$IntShr(int b, int c) { 639 if (doThrow) throw new Error(); 640 return b >> c; 641 } 642 static int $noinline$IntUshr(int b, int c) { 643 if (doThrow) throw new Error(); 644 return b >>> c; 645 } 646 647 648 // Each test line below should see one merge. 649 // 650 /// CHECK-START: void Main.$opt$validateShiftInt(int, int) instruction_simplifier$after_inlining (before) 651 /// CHECK: Shl 652 /// CHECK: Shl 653 /// CHECK: Shl 654 /// CHECK: Shl 655 /// CHECK: Shl 656 /// CHECK: Shl 657 /// CHECK: Shl 658 /// CHECK: Shl 659 /// CHECK: Shl 660 /// CHECK: Shl 661 /// CHECK: Shl 662 /// CHECK: Shl 663 /// CHECK-NOT: Shl 664 /// CHECK: Shr 665 /// CHECK: Shr 666 /// CHECK: Shr 667 /// CHECK: Shr 668 /// CHECK: Shr 669 /// CHECK: Shr 670 /// CHECK: Shr 671 /// CHECK: Shr 672 /// CHECK: Shr 673 /// CHECK: Shr 674 /// CHECK: Shr 675 /// CHECK: Shr 676 /// CHECK-NOT: Shl 677 /// CHECK: UShr 678 /// CHECK: UShr 679 /// CHECK: UShr 680 /// CHECK: UShr 681 /// CHECK: UShr 682 /// CHECK: UShr 683 /// CHECK: UShr 684 /// CHECK: UShr 685 /// CHECK: UShr 686 /// CHECK: UShr 687 /// CHECK: UShr 688 /// CHECK: UShr 689 /// CHECK-NOT: UShr 690 // 691 // Note: simplification after inlining removes `b << 32`, `b >> 32` and `b >>> 32`. 692 // 693 /// CHECK-START: void Main.$opt$validateShiftInt(int, int) instruction_simplifier$after_inlining (after) 694 /// CHECK: Shl 695 /// CHECK: Shl 696 /// CHECK: Shl 697 /// CHECK: Shl 698 /// CHECK: Shl 699 /// CHECK: Shl 700 /// CHECK: Shl 701 /// CHECK: Shl 702 /// CHECK: Shl 703 /// CHECK: Shl 704 /// CHECK: Shl 705 /// CHECK-NOT: Shl 706 /// CHECK: Shr 707 /// CHECK: Shr 708 /// CHECK: Shr 709 /// CHECK: Shr 710 /// CHECK: Shr 711 /// CHECK: Shr 712 /// CHECK: Shr 713 /// CHECK: Shr 714 /// CHECK: Shr 715 /// CHECK: Shr 716 /// CHECK: Shr 717 /// CHECK-NOT: Shl 718 /// CHECK: UShr 719 /// CHECK: UShr 720 /// CHECK: UShr 721 /// CHECK: UShr 722 /// CHECK: UShr 723 /// CHECK: UShr 724 /// CHECK: UShr 725 /// CHECK: UShr 726 /// CHECK: UShr 727 /// CHECK: UShr 728 /// CHECK: UShr 729 /// CHECK-NOT: UShr 730 // 731 // Note: running extra simplification after inlining and before GVN exposes the common 732 // subexpressions between shifts with larger distance `b << 62`, `b << 63` etc. 733 // and the equivalent smaller distances. 734 // 735 /// CHECK-START: void Main.$opt$validateShiftInt(int, int) GVN (after) 736 /// CHECK: Shl 737 /// CHECK: Shl 738 /// CHECK: Shl 739 /// CHECK: Shl 740 /// CHECK: Shl 741 /// CHECK: Shl 742 /// CHECK: Shl 743 /// CHECK: Shl 744 /// CHECK: Shl 745 /// CHECK-NOT: Shl 746 /// CHECK: Shr 747 /// CHECK: Shr 748 /// CHECK: Shr 749 /// CHECK: Shr 750 /// CHECK: Shr 751 /// CHECK: Shr 752 /// CHECK: Shr 753 /// CHECK: Shr 754 /// CHECK: Shr 755 /// CHECK-NOT: Shl 756 /// CHECK: UShr 757 /// CHECK: UShr 758 /// CHECK: UShr 759 /// CHECK: UShr 760 /// CHECK: UShr 761 /// CHECK: UShr 762 /// CHECK: UShr 763 /// CHECK: UShr 764 /// CHECK: UShr 765 /// CHECK-NOT: UShr 766 // 767 /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after) 768 /// CHECK: DataProcWithShifterOp 769 /// CHECK: DataProcWithShifterOp 770 /// CHECK: DataProcWithShifterOp 771 /// CHECK: DataProcWithShifterOp 772 /// CHECK: DataProcWithShifterOp 773 /// CHECK: DataProcWithShifterOp 774 /// CHECK: DataProcWithShifterOp 775 /// CHECK: DataProcWithShifterOp 776 /// CHECK: DataProcWithShifterOp 777 /// CHECK: DataProcWithShifterOp 778 /// CHECK: DataProcWithShifterOp 779 /// CHECK: DataProcWithShifterOp 780 /// CHECK: DataProcWithShifterOp 781 /// CHECK: DataProcWithShifterOp 782 /// CHECK: DataProcWithShifterOp 783 /// CHECK: DataProcWithShifterOp 784 /// CHECK: DataProcWithShifterOp 785 /// CHECK: DataProcWithShifterOp 786 /// CHECK: DataProcWithShifterOp 787 /// CHECK: DataProcWithShifterOp 788 /// CHECK: DataProcWithShifterOp 789 /// CHECK: DataProcWithShifterOp 790 /// CHECK: DataProcWithShifterOp 791 /// CHECK: DataProcWithShifterOp 792 /// CHECK: DataProcWithShifterOp 793 /// CHECK: DataProcWithShifterOp 794 /// CHECK: DataProcWithShifterOp 795 /// CHECK-NOT: DataProcWithShifterOp 796 797 /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after) 798 /// CHECK-NOT: Shl 799 /// CHECK-NOT: Shr 800 /// CHECK-NOT: UShr 801 802 /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after) 803 /// CHECK: DataProcWithShifterOp 804 /// CHECK: DataProcWithShifterOp 805 /// CHECK: DataProcWithShifterOp 806 /// CHECK: DataProcWithShifterOp 807 /// CHECK: DataProcWithShifterOp 808 /// CHECK: DataProcWithShifterOp 809 /// CHECK: DataProcWithShifterOp 810 /// CHECK: DataProcWithShifterOp 811 /// CHECK: DataProcWithShifterOp 812 /// CHECK: DataProcWithShifterOp 813 /// CHECK: DataProcWithShifterOp 814 /// CHECK: DataProcWithShifterOp 815 /// CHECK: DataProcWithShifterOp 816 /// CHECK: DataProcWithShifterOp 817 /// CHECK: DataProcWithShifterOp 818 /// CHECK: DataProcWithShifterOp 819 /// CHECK: DataProcWithShifterOp 820 /// CHECK: DataProcWithShifterOp 821 /// CHECK: DataProcWithShifterOp 822 /// CHECK: DataProcWithShifterOp 823 /// CHECK: DataProcWithShifterOp 824 /// CHECK: DataProcWithShifterOp 825 /// CHECK: DataProcWithShifterOp 826 /// CHECK: DataProcWithShifterOp 827 /// CHECK: DataProcWithShifterOp 828 /// CHECK: DataProcWithShifterOp 829 /// CHECK: DataProcWithShifterOp 830 /// CHECK-NOT: DataProcWithShifterOp 831 832 /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after) 833 /// CHECK-NOT: Shl 834 /// CHECK-NOT: Shr 835 /// CHECK-NOT: UShr 836 837 public static void $opt$validateShiftInt(int a, int b) { 838 assertIntEquals(a + $noinline$IntShl(b, 1), a + (b << 1)); 839 assertIntEquals(a + $noinline$IntShl(b, 6), a + (b << 6)); 840 assertIntEquals(a + $noinline$IntShl(b, 7), a + (b << 7)); 841 assertIntEquals(a + $noinline$IntShl(b, 8), a + (b << 8)); 842 assertIntEquals(a + $noinline$IntShl(b, 14), a + (b << 14)); 843 assertIntEquals(a + $noinline$IntShl(b, 15), a + (b << 15)); 844 assertIntEquals(a + $noinline$IntShl(b, 16), a + (b << 16)); 845 assertIntEquals(a + $noinline$IntShl(b, 30), a + (b << 30)); 846 assertIntEquals(a + $noinline$IntShl(b, 31), a + (b << 31)); 847 assertIntEquals(a + $noinline$IntShl(b, 32), a + (b << $opt$inline$IntConstant32())); 848 assertIntEquals(a + $noinline$IntShl(b, 62), a + (b << $opt$inline$IntConstant62())); 849 assertIntEquals(a + $noinline$IntShl(b, 63), a + (b << $opt$inline$IntConstant63())); 850 851 assertIntEquals(a - $noinline$IntShr(b, 1), a - (b >> 1)); 852 assertIntEquals(a - $noinline$IntShr(b, 6), a - (b >> 6)); 853 assertIntEquals(a - $noinline$IntShr(b, 7), a - (b >> 7)); 854 assertIntEquals(a - $noinline$IntShr(b, 8), a - (b >> 8)); 855 assertIntEquals(a - $noinline$IntShr(b, 14), a - (b >> 14)); 856 assertIntEquals(a - $noinline$IntShr(b, 15), a - (b >> 15)); 857 assertIntEquals(a - $noinline$IntShr(b, 16), a - (b >> 16)); 858 assertIntEquals(a - $noinline$IntShr(b, 30), a - (b >> 30)); 859 assertIntEquals(a - $noinline$IntShr(b, 31), a - (b >> 31)); 860 assertIntEquals(a - $noinline$IntShr(b, 32), a - (b >> $opt$inline$IntConstant32())); 861 assertIntEquals(a - $noinline$IntShr(b, 62), a - (b >> $opt$inline$IntConstant62())); 862 assertIntEquals(a - $noinline$IntShr(b, 63), a - (b >> $opt$inline$IntConstant63())); 863 864 assertIntEquals(a ^ $noinline$IntUshr(b, 1), a ^ (b >>> 1)); 865 assertIntEquals(a ^ $noinline$IntUshr(b, 6), a ^ (b >>> 6)); 866 assertIntEquals(a ^ $noinline$IntUshr(b, 7), a ^ (b >>> 7)); 867 assertIntEquals(a ^ $noinline$IntUshr(b, 8), a ^ (b >>> 8)); 868 assertIntEquals(a ^ $noinline$IntUshr(b, 14), a ^ (b >>> 14)); 869 assertIntEquals(a ^ $noinline$IntUshr(b, 15), a ^ (b >>> 15)); 870 assertIntEquals(a ^ $noinline$IntUshr(b, 16), a ^ (b >>> 16)); 871 assertIntEquals(a ^ $noinline$IntUshr(b, 30), a ^ (b >>> 30)); 872 assertIntEquals(a ^ $noinline$IntUshr(b, 31), a ^ (b >>> 31)); 873 assertIntEquals(a ^ $noinline$IntUshr(b, 32), a ^ (b >>> $opt$inline$IntConstant32())); 874 assertIntEquals(a ^ $noinline$IntUshr(b, 62), a ^ (b >>> $opt$inline$IntConstant62())); 875 assertIntEquals(a ^ $noinline$IntUshr(b, 63), a ^ (b >>> $opt$inline$IntConstant63())); 876 } 877 878 // Hiding constants outside the range [0, 32) used for int shifts from Jack. 879 // (Jack extracts only the low 5 bits.) 880 public static int $opt$inline$IntConstant32() { return 32; } 881 public static int $opt$inline$IntConstant62() { return 62; } 882 public static int $opt$inline$IntConstant63() { return 63; } 883 884 885 static long $noinline$LongShl(long b, long c) { 886 if (doThrow) throw new Error(); 887 return b << c; 888 } 889 static long $noinline$LongShr(long b, long c) { 890 if (doThrow) throw new Error(); 891 return b >> c; 892 } 893 static long $noinline$LongUshr(long b, long c) { 894 if (doThrow) throw new Error(); 895 return b >>> c; 896 } 897 898 // Each test line below should see one merge. 899 /// CHECK-START-ARM: long[] Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after) 900 /// CHECK: DataProcWithShifterOp 901 /// CHECK: DataProcWithShifterOp 902 /// CHECK: DataProcWithShifterOp 903 /// CHECK: DataProcWithShifterOp 904 /// CHECK: DataProcWithShifterOp 905 /// CHECK: DataProcWithShifterOp 906 /// CHECK: DataProcWithShifterOp 907 /// CHECK: DataProcWithShifterOp 908 /// CHECK: DataProcWithShifterOp 909 /// CHECK: DataProcWithShifterOp 910 /// CHECK: DataProcWithShifterOp 911 /// CHECK: DataProcWithShifterOp 912 /// CHECK: DataProcWithShifterOp 913 /// CHECK: DataProcWithShifterOp 914 /// CHECK: DataProcWithShifterOp 915 /// CHECK: DataProcWithShifterOp 916 /// CHECK: DataProcWithShifterOp 917 /// CHECK: DataProcWithShifterOp 918 /// CHECK: DataProcWithShifterOp 919 /// CHECK: DataProcWithShifterOp 920 /// CHECK: DataProcWithShifterOp 921 /// CHECK: DataProcWithShifterOp 922 /// CHECK: DataProcWithShifterOp 923 /// CHECK: DataProcWithShifterOp 924 /// CHECK: DataProcWithShifterOp 925 /// CHECK: DataProcWithShifterOp 926 /// CHECK: DataProcWithShifterOp 927 /// CHECK: DataProcWithShifterOp 928 /// CHECK: DataProcWithShifterOp 929 /// CHECK: DataProcWithShifterOp 930 /// CHECK: DataProcWithShifterOp 931 /// CHECK: DataProcWithShifterOp 932 /// CHECK: DataProcWithShifterOp 933 /// CHECK-NOT: DataProcWithShifterOp 934 935 // On ARM shifts by 1 are not merged. 936 /// CHECK-START-ARM: long[] Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after) 937 /// CHECK: Shl 938 /// CHECK-NOT: Shl 939 /// CHECK: Shr 940 /// CHECK-NOT: Shr 941 /// CHECK: UShr 942 /// CHECK-NOT: UShr 943 944 /// CHECK-START-ARM64: long[] Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after) 945 /// CHECK: DataProcWithShifterOp 946 /// CHECK: DataProcWithShifterOp 947 /// CHECK: DataProcWithShifterOp 948 /// CHECK: DataProcWithShifterOp 949 /// CHECK: DataProcWithShifterOp 950 /// CHECK: DataProcWithShifterOp 951 /// CHECK: DataProcWithShifterOp 952 /// CHECK: DataProcWithShifterOp 953 /// CHECK: DataProcWithShifterOp 954 /// CHECK: DataProcWithShifterOp 955 /// CHECK: DataProcWithShifterOp 956 /// CHECK: DataProcWithShifterOp 957 /// CHECK: DataProcWithShifterOp 958 /// CHECK: DataProcWithShifterOp 959 /// CHECK: DataProcWithShifterOp 960 /// CHECK: DataProcWithShifterOp 961 /// CHECK: DataProcWithShifterOp 962 /// CHECK: DataProcWithShifterOp 963 /// CHECK: DataProcWithShifterOp 964 /// CHECK: DataProcWithShifterOp 965 /// CHECK: DataProcWithShifterOp 966 /// CHECK: DataProcWithShifterOp 967 /// CHECK: DataProcWithShifterOp 968 /// CHECK: DataProcWithShifterOp 969 /// CHECK: DataProcWithShifterOp 970 /// CHECK: DataProcWithShifterOp 971 /// CHECK: DataProcWithShifterOp 972 /// CHECK: DataProcWithShifterOp 973 /// CHECK: DataProcWithShifterOp 974 /// CHECK: DataProcWithShifterOp 975 /// CHECK: DataProcWithShifterOp 976 /// CHECK: DataProcWithShifterOp 977 /// CHECK: DataProcWithShifterOp 978 /// CHECK: DataProcWithShifterOp 979 /// CHECK: DataProcWithShifterOp 980 /// CHECK: DataProcWithShifterOp 981 /// CHECK-NOT: DataProcWithShifterOp 982 983 /// CHECK-START-ARM64: long[] Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after) 984 /// CHECK-NOT: Shl 985 /// CHECK-NOT: Shr 986 /// CHECK-NOT: UShr 987 988 public static long[] $opt$validateShiftLong(long a, long b) { 989 long[] results = new long[36]; 990 991 results[0] = a + (b << 1); 992 results[1] = a + (b << 6); 993 results[2] = a + (b << 7); 994 results[3] = a + (b << 8); 995 results[4] = a + (b << 14); 996 results[5] = a + (b << 15); 997 results[6] = a + (b << 16); 998 results[7] = a + (b << 30); 999 results[8] = a + (b << 31); 1000 results[9] = a + (b << 32); 1001 results[10] = a + (b << 62); 1002 results[11] = a + (b << 63); 1003 1004 results[12] = a - (b >> 1); 1005 results[13] = a - (b >> 6); 1006 results[14] = a - (b >> 7); 1007 results[15] = a - (b >> 8); 1008 results[16] = a - (b >> 14); 1009 results[17] = a - (b >> 15); 1010 results[18] = a - (b >> 16); 1011 results[19] = a - (b >> 30); 1012 results[20] = a - (b >> 31); 1013 results[21] = a - (b >> 32); 1014 results[22] = a - (b >> 62); 1015 results[23] = a - (b >> 63); 1016 1017 results[24] = a ^ (b >>> 1); 1018 results[25] = a ^ (b >>> 6); 1019 results[26] = a ^ (b >>> 7); 1020 results[27] = a ^ (b >>> 8); 1021 results[28] = a ^ (b >>> 14); 1022 results[29] = a ^ (b >>> 15); 1023 results[30] = a ^ (b >>> 16); 1024 results[31] = a ^ (b >>> 30); 1025 results[32] = a ^ (b >>> 31); 1026 results[33] = a ^ (b >>> 32); 1027 results[34] = a ^ (b >>> 62); 1028 results[35] = a ^ (b >>> 63); 1029 1030 return results; 1031 } 1032 1033 public static void $opt$validateShiftLongAsserts(long a, long b) { 1034 long[] results = $opt$validateShiftLong(a, b); 1035 assertIntEquals(3 * 12, results.length); 1036 1037 assertLongEquals(a + $noinline$LongShl(b, 1), results[0]); 1038 assertLongEquals(a + $noinline$LongShl(b, 6), results[1]); 1039 assertLongEquals(a + $noinline$LongShl(b, 7), results[2]); 1040 assertLongEquals(a + $noinline$LongShl(b, 8), results[3]); 1041 assertLongEquals(a + $noinline$LongShl(b, 14), results[4]); 1042 assertLongEquals(a + $noinline$LongShl(b, 15), results[5]); 1043 assertLongEquals(a + $noinline$LongShl(b, 16), results[6]); 1044 assertLongEquals(a + $noinline$LongShl(b, 30), results[7]); 1045 assertLongEquals(a + $noinline$LongShl(b, 31), results[8]); 1046 assertLongEquals(a + $noinline$LongShl(b, 32), results[9]); 1047 assertLongEquals(a + $noinline$LongShl(b, 62), results[10]); 1048 assertLongEquals(a + $noinline$LongShl(b, 63), results[11]); 1049 1050 assertLongEquals(a - $noinline$LongShr(b, 1), results[12]); 1051 assertLongEquals(a - $noinline$LongShr(b, 6), results[13]); 1052 assertLongEquals(a - $noinline$LongShr(b, 7), results[14]); 1053 assertLongEquals(a - $noinline$LongShr(b, 8), results[15]); 1054 assertLongEquals(a - $noinline$LongShr(b, 14), results[16]); 1055 assertLongEquals(a - $noinline$LongShr(b, 15), results[17]); 1056 assertLongEquals(a - $noinline$LongShr(b, 16), results[18]); 1057 assertLongEquals(a - $noinline$LongShr(b, 30), results[19]); 1058 assertLongEquals(a - $noinline$LongShr(b, 31), results[20]); 1059 assertLongEquals(a - $noinline$LongShr(b, 32), results[21]); 1060 assertLongEquals(a - $noinline$LongShr(b, 62), results[22]); 1061 assertLongEquals(a - $noinline$LongShr(b, 63), results[23]); 1062 1063 assertLongEquals(a ^ $noinline$LongUshr(b, 1), results[24]); 1064 assertLongEquals(a ^ $noinline$LongUshr(b, 6), results[25]); 1065 assertLongEquals(a ^ $noinline$LongUshr(b, 7), results[26]); 1066 assertLongEquals(a ^ $noinline$LongUshr(b, 8), results[27]); 1067 assertLongEquals(a ^ $noinline$LongUshr(b, 14), results[28]); 1068 assertLongEquals(a ^ $noinline$LongUshr(b, 15), results[29]); 1069 assertLongEquals(a ^ $noinline$LongUshr(b, 16), results[30]); 1070 assertLongEquals(a ^ $noinline$LongUshr(b, 30), results[31]); 1071 assertLongEquals(a ^ $noinline$LongUshr(b, 31), results[32]); 1072 assertLongEquals(a ^ $noinline$LongUshr(b, 32), results[33]); 1073 assertLongEquals(a ^ $noinline$LongUshr(b, 62), results[34]); 1074 assertLongEquals(a ^ $noinline$LongUshr(b, 63), results[35]); 1075 } 1076 1077 1078 public static void main(String[] args) { 1079 assertLongEquals(10000L - 3L, $opt$noinline$translate(10000L, (byte)3)); 1080 assertLongEquals(-10000L - -3L, $opt$noinline$translate(-10000L, (byte)-3)); 1081 1082 assertIntEquals(4096, $opt$noinline$sameInput(512)); 1083 assertIntEquals(-8192, $opt$noinline$sameInput(-1024)); 1084 1085 assertIntEquals(((1 << 23) | 1), $opt$noinline$multipleUses(1)); 1086 assertIntEquals(((1 << 20) | 5), $opt$noinline$multipleUses(1 << 20)); 1087 1088 long inputs[] = { 1089 -((1L << 7) - 1L), -((1L << 7)), -((1L << 7) + 1L), 1090 -((1L << 15) - 1L), -((1L << 15)), -((1L << 15) + 1L), 1091 -((1L << 16) - 1L), -((1L << 16)), -((1L << 16) + 1L), 1092 -((1L << 31) - 1L), -((1L << 31)), -((1L << 31) + 1L), 1093 -((1L << 32) - 1L), -((1L << 32)), -((1L << 32) + 1L), 1094 -((1L << 63) - 1L), -((1L << 63)), -((1L << 63) + 1L), 1095 -42L, -314L, -2718281828L, -0x123456789L, -0x987654321L, 1096 -1L, -20L, -300L, -4000L, -50000L, -600000L, -7000000L, -80000000L, 1097 0L, 1098 1L, 20L, 300L, 4000L, 50000L, 600000L, 7000000L, 80000000L, 1099 42L, 314L, 2718281828L, 0x123456789L, 0x987654321L, 1100 (1L << 7) - 1L, (1L << 7), (1L << 7) + 1L, 1101 (1L << 8) - 1L, (1L << 8), (1L << 8) + 1L, 1102 (1L << 15) - 1L, (1L << 15), (1L << 15) + 1L, 1103 (1L << 16) - 1L, (1L << 16), (1L << 16) + 1L, 1104 (1L << 31) - 1L, (1L << 31), (1L << 31) + 1L, 1105 (1L << 32) - 1L, (1L << 32), (1L << 32) + 1L, 1106 (1L << 63) - 1L, (1L << 63), (1L << 63) + 1L, 1107 Long.MIN_VALUE, Long.MAX_VALUE 1108 }; 1109 for (int i = 0; i < inputs.length; i++) { 1110 $opt$noinline$testNeg((int)inputs[i]); 1111 for (int j = 0; j < inputs.length; j++) { 1112 $opt$noinline$testAnd(inputs[i], inputs[j]); 1113 $opt$noinline$testOr((int)inputs[i], (int)inputs[j]); 1114 $opt$noinline$testXor(inputs[i], inputs[j]); 1115 1116 $opt$validateExtendByte(inputs[i], (byte)inputs[j]); 1117 $opt$validateExtendChar(inputs[i], (char)inputs[j]); 1118 $opt$validateExtendShort(inputs[i], (short)inputs[j]); 1119 $opt$validateExtendInt(inputs[i], (int)inputs[j]); 1120 $opt$validateExtendLong(inputs[i], inputs[j]); 1121 1122 $opt$validateShiftInt((int)inputs[i], (int)inputs[j]); 1123 $opt$validateShiftLongAsserts(inputs[i], inputs[j]); 1124 } 1125 } 1126 1127 } 1128 } 1129