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 assertByteEquals(byte expected, byte result)22 public static void assertByteEquals(byte expected, byte result) { 23 if (expected != result) { 24 throw new Error("Expected: " + expected + ", found: " + result); 25 } 26 } 27 assertCharEquals(char expected, char result)28 public static void assertCharEquals(char expected, char result) { 29 if (expected != result) { 30 throw new Error("Expected: " + expected + ", found: " + result); 31 } 32 } 33 assertShortEquals(short expected, short result)34 public static void assertShortEquals(short expected, short result) { 35 if (expected != result) { 36 throw new Error("Expected: " + expected + ", found: " + result); 37 } 38 } 39 assertIntEquals(int expected, int result)40 public static void assertIntEquals(int expected, int result) { 41 if (expected != result) { 42 throw new Error("Expected: " + expected + ", found: " + result); 43 } 44 } 45 assertLongEquals(long expected, long result)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. $noinline$byteToChar(byte v)53 static char $noinline$byteToChar (byte v) { if (doThrow) throw new Error(); return (char)v; } $noinline$byteToShort(byte v)54 static short $noinline$byteToShort (byte v) { if (doThrow) throw new Error(); return (short)v; } $noinline$byteToInt(byte v)55 static int $noinline$byteToInt (byte v) { if (doThrow) throw new Error(); return (int)v; } $noinline$byteToLong(byte v)56 static long $noinline$byteToLong (byte v) { if (doThrow) throw new Error(); return (long)v; } $noinline$charToByte(char v)57 static byte $noinline$charToByte (char v) { if (doThrow) throw new Error(); return (byte)v; } $noinline$charToShort(char v)58 static short $noinline$charToShort (char v) { if (doThrow) throw new Error(); return (short)v; } $noinline$charToInt(char v)59 static int $noinline$charToInt (char v) { if (doThrow) throw new Error(); return (int)v; } $noinline$charToLong(char v)60 static long $noinline$charToLong (char v) { if (doThrow) throw new Error(); return (long)v; } $noinline$shortToByte(short v)61 static byte $noinline$shortToByte (short v) { if (doThrow) throw new Error(); return (byte)v; } $noinline$shortToChar(short v)62 static char $noinline$shortToChar (short v) { if (doThrow) throw new Error(); return (char)v; } $noinline$shortToInt(short v)63 static int $noinline$shortToInt (short v) { if (doThrow) throw new Error(); return (int)v; } $noinline$shortToLong(short v)64 static long $noinline$shortToLong (short v) { if (doThrow) throw new Error(); return (long)v; } $noinline$intToByte(int v)65 static byte $noinline$intToByte (int v) { if (doThrow) throw new Error(); return (byte)v; } $noinline$intToChar(int v)66 static char $noinline$intToChar (int v) { if (doThrow) throw new Error(); return (char)v; } $noinline$intToShort(int v)67 static short $noinline$intToShort (int v) { if (doThrow) throw new Error(); return (short)v; } $noinline$intToLong(int v)68 static long $noinline$intToLong (int v) { if (doThrow) throw new Error(); return (long)v; } $noinline$longToByte(long v)69 static byte $noinline$longToByte (long v) { if (doThrow) throw new Error(); return (byte)v; } $noinline$longToChar(long v)70 static char $noinline$longToChar (long v) { if (doThrow) throw new Error(); return (char)v; } $noinline$longToShort(long v)71 static short $noinline$longToShort (long v) { if (doThrow) throw new Error(); return (short)v; } $noinline$longToInt(long 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 $opt$noinline$translate(long l, byte b)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 $opt$noinline$sameInput(int a)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 $opt$noinline$multipleUses(int arg)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 238 /// CHECK: and 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 $opt$noinline$testAnd(long a, long b)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 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 $opt$noinline$testOr(int a, int b)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: mov 286 /// CHECK: asr 287 /// CHECK: eor 288 289 /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) instruction_simplifier_arm64 (after) 290 /// CHECK: DataProcWithShifterOp 291 /// CHECK-NOT: DataProcWithShifterOp 292 293 /// CHECK-START-ARM64: void Main.$opt$noinline$testXor(long, long) disassembly (after) 294 /// CHECK: eor lsr 295 /// CHECK: sxtw 296 /// CHECK: eor 297 $opt$noinline$testXor(long a, long b)298 static void $opt$noinline$testXor(long a, long b) { 299 if (doThrow) throw new Error(); 300 assertLongEquals((a ^ $noinline$LongUshr(b, 7)) | (a ^ $noinline$longToInt(b)), 301 (a ^ (b >>> 7)) | (a ^ (int)b)); 302 } 303 304 /// CHECK-START-ARM: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm (after) 305 /// CHECK-NOT: DataProcWithShifterOp 306 307 /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) instruction_simplifier_arm64 (after) 308 /// CHECK: DataProcWithShifterOp 309 /// CHECK-NOT: DataProcWithShifterOp 310 311 /// CHECK-START-ARM64: void Main.$opt$noinline$testNeg(int) disassembly (after) 312 /// CHECK: neg lsl 313 /// CHECK: sxth 314 /// CHECK: neg 315 $opt$noinline$testNeg(int a)316 static void $opt$noinline$testNeg(int a) { 317 if (doThrow) throw new Error(); 318 assertIntEquals(-$noinline$IntShl(a, 8) | -$noinline$intToShort(a), 319 (-(a << 8)) | (-(short)a)); 320 } 321 322 /** 323 * The functions below are used to compare the result of optimized operations 324 * to non-optimized operations. 325 * On the left-hand side we use a non-inlined function call to ensure the 326 * optimization does not occur. The checker tests ensure that the optimization 327 * does occur on the right-hand. 328 */ 329 330 /// CHECK-START-ARM: void Main.$opt$validateExtendByteInt1(int, byte) instruction_simplifier_arm (after) 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 $opt$validateExtendByteInt1(int a, byte b)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 $opt$validateExtendByteInt2(int a, byte b)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 $opt$validateExtendByteLong(long a, byte b)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 $opt$validateExtendByte(long a, byte b)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-NOT: DataProcWithShifterOp 404 405 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after) 406 /// CHECK: DataProcWithShifterOp 407 /// CHECK: DataProcWithShifterOp 408 409 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt1(int, char) instruction_simplifier_arm64 (after) 410 /// CHECK-NOT: TypeConversion 411 $opt$validateExtendCharInt1(int a, char b)412 public static void $opt$validateExtendCharInt1(int a, char b) { 413 assertIntEquals(a + $noinline$charToByte (b), a + (byte)b); 414 assertIntEquals(a + $noinline$charToShort(b), a + (short)b); 415 } 416 417 /// CHECK-START-ARM: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm (after) 418 /// CHECK-NOT: DataProcWithShifterOp 419 420 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharInt2(int, char) instruction_simplifier_arm64 (after) 421 /// CHECK-NOT: DataProcWithShifterOp 422 $opt$validateExtendCharInt2(int a, char b)423 public static void $opt$validateExtendCharInt2(int a, char b) { 424 // The conversion to `int` has been optimized away, so there is nothing to merge. 425 assertIntEquals (a + $noinline$charToInt (b), a + (int)b); 426 // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge. 427 assertLongEquals(a + $noinline$charToLong(b), a + (long)b); 428 } 429 430 /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after) 431 /// CHECK: DataProcWithShifterOp 432 /// CHECK: DataProcWithShifterOp 433 /// CHECK: DataProcWithShifterOp 434 /// CHECK: DataProcWithShifterOp 435 /// CHECK: DataProcWithShifterOp 436 /// CHECK: DataProcWithShifterOp 437 /// CHECK-NOT: DataProcWithShifterOp 438 439 /// CHECK-START-ARM: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm (after) 440 /// CHECK: TypeConversion 441 /// CHECK: TypeConversion 442 /// CHECK-NOT: TypeConversion 443 444 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after) 445 /// CHECK: DataProcWithShifterOp 446 /// CHECK: DataProcWithShifterOp 447 /// CHECK: DataProcWithShifterOp 448 /// CHECK: DataProcWithShifterOp 449 /// CHECK: DataProcWithShifterOp 450 /// CHECK: DataProcWithShifterOp 451 /// CHECK-NOT: DataProcWithShifterOp 452 453 /// CHECK-START-ARM64: void Main.$opt$validateExtendCharLong(long, char) instruction_simplifier_arm64 (after) 454 /// CHECK: TypeConversion 455 /// CHECK: TypeConversion 456 /// CHECK-NOT: TypeConversion 457 $opt$validateExtendCharLong(long a, char b)458 public static void $opt$validateExtendCharLong(long a, char b) { 459 // The first two tests have a type conversion. 460 assertLongEquals(a + $noinline$charToByte (b), a + (byte)b); 461 assertLongEquals(a + $noinline$charToShort(b), a + (short)b); 462 // On ARM64 this test does not because the conversion to `int` is optimized away. 463 assertLongEquals(a + $noinline$charToInt (b), a + (int)b); 464 } 465 $opt$validateExtendChar(long a, char b)466 public static void $opt$validateExtendChar(long a, char b) { 467 $opt$validateExtendCharInt1((int)a, b); 468 $opt$validateExtendCharInt2((int)a, b); 469 $opt$validateExtendCharLong(a, b); 470 } 471 472 /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm (after) 473 /// CHECK-NOT: DataProcWithShifterOp 474 475 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after) 476 /// CHECK: DataProcWithShifterOp 477 /// CHECK: DataProcWithShifterOp 478 479 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt1(int, short) instruction_simplifier_arm64 (after) 480 /// CHECK-NOT: TypeConversion 481 $opt$validateExtendShortInt1(int a, short b)482 public static void $opt$validateExtendShortInt1(int a, short b) { 483 assertIntEquals(a + $noinline$shortToByte (b), a + (byte)b); 484 assertIntEquals(a + $noinline$shortToChar (b), a + (char)b); 485 } 486 487 /// CHECK-START-ARM: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm (after) 488 /// CHECK-NOT: DataProcWithShifterOp 489 490 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortInt2(int, short) instruction_simplifier_arm64 (after) 491 /// CHECK-NOT: DataProcWithShifterOp 492 $opt$validateExtendShortInt2(int a, short b)493 public static void $opt$validateExtendShortInt2(int a, short b) { 494 // The conversion to `int` has been optimized away, so there is nothing to merge. 495 assertIntEquals (a + $noinline$shortToInt (b), a + (int)b); 496 // There is an environment use for `(long)b` and the implicit `(long)a`, preventing the merge. 497 assertLongEquals(a + $noinline$shortToLong (b), a + (long)b); 498 } 499 500 /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after) 501 /// CHECK: DataProcWithShifterOp 502 /// CHECK: DataProcWithShifterOp 503 /// CHECK: DataProcWithShifterOp 504 /// CHECK: DataProcWithShifterOp 505 /// CHECK: DataProcWithShifterOp 506 /// CHECK: DataProcWithShifterOp 507 /// CHECK-NOT: DataProcWithShifterOp 508 509 /// CHECK-START-ARM: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm (after) 510 /// CHECK: TypeConversion 511 /// CHECK: TypeConversion 512 /// CHECK-NOT: TypeConversion 513 514 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after) 515 /// CHECK: DataProcWithShifterOp 516 /// CHECK: DataProcWithShifterOp 517 /// CHECK: DataProcWithShifterOp 518 /// CHECK: DataProcWithShifterOp 519 /// CHECK: DataProcWithShifterOp 520 /// CHECK: DataProcWithShifterOp 521 /// CHECK-NOT: DataProcWithShifterOp 522 523 /// CHECK-START-ARM64: void Main.$opt$validateExtendShortLong(long, short) instruction_simplifier_arm64 (after) 524 /// CHECK: TypeConversion 525 /// CHECK: TypeConversion 526 /// CHECK-NOT: TypeConversion 527 $opt$validateExtendShortLong(long a, short b)528 public static void $opt$validateExtendShortLong(long a, short b) { 529 // The first two tests have a type conversion. 530 assertLongEquals(a + $noinline$shortToByte(b), a + (byte)b); 531 assertLongEquals(a + $noinline$shortToChar(b), a + (char)b); 532 // On ARM64 this test does not because the conversion to `int` is optimized away. 533 assertLongEquals(a + $noinline$shortToInt (b), a + (int)b); 534 } 535 $opt$validateExtendShort(long a, short b)536 public static void $opt$validateExtendShort(long a, short b) { 537 $opt$validateExtendShortInt1((int)a, b); 538 $opt$validateExtendShortInt2((int)a, b); 539 $opt$validateExtendShortLong(a, b); 540 } 541 542 /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after) 543 /// CHECK: DataProcWithShifterOp 544 /// CHECK: DataProcWithShifterOp 545 /// CHECK: DataProcWithShifterOp 546 /// CHECK: DataProcWithShifterOp 547 /// CHECK: DataProcWithShifterOp 548 /// CHECK: DataProcWithShifterOp 549 /// CHECK: DataProcWithShifterOp 550 /// CHECK-NOT: DataProcWithShifterOp 551 552 /// CHECK-START-ARM: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm (after) 553 /// CHECK: TypeConversion 554 /// CHECK: TypeConversion 555 /// CHECK: TypeConversion 556 /// CHECK-NOT: TypeConversion 557 558 /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after) 559 /// CHECK: DataProcWithShifterOp 560 /// CHECK: DataProcWithShifterOp 561 /// CHECK: DataProcWithShifterOp 562 /// CHECK: DataProcWithShifterOp 563 /// CHECK: DataProcWithShifterOp 564 /// CHECK: DataProcWithShifterOp 565 /// CHECK: DataProcWithShifterOp 566 /// CHECK-NOT: DataProcWithShifterOp 567 568 /// CHECK-START-ARM64: void Main.$opt$validateExtendInt(long, int) instruction_simplifier_arm64 (after) 569 /// CHECK: TypeConversion 570 /// CHECK: TypeConversion 571 /// CHECK: TypeConversion 572 /// CHECK-NOT: TypeConversion 573 $opt$validateExtendInt(long a, int b)574 public static void $opt$validateExtendInt(long a, int b) { 575 // All tests have a conversion to `long`. The first three tests also have a 576 // conversion from `int` to the specified type. For each test the conversion 577 // to `long` is merged into the shifter operand. 578 assertLongEquals(a + $noinline$intToByte (b), a + (byte)b); 579 assertLongEquals(a + $noinline$intToChar (b), a + (char)b); 580 assertLongEquals(a + $noinline$intToShort(b), a + (short)b); 581 assertLongEquals(a + $noinline$intToLong (b), a + (long)b); 582 } 583 584 /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after) 585 /// CHECK: DataProcWithShifterOp 586 /// CHECK: DataProcWithShifterOp 587 /// CHECK: DataProcWithShifterOp 588 /// CHECK: DataProcWithShifterOp 589 /// CHECK: DataProcWithShifterOp 590 /// CHECK: DataProcWithShifterOp 591 /// CHECK: DataProcWithShifterOp 592 /// CHECK: DataProcWithShifterOp 593 /// CHECK-NOT: DataProcWithShifterOp 594 595 /// CHECK-START-ARM: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm (after) 596 /// CHECK: TypeConversion 597 /// CHECK: TypeConversion 598 /// CHECK: TypeConversion 599 /// CHECK: TypeConversion 600 /// CHECK-NOT: TypeConversion 601 602 /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after) 603 /// CHECK: DataProcWithShifterOp 604 /// CHECK: DataProcWithShifterOp 605 /// CHECK: DataProcWithShifterOp 606 /// CHECK: DataProcWithShifterOp 607 /// CHECK: DataProcWithShifterOp 608 /// CHECK: DataProcWithShifterOp 609 /// CHECK: DataProcWithShifterOp 610 /// CHECK: DataProcWithShifterOp 611 /// CHECK-NOT: DataProcWithShifterOp 612 613 /// CHECK-START-ARM64: void Main.$opt$validateExtendLong(long, long) instruction_simplifier_arm64 (after) 614 /// CHECK: TypeConversion 615 /// CHECK: TypeConversion 616 /// CHECK: TypeConversion 617 /// CHECK: TypeConversion 618 /// CHECK-NOT: TypeConversion 619 $opt$validateExtendLong(long a, long b)620 public static void $opt$validateExtendLong(long a, long b) { 621 // Each test has two conversions, from `long` and then back to `long`. The 622 // conversions to `long` are merged. 623 assertLongEquals(a + $noinline$longToByte (b), a + (byte)b); 624 assertLongEquals(a + $noinline$longToChar (b), a + (char)b); 625 assertLongEquals(a + $noinline$longToShort(b), a + (short)b); 626 assertLongEquals(a + $noinline$longToInt (b), a + (int)b); 627 } 628 629 $noinline$IntShl(int b, int c)630 static int $noinline$IntShl(int b, int c) { 631 if (doThrow) throw new Error(); 632 return b << c; 633 } $noinline$IntShr(int b, int c)634 static int $noinline$IntShr(int b, int c) { 635 if (doThrow) throw new Error(); 636 return b >> c; 637 } $noinline$IntUshr(int b, int c)638 static int $noinline$IntUshr(int b, int c) { 639 if (doThrow) throw new Error(); 640 return b >>> c; 641 } 642 643 644 // Each test line below should see one merge. 645 /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after) 646 /// CHECK: DataProcWithShifterOp 647 /// CHECK: DataProcWithShifterOp 648 /// CHECK: DataProcWithShifterOp 649 /// CHECK: DataProcWithShifterOp 650 /// CHECK: DataProcWithShifterOp 651 /// CHECK: DataProcWithShifterOp 652 /// CHECK: DataProcWithShifterOp 653 /// CHECK: DataProcWithShifterOp 654 /// CHECK: DataProcWithShifterOp 655 /// CHECK: DataProcWithShifterOp 656 /// CHECK: DataProcWithShifterOp 657 /// CHECK: DataProcWithShifterOp 658 /// CHECK: DataProcWithShifterOp 659 /// CHECK: DataProcWithShifterOp 660 /// CHECK: DataProcWithShifterOp 661 /// CHECK: DataProcWithShifterOp 662 /// CHECK: DataProcWithShifterOp 663 /// CHECK: DataProcWithShifterOp 664 /// CHECK: DataProcWithShifterOp 665 /// CHECK: DataProcWithShifterOp 666 /// CHECK: DataProcWithShifterOp 667 /// CHECK: DataProcWithShifterOp 668 /// CHECK: DataProcWithShifterOp 669 /// CHECK: DataProcWithShifterOp 670 /// CHECK: DataProcWithShifterOp 671 /// CHECK: DataProcWithShifterOp 672 /// CHECK: DataProcWithShifterOp 673 /// CHECK: DataProcWithShifterOp 674 /// CHECK: DataProcWithShifterOp 675 /// CHECK: DataProcWithShifterOp 676 /// CHECK: DataProcWithShifterOp 677 /// CHECK: DataProcWithShifterOp 678 /// CHECK: DataProcWithShifterOp 679 /// CHECK-NOT: DataProcWithShifterOp 680 // Note: `b << 32`, `b >> 32` and `b >>> 32` are optimized away by generic simplifier. 681 682 /// CHECK-START-ARM: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm (after) 683 /// CHECK-NOT: Shl 684 /// CHECK-NOT: Shr 685 /// CHECK-NOT: UShr 686 687 /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after) 688 /// CHECK: DataProcWithShifterOp 689 /// CHECK: DataProcWithShifterOp 690 /// CHECK: DataProcWithShifterOp 691 /// CHECK: DataProcWithShifterOp 692 /// CHECK: DataProcWithShifterOp 693 /// CHECK: DataProcWithShifterOp 694 /// CHECK: DataProcWithShifterOp 695 /// CHECK: DataProcWithShifterOp 696 /// CHECK: DataProcWithShifterOp 697 /// CHECK: DataProcWithShifterOp 698 /// CHECK: DataProcWithShifterOp 699 /// CHECK: DataProcWithShifterOp 700 /// CHECK: DataProcWithShifterOp 701 /// CHECK: DataProcWithShifterOp 702 /// CHECK: DataProcWithShifterOp 703 /// CHECK: DataProcWithShifterOp 704 /// CHECK: DataProcWithShifterOp 705 /// CHECK: DataProcWithShifterOp 706 /// CHECK: DataProcWithShifterOp 707 /// CHECK: DataProcWithShifterOp 708 /// CHECK: DataProcWithShifterOp 709 /// CHECK: DataProcWithShifterOp 710 /// CHECK: DataProcWithShifterOp 711 /// CHECK: DataProcWithShifterOp 712 /// CHECK: DataProcWithShifterOp 713 /// CHECK: DataProcWithShifterOp 714 /// CHECK: DataProcWithShifterOp 715 /// CHECK: DataProcWithShifterOp 716 /// CHECK: DataProcWithShifterOp 717 /// CHECK: DataProcWithShifterOp 718 /// CHECK: DataProcWithShifterOp 719 /// CHECK: DataProcWithShifterOp 720 /// CHECK: DataProcWithShifterOp 721 /// CHECK-NOT: DataProcWithShifterOp 722 // Note: `b << 32`, `b >> 32` and `b >>> 32` are optimized away by generic simplifier. 723 724 /// CHECK-START-ARM64: void Main.$opt$validateShiftInt(int, int) instruction_simplifier_arm64 (after) 725 /// CHECK-NOT: Shl 726 /// CHECK-NOT: Shr 727 /// CHECK-NOT: UShr 728 $opt$validateShiftInt(int a, int b)729 public static void $opt$validateShiftInt(int a, int b) { 730 assertIntEquals(a + $noinline$IntShl(b, 1), a + (b << 1)); 731 assertIntEquals(a + $noinline$IntShl(b, 6), a + (b << 6)); 732 assertIntEquals(a + $noinline$IntShl(b, 7), a + (b << 7)); 733 assertIntEquals(a + $noinline$IntShl(b, 8), a + (b << 8)); 734 assertIntEquals(a + $noinline$IntShl(b, 14), a + (b << 14)); 735 assertIntEquals(a + $noinline$IntShl(b, 15), a + (b << 15)); 736 assertIntEquals(a + $noinline$IntShl(b, 16), a + (b << 16)); 737 assertIntEquals(a + $noinline$IntShl(b, 30), a + (b << 30)); 738 assertIntEquals(a + $noinline$IntShl(b, 31), a + (b << 31)); 739 assertIntEquals(a + $noinline$IntShl(b, 32), a + (b << $opt$inline$IntConstant32())); 740 assertIntEquals(a + $noinline$IntShl(b, 62), a + (b << $opt$inline$IntConstant62())); 741 assertIntEquals(a + $noinline$IntShl(b, 63), a + (b << $opt$inline$IntConstant63())); 742 743 assertIntEquals(a - $noinline$IntShr(b, 1), a - (b >> 1)); 744 assertIntEquals(a - $noinline$IntShr(b, 6), a - (b >> 6)); 745 assertIntEquals(a - $noinline$IntShr(b, 7), a - (b >> 7)); 746 assertIntEquals(a - $noinline$IntShr(b, 8), a - (b >> 8)); 747 assertIntEquals(a - $noinline$IntShr(b, 14), a - (b >> 14)); 748 assertIntEquals(a - $noinline$IntShr(b, 15), a - (b >> 15)); 749 assertIntEquals(a - $noinline$IntShr(b, 16), a - (b >> 16)); 750 assertIntEquals(a - $noinline$IntShr(b, 30), a - (b >> 30)); 751 assertIntEquals(a - $noinline$IntShr(b, 31), a - (b >> 31)); 752 assertIntEquals(a - $noinline$IntShr(b, 32), a - (b >> $opt$inline$IntConstant32())); 753 assertIntEquals(a - $noinline$IntShr(b, 62), a - (b >> $opt$inline$IntConstant62())); 754 assertIntEquals(a - $noinline$IntShr(b, 63), a - (b >> $opt$inline$IntConstant63())); 755 756 assertIntEquals(a ^ $noinline$IntUshr(b, 1), a ^ (b >>> 1)); 757 assertIntEquals(a ^ $noinline$IntUshr(b, 6), a ^ (b >>> 6)); 758 assertIntEquals(a ^ $noinline$IntUshr(b, 7), a ^ (b >>> 7)); 759 assertIntEquals(a ^ $noinline$IntUshr(b, 8), a ^ (b >>> 8)); 760 assertIntEquals(a ^ $noinline$IntUshr(b, 14), a ^ (b >>> 14)); 761 assertIntEquals(a ^ $noinline$IntUshr(b, 15), a ^ (b >>> 15)); 762 assertIntEquals(a ^ $noinline$IntUshr(b, 16), a ^ (b >>> 16)); 763 assertIntEquals(a ^ $noinline$IntUshr(b, 30), a ^ (b >>> 30)); 764 assertIntEquals(a ^ $noinline$IntUshr(b, 31), a ^ (b >>> 31)); 765 assertIntEquals(a ^ $noinline$IntUshr(b, 32), a ^ (b >>> $opt$inline$IntConstant32())); 766 assertIntEquals(a ^ $noinline$IntUshr(b, 62), a ^ (b >>> $opt$inline$IntConstant62())); 767 assertIntEquals(a ^ $noinline$IntUshr(b, 63), a ^ (b >>> $opt$inline$IntConstant63())); 768 } 769 770 // Hiding constants outside the range [0, 32) used for int shifts from Jack. 771 // (Jack extracts only the low 5 bits.) $opt$inline$IntConstant32()772 public static int $opt$inline$IntConstant32() { return 32; } $opt$inline$IntConstant62()773 public static int $opt$inline$IntConstant62() { return 62; } $opt$inline$IntConstant63()774 public static int $opt$inline$IntConstant63() { return 63; } 775 776 $noinline$LongShl(long b, long c)777 static long $noinline$LongShl(long b, long c) { 778 if (doThrow) throw new Error(); 779 return b << c; 780 } $noinline$LongShr(long b, long c)781 static long $noinline$LongShr(long b, long c) { 782 if (doThrow) throw new Error(); 783 return b >> c; 784 } $noinline$LongUshr(long b, long c)785 static long $noinline$LongUshr(long b, long c) { 786 if (doThrow) throw new Error(); 787 return b >>> c; 788 } 789 790 // Each test line below should see one merge. 791 /// CHECK-START-ARM: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after) 792 /// CHECK: DataProcWithShifterOp 793 /// CHECK: DataProcWithShifterOp 794 /// CHECK: DataProcWithShifterOp 795 /// CHECK: DataProcWithShifterOp 796 /// CHECK: DataProcWithShifterOp 797 /// CHECK: DataProcWithShifterOp 798 /// CHECK: DataProcWithShifterOp 799 /// CHECK: DataProcWithShifterOp 800 /// CHECK: DataProcWithShifterOp 801 /// CHECK: DataProcWithShifterOp 802 /// CHECK: DataProcWithShifterOp 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-NOT: DataProcWithShifterOp 826 827 // On ARM shifts by 1 are not merged. 828 /// CHECK-START-ARM: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm (after) 829 /// CHECK: Shl 830 /// CHECK-NOT: Shl 831 /// CHECK: Shr 832 /// CHECK-NOT: Shr 833 /// CHECK: UShr 834 /// CHECK-NOT: UShr 835 836 /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after) 837 /// CHECK: DataProcWithShifterOp 838 /// CHECK: DataProcWithShifterOp 839 /// CHECK: DataProcWithShifterOp 840 /// CHECK: DataProcWithShifterOp 841 /// CHECK: DataProcWithShifterOp 842 /// CHECK: DataProcWithShifterOp 843 /// CHECK: DataProcWithShifterOp 844 /// CHECK: DataProcWithShifterOp 845 /// CHECK: DataProcWithShifterOp 846 /// CHECK: DataProcWithShifterOp 847 /// CHECK: DataProcWithShifterOp 848 /// CHECK: DataProcWithShifterOp 849 /// CHECK: DataProcWithShifterOp 850 /// CHECK: DataProcWithShifterOp 851 /// CHECK: DataProcWithShifterOp 852 /// CHECK: DataProcWithShifterOp 853 /// CHECK: DataProcWithShifterOp 854 /// CHECK: DataProcWithShifterOp 855 /// CHECK: DataProcWithShifterOp 856 /// CHECK: DataProcWithShifterOp 857 /// CHECK: DataProcWithShifterOp 858 /// CHECK: DataProcWithShifterOp 859 /// CHECK: DataProcWithShifterOp 860 /// CHECK: DataProcWithShifterOp 861 /// CHECK: DataProcWithShifterOp 862 /// CHECK: DataProcWithShifterOp 863 /// CHECK: DataProcWithShifterOp 864 /// CHECK: DataProcWithShifterOp 865 /// CHECK: DataProcWithShifterOp 866 /// CHECK: DataProcWithShifterOp 867 /// CHECK: DataProcWithShifterOp 868 /// CHECK: DataProcWithShifterOp 869 /// CHECK: DataProcWithShifterOp 870 /// CHECK: DataProcWithShifterOp 871 /// CHECK: DataProcWithShifterOp 872 /// CHECK: DataProcWithShifterOp 873 /// CHECK-NOT: DataProcWithShifterOp 874 875 /// CHECK-START-ARM64: void Main.$opt$validateShiftLong(long, long) instruction_simplifier_arm64 (after) 876 /// CHECK-NOT: Shl 877 /// CHECK-NOT: Shr 878 /// CHECK-NOT: UShr 879 $opt$validateShiftLong(long a, long b)880 public static void $opt$validateShiftLong(long a, long b) { 881 assertLongEquals(a + $noinline$LongShl(b, 1), a + (b << 1)); 882 assertLongEquals(a + $noinline$LongShl(b, 6), a + (b << 6)); 883 assertLongEquals(a + $noinline$LongShl(b, 7), a + (b << 7)); 884 assertLongEquals(a + $noinline$LongShl(b, 8), a + (b << 8)); 885 assertLongEquals(a + $noinline$LongShl(b, 14), a + (b << 14)); 886 assertLongEquals(a + $noinline$LongShl(b, 15), a + (b << 15)); 887 assertLongEquals(a + $noinline$LongShl(b, 16), a + (b << 16)); 888 assertLongEquals(a + $noinline$LongShl(b, 30), a + (b << 30)); 889 assertLongEquals(a + $noinline$LongShl(b, 31), a + (b << 31)); 890 assertLongEquals(a + $noinline$LongShl(b, 32), a + (b << 32)); 891 assertLongEquals(a + $noinline$LongShl(b, 62), a + (b << 62)); 892 assertLongEquals(a + $noinline$LongShl(b, 63), a + (b << 63)); 893 894 assertLongEquals(a - $noinline$LongShr(b, 1), a - (b >> 1)); 895 assertLongEquals(a - $noinline$LongShr(b, 6), a - (b >> 6)); 896 assertLongEquals(a - $noinline$LongShr(b, 7), a - (b >> 7)); 897 assertLongEquals(a - $noinline$LongShr(b, 8), a - (b >> 8)); 898 assertLongEquals(a - $noinline$LongShr(b, 14), a - (b >> 14)); 899 assertLongEquals(a - $noinline$LongShr(b, 15), a - (b >> 15)); 900 assertLongEquals(a - $noinline$LongShr(b, 16), a - (b >> 16)); 901 assertLongEquals(a - $noinline$LongShr(b, 30), a - (b >> 30)); 902 assertLongEquals(a - $noinline$LongShr(b, 31), a - (b >> 31)); 903 assertLongEquals(a - $noinline$LongShr(b, 32), a - (b >> 32)); 904 assertLongEquals(a - $noinline$LongShr(b, 62), a - (b >> 62)); 905 assertLongEquals(a - $noinline$LongShr(b, 63), a - (b >> 63)); 906 907 assertLongEquals(a ^ $noinline$LongUshr(b, 1), a ^ (b >>> 1)); 908 assertLongEquals(a ^ $noinline$LongUshr(b, 6), a ^ (b >>> 6)); 909 assertLongEquals(a ^ $noinline$LongUshr(b, 7), a ^ (b >>> 7)); 910 assertLongEquals(a ^ $noinline$LongUshr(b, 8), a ^ (b >>> 8)); 911 assertLongEquals(a ^ $noinline$LongUshr(b, 14), a ^ (b >>> 14)); 912 assertLongEquals(a ^ $noinline$LongUshr(b, 15), a ^ (b >>> 15)); 913 assertLongEquals(a ^ $noinline$LongUshr(b, 16), a ^ (b >>> 16)); 914 assertLongEquals(a ^ $noinline$LongUshr(b, 30), a ^ (b >>> 30)); 915 assertLongEquals(a ^ $noinline$LongUshr(b, 31), a ^ (b >>> 31)); 916 assertLongEquals(a ^ $noinline$LongUshr(b, 32), a ^ (b >>> 32)); 917 assertLongEquals(a ^ $noinline$LongUshr(b, 62), a ^ (b >>> 62)); 918 assertLongEquals(a ^ $noinline$LongUshr(b, 63), a ^ (b >>> 63)); 919 } 920 921 main(String[] args)922 public static void main(String[] args) { 923 assertLongEquals(10000L - 3L, $opt$noinline$translate(10000L, (byte)3)); 924 assertLongEquals(-10000L - -3L, $opt$noinline$translate(-10000L, (byte)-3)); 925 926 assertIntEquals(4096, $opt$noinline$sameInput(512)); 927 assertIntEquals(-8192, $opt$noinline$sameInput(-1024)); 928 929 assertIntEquals(((1 << 23) | 1), $opt$noinline$multipleUses(1)); 930 assertIntEquals(((1 << 20) | 5), $opt$noinline$multipleUses(1 << 20)); 931 932 long inputs[] = { 933 -((1L << 7) - 1L), -((1L << 7)), -((1L << 7) + 1L), 934 -((1L << 15) - 1L), -((1L << 15)), -((1L << 15) + 1L), 935 -((1L << 16) - 1L), -((1L << 16)), -((1L << 16) + 1L), 936 -((1L << 31) - 1L), -((1L << 31)), -((1L << 31) + 1L), 937 -((1L << 32) - 1L), -((1L << 32)), -((1L << 32) + 1L), 938 -((1L << 63) - 1L), -((1L << 63)), -((1L << 63) + 1L), 939 -42L, -314L, -2718281828L, -0x123456789L, -0x987654321L, 940 -1L, -20L, -300L, -4000L, -50000L, -600000L, -7000000L, -80000000L, 941 0L, 942 1L, 20L, 300L, 4000L, 50000L, 600000L, 7000000L, 80000000L, 943 42L, 314L, 2718281828L, 0x123456789L, 0x987654321L, 944 (1L << 7) - 1L, (1L << 7), (1L << 7) + 1L, 945 (1L << 8) - 1L, (1L << 8), (1L << 8) + 1L, 946 (1L << 15) - 1L, (1L << 15), (1L << 15) + 1L, 947 (1L << 16) - 1L, (1L << 16), (1L << 16) + 1L, 948 (1L << 31) - 1L, (1L << 31), (1L << 31) + 1L, 949 (1L << 32) - 1L, (1L << 32), (1L << 32) + 1L, 950 (1L << 63) - 1L, (1L << 63), (1L << 63) + 1L, 951 Long.MIN_VALUE, Long.MAX_VALUE 952 }; 953 for (int i = 0; i < inputs.length; i++) { 954 $opt$noinline$testNeg((int)inputs[i]); 955 for (int j = 0; j < inputs.length; j++) { 956 $opt$noinline$testAnd(inputs[i], inputs[j]); 957 $opt$noinline$testOr((int)inputs[i], (int)inputs[j]); 958 $opt$noinline$testXor(inputs[i], inputs[j]); 959 960 $opt$validateExtendByte(inputs[i], (byte)inputs[j]); 961 $opt$validateExtendChar(inputs[i], (char)inputs[j]); 962 $opt$validateExtendShort(inputs[i], (short)inputs[j]); 963 $opt$validateExtendInt(inputs[i], (int)inputs[j]); 964 $opt$validateExtendLong(inputs[i], inputs[j]); 965 966 $opt$validateShiftInt((int)inputs[i], (int)inputs[j]); 967 $opt$validateShiftLong(inputs[i], inputs[j]); 968 } 969 } 970 971 } 972 } 973