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