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 import java.lang.reflect.Method; 18 19 public class Main { 20 21 public static void assertBooleanEquals(boolean expected, boolean result) { 22 if (expected != result) { 23 throw new Error("Expected: " + expected + ", found: " + result); 24 } 25 } 26 27 public static void assertIntEquals(int expected, int result) { 28 if (expected != result) { 29 throw new Error("Expected: " + expected + ", found: " + result); 30 } 31 } 32 33 public static void assertLongEquals(long expected, long result) { 34 if (expected != result) { 35 throw new Error("Expected: " + expected + ", found: " + result); 36 } 37 } 38 39 public static void assertFloatEquals(float expected, float result) { 40 if (expected != result) { 41 throw new Error("Expected: " + expected + ", found: " + result); 42 } 43 } 44 45 public static void assertDoubleEquals(double expected, double result) { 46 if (expected != result) { 47 throw new Error("Expected: " + expected + ", found: " + result); 48 } 49 } 50 51 public static void assertStringEquals(String expected, String result) { 52 if (expected == null ? result != null : !expected.equals(result)) { 53 throw new Error("Expected: " + expected + ", found: " + result); 54 } 55 } 56 57 /** 58 * Tiny programs exercising optimizations of arithmetic identities. 59 */ 60 61 /// CHECK-START: long Main.Add0(long) instruction_simplifier (before) 62 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 63 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0 64 /// CHECK-DAG: <<Add:j\d+>> Add [<<Const0>>,<<Arg>>] 65 /// CHECK-DAG: Return [<<Add>>] 66 67 /// CHECK-START: long Main.Add0(long) instruction_simplifier (after) 68 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 69 /// CHECK-DAG: Return [<<Arg>>] 70 71 /// CHECK-START: long Main.Add0(long) instruction_simplifier (after) 72 /// CHECK-NOT: Add 73 74 public static long Add0(long arg) { 75 return 0 + arg; 76 } 77 78 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before) 79 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 80 /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1 81 /// CHECK-DAG: <<And:i\d+>> And [<<Arg>>,<<ConstF>>] 82 /// CHECK-DAG: Return [<<And>>] 83 84 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after) 85 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 86 /// CHECK-DAG: Return [<<Arg>>] 87 88 /// CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after) 89 /// CHECK-NOT: And 90 91 public static int AndAllOnes(int arg) { 92 return arg & -1; 93 } 94 95 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (before) 96 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 97 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28 98 /// CHECK-DAG: <<Const15:i\d+>> IntConstant 15 99 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>] 100 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const15>>] 101 /// CHECK-DAG: Return [<<And>>] 102 103 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (after) 104 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 105 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28 106 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>] 107 /// CHECK-DAG: Return [<<UShr>>] 108 109 /// CHECK-START: int Main.UShr28And15(int) instruction_simplifier (after) 110 /// CHECK-NOT: And 111 112 public static int UShr28And15(int arg) { 113 return (arg >>> 28) & 15; 114 } 115 116 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (before) 117 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 118 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60 119 /// CHECK-DAG: <<Const15:j\d+>> LongConstant 15 120 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>] 121 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const15>>] 122 /// CHECK-DAG: Return [<<And>>] 123 124 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (after) 125 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 126 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60 127 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>] 128 /// CHECK-DAG: Return [<<UShr>>] 129 130 /// CHECK-START: long Main.UShr60And15(long) instruction_simplifier (after) 131 /// CHECK-NOT: And 132 133 public static long UShr60And15(long arg) { 134 return (arg >>> 60) & 15; 135 } 136 137 /// CHECK-START: int Main.UShr28And7(int) instruction_simplifier (before) 138 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 139 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28 140 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7 141 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>] 142 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const7>>] 143 /// CHECK-DAG: Return [<<And>>] 144 145 /// CHECK-START: int Main.UShr28And7(int) instruction_simplifier (after) 146 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 147 /// CHECK-DAG: <<Const28:i\d+>> IntConstant 28 148 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7 149 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const28>>] 150 /// CHECK-DAG: <<And:i\d+>> And [<<UShr>>,<<Const7>>] 151 /// CHECK-DAG: Return [<<And>>] 152 153 public static int UShr28And7(int arg) { 154 return (arg >>> 28) & 7; 155 } 156 157 /// CHECK-START: long Main.UShr60And7(long) instruction_simplifier (before) 158 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 159 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60 160 /// CHECK-DAG: <<Const7:j\d+>> LongConstant 7 161 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>] 162 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const7>>] 163 /// CHECK-DAG: Return [<<And>>] 164 165 /// CHECK-START: long Main.UShr60And7(long) instruction_simplifier (after) 166 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 167 /// CHECK-DAG: <<Const60:i\d+>> IntConstant 60 168 /// CHECK-DAG: <<Const7:j\d+>> LongConstant 7 169 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const60>>] 170 /// CHECK-DAG: <<And:j\d+>> And [<<UShr>>,<<Const7>>] 171 /// CHECK-DAG: Return [<<And>>] 172 173 public static long UShr60And7(long arg) { 174 return (arg >>> 60) & 7; 175 } 176 177 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (before) 178 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 179 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24 180 /// CHECK-DAG: <<Const255:i\d+>> IntConstant 255 181 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>] 182 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const255>>] 183 /// CHECK-DAG: Return [<<And>>] 184 185 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (after) 186 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 187 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24 188 /// CHECK-DAG: <<UShr:i\d+>> UShr [<<Arg>>,<<Const24>>] 189 /// CHECK-DAG: Return [<<UShr>>] 190 191 /// CHECK-START: int Main.Shr24And255(int) instruction_simplifier (after) 192 /// CHECK-NOT: Shr 193 /// CHECK-NOT: And 194 195 public static int Shr24And255(int arg) { 196 return (arg >> 24) & 255; 197 } 198 199 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (before) 200 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 201 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56 202 /// CHECK-DAG: <<Const255:j\d+>> LongConstant 255 203 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>] 204 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const255>>] 205 /// CHECK-DAG: Return [<<And>>] 206 207 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (after) 208 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 209 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56 210 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const56>>] 211 /// CHECK-DAG: Return [<<UShr>>] 212 213 /// CHECK-START: long Main.Shr56And255(long) instruction_simplifier (after) 214 /// CHECK-NOT: Shr 215 /// CHECK-NOT: And 216 217 public static long Shr56And255(long arg) { 218 return (arg >> 56) & 255; 219 } 220 221 /// CHECK-START: int Main.Shr24And127(int) instruction_simplifier (before) 222 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 223 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24 224 /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127 225 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>] 226 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>] 227 /// CHECK-DAG: Return [<<And>>] 228 229 /// CHECK-START: int Main.Shr24And127(int) instruction_simplifier (after) 230 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 231 /// CHECK-DAG: <<Const24:i\d+>> IntConstant 24 232 /// CHECK-DAG: <<Const127:i\d+>> IntConstant 127 233 /// CHECK-DAG: <<Shr:i\d+>> Shr [<<Arg>>,<<Const24>>] 234 /// CHECK-DAG: <<And:i\d+>> And [<<Shr>>,<<Const127>>] 235 /// CHECK-DAG: Return [<<And>>] 236 237 public static int Shr24And127(int arg) { 238 return (arg >> 24) & 127; 239 } 240 241 /// CHECK-START: long Main.Shr56And127(long) instruction_simplifier (before) 242 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 243 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56 244 /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127 245 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>] 246 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>] 247 /// CHECK-DAG: Return [<<And>>] 248 249 /// CHECK-START: long Main.Shr56And127(long) instruction_simplifier (after) 250 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 251 /// CHECK-DAG: <<Const56:i\d+>> IntConstant 56 252 /// CHECK-DAG: <<Const127:j\d+>> LongConstant 127 253 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const56>>] 254 /// CHECK-DAG: <<And:j\d+>> And [<<Shr>>,<<Const127>>] 255 /// CHECK-DAG: Return [<<And>>] 256 257 public static long Shr56And127(long arg) { 258 return (arg >> 56) & 127; 259 } 260 261 /// CHECK-START: long Main.Div1(long) instruction_simplifier (before) 262 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 263 /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1 264 /// CHECK-DAG: <<Div:j\d+>> Div [<<Arg>>,<<Const1>>] 265 /// CHECK-DAG: Return [<<Div>>] 266 267 /// CHECK-START: long Main.Div1(long) instruction_simplifier (after) 268 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 269 /// CHECK-DAG: Return [<<Arg>>] 270 271 /// CHECK-START: long Main.Div1(long) instruction_simplifier (after) 272 /// CHECK-NOT: Div 273 274 public static long Div1(long arg) { 275 return arg / 1; 276 } 277 278 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (before) 279 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 280 /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1 281 /// CHECK-DAG: <<Div:i\d+>> Div [<<Arg>>,<<ConstN1>>] 282 /// CHECK-DAG: Return [<<Div>>] 283 284 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after) 285 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 286 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>] 287 /// CHECK-DAG: Return [<<Neg>>] 288 289 /// CHECK-START: int Main.DivN1(int) instruction_simplifier (after) 290 /// CHECK-NOT: Div 291 292 public static int DivN1(int arg) { 293 return arg / -1; 294 } 295 296 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (before) 297 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 298 /// CHECK-DAG: <<Const1:j\d+>> LongConstant 1 299 /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Const1>>,<<Arg>>] 300 /// CHECK-DAG: Return [<<Mul>>] 301 302 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after) 303 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 304 /// CHECK-DAG: Return [<<Arg>>] 305 306 /// CHECK-START: long Main.Mul1(long) instruction_simplifier (after) 307 /// CHECK-NOT: Mul 308 309 public static long Mul1(long arg) { 310 return arg * 1; 311 } 312 313 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (before) 314 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 315 /// CHECK-DAG: <<ConstN1:i\d+>> IntConstant -1 316 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Arg>>,<<ConstN1>>] 317 /// CHECK-DAG: Return [<<Mul>>] 318 319 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after) 320 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 321 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>] 322 /// CHECK-DAG: Return [<<Neg>>] 323 324 /// CHECK-START: int Main.MulN1(int) instruction_simplifier (after) 325 /// CHECK-NOT: Mul 326 327 public static int MulN1(int arg) { 328 return arg * -1; 329 } 330 331 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before) 332 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 333 /// CHECK-DAG: <<Const128:j\d+>> LongConstant 128 334 /// CHECK-DAG: <<Mul:j\d+>> Mul [<<Const128>>,<<Arg>>] 335 /// CHECK-DAG: Return [<<Mul>>] 336 337 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after) 338 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 339 /// CHECK-DAG: <<Const7:i\d+>> IntConstant 7 340 /// CHECK-DAG: <<Shl:j\d+>> Shl [<<Arg>>,<<Const7>>] 341 /// CHECK-DAG: Return [<<Shl>>] 342 343 /// CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after) 344 /// CHECK-NOT: Mul 345 346 public static long MulPowerOfTwo128(long arg) { 347 return arg * 128; 348 } 349 350 /// CHECK-START: int Main.Or0(int) instruction_simplifier (before) 351 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 352 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 353 /// CHECK-DAG: <<Or:i\d+>> Or [<<Arg>>,<<Const0>>] 354 /// CHECK-DAG: Return [<<Or>>] 355 356 /// CHECK-START: int Main.Or0(int) instruction_simplifier (after) 357 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 358 /// CHECK-DAG: Return [<<Arg>>] 359 360 /// CHECK-START: int Main.Or0(int) instruction_simplifier (after) 361 /// CHECK-NOT: Or 362 363 public static int Or0(int arg) { 364 return arg | 0; 365 } 366 367 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (before) 368 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 369 /// CHECK-DAG: <<Or:j\d+>> Or [<<Arg>>,<<Arg>>] 370 /// CHECK-DAG: Return [<<Or>>] 371 372 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after) 373 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 374 /// CHECK-DAG: Return [<<Arg>>] 375 376 /// CHECK-START: long Main.OrSame(long) instruction_simplifier (after) 377 /// CHECK-NOT: Or 378 379 public static long OrSame(long arg) { 380 return arg | arg; 381 } 382 383 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (before) 384 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 385 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 386 /// CHECK-DAG: <<Shl:i\d+>> Shl [<<Arg>>,<<Const0>>] 387 /// CHECK-DAG: Return [<<Shl>>] 388 389 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after) 390 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 391 /// CHECK-DAG: Return [<<Arg>>] 392 393 /// CHECK-START: int Main.Shl0(int) instruction_simplifier (after) 394 /// CHECK-NOT: Shl 395 396 public static int Shl0(int arg) { 397 return arg << 0; 398 } 399 400 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (before) 401 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 402 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 403 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const0>>] 404 /// CHECK-DAG: Return [<<Shr>>] 405 406 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after) 407 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 408 /// CHECK-DAG: Return [<<Arg>>] 409 410 /// CHECK-START: long Main.Shr0(long) instruction_simplifier (after) 411 /// CHECK-NOT: Shr 412 413 public static long Shr0(long arg) { 414 return arg >> 0; 415 } 416 417 /// CHECK-START: long Main.Shr64(long) instruction_simplifier (before) 418 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 419 /// CHECK-DAG: <<Const64:i\d+>> IntConstant 64 420 /// CHECK-DAG: <<Shr:j\d+>> Shr [<<Arg>>,<<Const64>>] 421 /// CHECK-DAG: Return [<<Shr>>] 422 423 /// CHECK-START: long Main.Shr64(long) instruction_simplifier (after) 424 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 425 /// CHECK-DAG: Return [<<Arg>>] 426 427 /// CHECK-START: long Main.Shr64(long) instruction_simplifier (after) 428 /// CHECK-NOT: Shr 429 430 public static long Shr64(long arg) { 431 return arg >> 64; 432 } 433 434 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (before) 435 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 436 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0 437 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg>>,<<Const0>>] 438 /// CHECK-DAG: Return [<<Sub>>] 439 440 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after) 441 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 442 /// CHECK-DAG: Return [<<Arg>>] 443 444 /// CHECK-START: long Main.Sub0(long) instruction_simplifier (after) 445 /// CHECK-NOT: Sub 446 447 public static long Sub0(long arg) { 448 return arg - 0; 449 } 450 451 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before) 452 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 453 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 454 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Const0>>,<<Arg>>] 455 /// CHECK-DAG: Return [<<Sub>>] 456 457 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after) 458 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 459 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg>>] 460 /// CHECK-DAG: Return [<<Neg>>] 461 462 /// CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (after) 463 /// CHECK-NOT: Sub 464 465 public static int SubAliasNeg(int arg) { 466 return 0 - arg; 467 } 468 469 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (before) 470 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 471 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 472 /// CHECK-DAG: <<UShr:j\d+>> UShr [<<Arg>>,<<Const0>>] 473 /// CHECK-DAG: Return [<<UShr>>] 474 475 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after) 476 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 477 /// CHECK-DAG: Return [<<Arg>>] 478 479 /// CHECK-START: long Main.UShr0(long) instruction_simplifier (after) 480 /// CHECK-NOT: UShr 481 482 public static long UShr0(long arg) { 483 return arg >>> 0; 484 } 485 486 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (before) 487 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 488 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 489 /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<Const0>>] 490 /// CHECK-DAG: Return [<<Xor>>] 491 492 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after) 493 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 494 /// CHECK-DAG: Return [<<Arg>>] 495 496 /// CHECK-START: int Main.Xor0(int) instruction_simplifier (after) 497 /// CHECK-NOT: Xor 498 499 public static int Xor0(int arg) { 500 return arg ^ 0; 501 } 502 503 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before) 504 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 505 /// CHECK-DAG: <<ConstF:i\d+>> IntConstant -1 506 /// CHECK-DAG: <<Xor:i\d+>> Xor [<<Arg>>,<<ConstF>>] 507 /// CHECK-DAG: Return [<<Xor>>] 508 509 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after) 510 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 511 /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>] 512 /// CHECK-DAG: Return [<<Not>>] 513 514 /// CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after) 515 /// CHECK-NOT: Xor 516 517 public static int XorAllOnes(int arg) { 518 return arg ^ -1; 519 } 520 521 /** 522 * Test that addition or subtraction operation with both inputs negated are 523 * optimized to use a single negation after the operation. 524 * The transformation tested is implemented in 525 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`. 526 */ 527 528 /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before) 529 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 530 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 531 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>] 532 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>] 533 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>] 534 /// CHECK-DAG: Return [<<Add>>] 535 536 /// CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after) 537 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 538 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 539 /// CHECK-NOT: Neg 540 /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>] 541 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>] 542 /// CHECK-DAG: Return [<<Neg>>] 543 544 public static int AddNegs1(int arg1, int arg2) { 545 return -arg1 + -arg2; 546 } 547 548 /** 549 * This is similar to the test-case AddNegs1, but the negations have 550 * multiple uses. 551 * The transformation tested is implemented in 552 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`. 553 * The current code won't perform the previous optimization. The 554 * transformations do not look at other uses of their inputs. As they don't 555 * know what will happen with other uses, they do not take the risk of 556 * increasing the register pressure by creating or extending live ranges. 557 */ 558 559 /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before) 560 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 561 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 562 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>] 563 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>] 564 /// CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>] 565 /// CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>] 566 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>] 567 /// CHECK-DAG: Return [<<Or>>] 568 569 /// CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after) 570 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 571 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 572 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>] 573 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>] 574 /// CHECK-DAG: <<Add1:i\d+>> Add [<<Neg1>>,<<Neg2>>] 575 /// CHECK-DAG: <<Add2:i\d+>> Add [<<Neg1>>,<<Neg2>>] 576 /// CHECK-NOT: Neg 577 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add1>>,<<Add2>>] 578 /// CHECK-DAG: Return [<<Or>>] 579 580 /// CHECK-START: int Main.AddNegs2(int, int) GVN (after) 581 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 582 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 583 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg1>>] 584 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Arg2>>] 585 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg1>>,<<Neg2>>] 586 /// CHECK-DAG: <<Or:i\d+>> Or [<<Add>>,<<Add>>] 587 /// CHECK-DAG: Return [<<Or>>] 588 589 public static int AddNegs2(int arg1, int arg2) { 590 int temp1 = -arg1; 591 int temp2 = -arg2; 592 return (temp1 + temp2) | (temp1 + temp2); 593 } 594 595 /** 596 * This follows test-cases AddNegs1 and AddNegs2. 597 * The transformation tested is implemented in 598 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`. 599 * The optimization should not happen if it moves an additional instruction in 600 * the loop. 601 */ 602 603 /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before) 604 // -------------- Arguments and initial negation operations. 605 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue 606 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue 607 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>] 608 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>] 609 /// CHECK: Goto 610 // -------------- Loop 611 /// CHECK: SuspendCheck 612 /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>] 613 /// CHECK: Goto 614 615 /// CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after) 616 // -------------- Arguments and initial negation operations. 617 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue 618 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue 619 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg1>>] 620 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Arg2>>] 621 /// CHECK: Goto 622 // -------------- Loop 623 /// CHECK: SuspendCheck 624 /// CHECK: <<Add:j\d+>> Add [<<Neg1>>,<<Neg2>>] 625 /// CHECK-NOT: Neg 626 /// CHECK: Goto 627 628 public static long AddNegs3(long arg1, long arg2) { 629 long res = 0; 630 long n_arg1 = -arg1; 631 long n_arg2 = -arg2; 632 for (long i = 0; i < 1; i++) { 633 res += n_arg1 + n_arg2 + i; 634 } 635 return res; 636 } 637 638 /** 639 * Test the simplification of an addition with a negated argument into a 640 * subtraction. 641 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`. 642 */ 643 644 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before) 645 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue 646 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue 647 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>] 648 /// CHECK-DAG: <<Add:j\d+>> Add [<<Neg>>,<<Arg2>>] 649 /// CHECK-DAG: Return [<<Add>>] 650 651 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after) 652 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue 653 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue 654 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Arg2>>,<<Arg1>>] 655 /// CHECK-DAG: Return [<<Sub>>] 656 657 /// CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after) 658 /// CHECK-NOT: Neg 659 /// CHECK-NOT: Add 660 661 public static long AddNeg1(long arg1, long arg2) { 662 return -arg1 + arg2; 663 } 664 665 /** 666 * This is similar to the test-case AddNeg1, but the negation has two uses. 667 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`. 668 * The current code won't perform the previous optimization. The 669 * transformations do not look at other uses of their inputs. As they don't 670 * know what will happen with other uses, they do not take the risk of 671 * increasing the register pressure by creating or extending live ranges. 672 */ 673 674 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before) 675 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue 676 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue 677 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>] 678 /// CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>] 679 /// CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>] 680 /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>] 681 /// CHECK-DAG: Return [<<Res>>] 682 683 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after) 684 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue 685 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue 686 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg2>>] 687 /// CHECK-DAG: <<Add1:j\d+>> Add [<<Arg1>>,<<Neg>>] 688 /// CHECK-DAG: <<Add2:j\d+>> Add [<<Arg1>>,<<Neg>>] 689 /// CHECK-DAG: <<Res:j\d+>> Or [<<Add1>>,<<Add2>>] 690 /// CHECK-DAG: Return [<<Res>>] 691 692 /// CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after) 693 /// CHECK-NOT: Sub 694 695 public static long AddNeg2(long arg1, long arg2) { 696 long temp = -arg2; 697 return (arg1 + temp) | (arg1 + temp); 698 } 699 700 /** 701 * Test simplification of the `-(-var)` pattern. 702 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`. 703 */ 704 705 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before) 706 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 707 /// CHECK-DAG: <<Neg1:j\d+>> Neg [<<Arg>>] 708 /// CHECK-DAG: <<Neg2:j\d+>> Neg [<<Neg1>>] 709 /// CHECK-DAG: Return [<<Neg2>>] 710 711 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after) 712 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 713 /// CHECK-DAG: Return [<<Arg>>] 714 715 /// CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after) 716 /// CHECK-NOT: Neg 717 718 public static long NegNeg1(long arg) { 719 return -(-arg); 720 } 721 722 /** 723 * Test 'multi-step' simplification, where a first transformation yields a 724 * new simplification possibility for the current instruction. 725 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg` 726 * and in `InstructionSimplifierVisitor::VisitAdd`. 727 */ 728 729 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before) 730 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 731 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Arg>>] 732 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Neg1>>] 733 /// CHECK-DAG: <<Add:i\d+>> Add [<<Neg2>>,<<Neg1>>] 734 /// CHECK-DAG: Return [<<Add>>] 735 736 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after) 737 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 738 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg>>,<<Arg>>] 739 /// CHECK-DAG: Return [<<Sub>>] 740 741 /// CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after) 742 /// CHECK-NOT: Neg 743 /// CHECK-NOT: Add 744 745 /// CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after) 746 /// CHECK: <<Const0:i\d+>> IntConstant 0 747 /// CHECK-NOT: Neg 748 /// CHECK-NOT: Add 749 /// CHECK: Return [<<Const0>>] 750 751 public static int NegNeg2(int arg) { 752 int temp = -arg; 753 return temp + -temp; 754 } 755 756 /** 757 * Test another 'multi-step' simplification, where a first transformation 758 * yields a new simplification possibility for the current instruction. 759 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg` 760 * and in `InstructionSimplifierVisitor::VisitSub`. 761 */ 762 763 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before) 764 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 765 /// CHECK-DAG: <<Const0:j\d+>> LongConstant 0 766 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg>>] 767 /// CHECK-DAG: <<Sub:j\d+>> Sub [<<Const0>>,<<Neg>>] 768 /// CHECK-DAG: Return [<<Sub>>] 769 770 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after) 771 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 772 /// CHECK-DAG: Return [<<Arg>>] 773 774 /// CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after) 775 /// CHECK-NOT: Neg 776 /// CHECK-NOT: Sub 777 778 public static long NegNeg3(long arg) { 779 return 0 - -arg; 780 } 781 782 /** 783 * Test that a negated subtraction is simplified to a subtraction with its 784 * arguments reversed. 785 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`. 786 */ 787 788 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before) 789 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 790 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 791 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>] 792 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Sub>>] 793 /// CHECK-DAG: Return [<<Neg>>] 794 795 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after) 796 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 797 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 798 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg2>>,<<Arg1>>] 799 /// CHECK-DAG: Return [<<Sub>>] 800 801 /// CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after) 802 /// CHECK-NOT: Neg 803 804 public static int NegSub1(int arg1, int arg2) { 805 return -(arg1 - arg2); 806 } 807 808 /** 809 * This is similar to the test-case NegSub1, but the subtraction has 810 * multiple uses. 811 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`. 812 * The current code won't perform the previous optimization. The 813 * transformations do not look at other uses of their inputs. As they don't 814 * know what will happen with other uses, they do not take the risk of 815 * increasing the register pressure by creating or extending live ranges. 816 */ 817 818 /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before) 819 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 820 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 821 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>] 822 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>] 823 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>] 824 /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>] 825 /// CHECK-DAG: Return [<<Or>>] 826 827 /// CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after) 828 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 829 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 830 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Arg1>>,<<Arg2>>] 831 /// CHECK-DAG: <<Neg1:i\d+>> Neg [<<Sub>>] 832 /// CHECK-DAG: <<Neg2:i\d+>> Neg [<<Sub>>] 833 /// CHECK-DAG: <<Or:i\d+>> Or [<<Neg1>>,<<Neg2>>] 834 /// CHECK-DAG: Return [<<Or>>] 835 836 public static int NegSub2(int arg1, int arg2) { 837 int temp = arg1 - arg2; 838 return -temp | -temp; 839 } 840 841 /** 842 * Test simplification of the `~~var` pattern. 843 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`. 844 */ 845 846 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (before) 847 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 848 /// CHECK-DAG: <<Not1:j\d+>> Not [<<Arg>>] 849 /// CHECK-DAG: <<Not2:j\d+>> Not [<<Not1>>] 850 /// CHECK-DAG: Return [<<Not2>>] 851 852 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after) 853 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 854 /// CHECK-DAG: Return [<<Arg>>] 855 856 /// CHECK-START: long Main.NotNot1(long) instruction_simplifier (after) 857 /// CHECK-NOT: Not 858 859 public static long NotNot1(long arg) { 860 return ~~arg; 861 } 862 863 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (before) 864 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 865 /// CHECK-DAG: <<Not1:i\d+>> Not [<<Arg>>] 866 /// CHECK-DAG: <<Not2:i\d+>> Not [<<Not1>>] 867 /// CHECK-DAG: <<Add:i\d+>> Add [<<Not2>>,<<Not1>>] 868 /// CHECK-DAG: Return [<<Add>>] 869 870 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after) 871 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 872 /// CHECK-DAG: <<Not:i\d+>> Not [<<Arg>>] 873 /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg>>,<<Not>>] 874 /// CHECK-DAG: Return [<<Add>>] 875 876 /// CHECK-START: int Main.NotNot2(int) instruction_simplifier (after) 877 /// CHECK: Not 878 /// CHECK-NOT: Not 879 880 public static int NotNot2(int arg) { 881 int temp = ~arg; 882 return temp + ~temp; 883 } 884 885 /** 886 * Test the simplification of a subtraction with a negated argument. 887 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`. 888 */ 889 890 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before) 891 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 892 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 893 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>] 894 /// CHECK-DAG: <<Sub:i\d+>> Sub [<<Neg>>,<<Arg2>>] 895 /// CHECK-DAG: Return [<<Sub>>] 896 897 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after) 898 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 899 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 900 /// CHECK-DAG: <<Add:i\d+>> Add [<<Arg1>>,<<Arg2>>] 901 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Add>>] 902 /// CHECK-DAG: Return [<<Neg>>] 903 904 /// CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after) 905 /// CHECK-NOT: Sub 906 907 public static int SubNeg1(int arg1, int arg2) { 908 return -arg1 - arg2; 909 } 910 911 /** 912 * This is similar to the test-case SubNeg1, but the negation has 913 * multiple uses. 914 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`. 915 * The current code won't perform the previous optimization. The 916 * transformations do not look at other uses of their inputs. As they don't 917 * know what will happen with other uses, they do not take the risk of 918 * increasing the register pressure by creating or extending live ranges. 919 */ 920 921 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before) 922 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 923 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 924 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>] 925 /// CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>] 926 /// CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>] 927 /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>] 928 /// CHECK-DAG: Return [<<Or>>] 929 930 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after) 931 /// CHECK-DAG: <<Arg1:i\d+>> ParameterValue 932 /// CHECK-DAG: <<Arg2:i\d+>> ParameterValue 933 /// CHECK-DAG: <<Neg:i\d+>> Neg [<<Arg1>>] 934 /// CHECK-DAG: <<Sub1:i\d+>> Sub [<<Neg>>,<<Arg2>>] 935 /// CHECK-DAG: <<Sub2:i\d+>> Sub [<<Neg>>,<<Arg2>>] 936 /// CHECK-DAG: <<Or:i\d+>> Or [<<Sub1>>,<<Sub2>>] 937 /// CHECK-DAG: Return [<<Or>>] 938 939 /// CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after) 940 /// CHECK-NOT: Add 941 942 public static int SubNeg2(int arg1, int arg2) { 943 int temp = -arg1; 944 return (temp - arg2) | (temp - arg2); 945 } 946 947 /** 948 * This follows test-cases SubNeg1 and SubNeg2. 949 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`. 950 * The optimization should not happen if it moves an additional instruction in 951 * the loop. 952 */ 953 954 /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before) 955 // -------------- Arguments and initial negation operation. 956 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue 957 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue 958 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>] 959 /// CHECK: Goto 960 // -------------- Loop 961 /// CHECK: SuspendCheck 962 /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>] 963 /// CHECK: Goto 964 965 /// CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after) 966 // -------------- Arguments and initial negation operation. 967 /// CHECK-DAG: <<Arg1:j\d+>> ParameterValue 968 /// CHECK-DAG: <<Arg2:j\d+>> ParameterValue 969 /// CHECK-DAG: <<Neg:j\d+>> Neg [<<Arg1>>] 970 /// CHECK-DAG: Goto 971 // -------------- Loop 972 /// CHECK: SuspendCheck 973 /// CHECK: <<Sub:j\d+>> Sub [<<Neg>>,<<Arg2>>] 974 /// CHECK-NOT: Neg 975 /// CHECK: Goto 976 977 public static long SubNeg3(long arg1, long arg2) { 978 long res = 0; 979 long temp = -arg1; 980 for (long i = 0; i < 1; i++) { 981 res += temp - arg2 - i; 982 } 983 return res; 984 } 985 986 /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before) 987 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue 988 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 989 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 990 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 991 /// CHECK-DAG: <<NotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<Arg>>] 992 /// CHECK-DAG: <<Cond:z\d+>> Equal [<<NotArg>>,<<Const2>>] 993 /// CHECK-DAG: <<NotCond:i\d+>> Select [<<Const1>>,<<Const0>>,<<Cond>>] 994 /// CHECK-DAG: Return [<<NotCond>>] 995 996 /// CHECK-START: boolean Main.EqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after) 997 /// CHECK-DAG: <<True:i\d+>> IntConstant 1 998 /// CHECK-DAG: Return [<<True>>] 999 1000 public static boolean EqualBoolVsIntConst(boolean arg) { 1001 return (arg ? 0 : 1) != 2; 1002 } 1003 1004 /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (before) 1005 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue 1006 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1007 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1008 /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2 1009 /// CHECK-DAG: <<NotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<Arg>>] 1010 /// CHECK-DAG: <<Cond:z\d+>> NotEqual [<<NotArg>>,<<Const2>>] 1011 /// CHECK-DAG: <<NotCond:i\d+>> Select [<<Const1>>,<<Const0>>,<<Cond>>] 1012 /// CHECK-DAG: Return [<<NotCond>>] 1013 1014 /// CHECK-START: boolean Main.NotEqualBoolVsIntConst(boolean) instruction_simplifier_after_bce (after) 1015 /// CHECK-DAG: <<False:i\d+>> IntConstant 0 1016 /// CHECK-DAG: Return [<<False>>] 1017 1018 public static boolean NotEqualBoolVsIntConst(boolean arg) { 1019 return (arg ? 0 : 1) == 2; 1020 } 1021 1022 /* 1023 * Test simplification of double Boolean negation. Note that sometimes 1024 * both negations can be removed but we only expect the simplifier to 1025 * remove the second. 1026 */ 1027 1028 /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (before) 1029 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue 1030 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1031 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1032 /// CHECK-DAG: <<NotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<Arg>>] 1033 /// CHECK-DAG: <<NotNotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<NotArg>>] 1034 /// CHECK-DAG: Return [<<NotNotArg>>] 1035 1036 /// CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_bce (after) 1037 /// CHECK-DAG: <<Arg:z\d+>> ParameterValue 1038 /// CHECK-DAG: Return [<<Arg>>] 1039 1040 public static boolean NegateValue(boolean arg) { 1041 return !arg; 1042 } 1043 1044 public static boolean NotNotBool(boolean arg) { 1045 return !(NegateValue(arg)); 1046 } 1047 1048 /// CHECK-START: float Main.Div2(float) instruction_simplifier (before) 1049 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1050 /// CHECK-DAG: <<Const2:f\d+>> FloatConstant 2 1051 /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<Const2>>] 1052 /// CHECK-DAG: Return [<<Div>>] 1053 1054 /// CHECK-START: float Main.Div2(float) instruction_simplifier (after) 1055 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1056 /// CHECK-DAG: <<ConstP5:f\d+>> FloatConstant 0.5 1057 /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstP5>>] 1058 /// CHECK-DAG: Return [<<Mul>>] 1059 1060 /// CHECK-START: float Main.Div2(float) instruction_simplifier (after) 1061 /// CHECK-NOT: Div 1062 1063 public static float Div2(float arg) { 1064 return arg / 2.0f; 1065 } 1066 1067 /// CHECK-START: double Main.Div2(double) instruction_simplifier (before) 1068 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue 1069 /// CHECK-DAG: <<Const2:d\d+>> DoubleConstant 2 1070 /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<Const2>>] 1071 /// CHECK-DAG: Return [<<Div>>] 1072 1073 /// CHECK-START: double Main.Div2(double) instruction_simplifier (after) 1074 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue 1075 /// CHECK-DAG: <<ConstP5:d\d+>> DoubleConstant 0.5 1076 /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstP5>>] 1077 /// CHECK-DAG: Return [<<Mul>>] 1078 1079 /// CHECK-START: double Main.Div2(double) instruction_simplifier (after) 1080 /// CHECK-NOT: Div 1081 public static double Div2(double arg) { 1082 return arg / 2.0; 1083 } 1084 1085 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (before) 1086 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1087 /// CHECK-DAG: <<ConstMP25:f\d+>> FloatConstant -0.25 1088 /// CHECK-DAG: <<Div:f\d+>> Div [<<Arg>>,<<ConstMP25>>] 1089 /// CHECK-DAG: Return [<<Div>>] 1090 1091 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after) 1092 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1093 /// CHECK-DAG: <<ConstM4:f\d+>> FloatConstant -4 1094 /// CHECK-DAG: <<Mul:f\d+>> Mul [<<Arg>>,<<ConstM4>>] 1095 /// CHECK-DAG: Return [<<Mul>>] 1096 1097 /// CHECK-START: float Main.DivMP25(float) instruction_simplifier (after) 1098 /// CHECK-NOT: Div 1099 1100 public static float DivMP25(float arg) { 1101 return arg / -0.25f; 1102 } 1103 1104 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (before) 1105 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue 1106 /// CHECK-DAG: <<ConstMP25:d\d+>> DoubleConstant -0.25 1107 /// CHECK-DAG: <<Div:d\d+>> Div [<<Arg>>,<<ConstMP25>>] 1108 /// CHECK-DAG: Return [<<Div>>] 1109 1110 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after) 1111 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue 1112 /// CHECK-DAG: <<ConstM4:d\d+>> DoubleConstant -4 1113 /// CHECK-DAG: <<Mul:d\d+>> Mul [<<Arg>>,<<ConstM4>>] 1114 /// CHECK-DAG: Return [<<Mul>>] 1115 1116 /// CHECK-START: double Main.DivMP25(double) instruction_simplifier (after) 1117 /// CHECK-NOT: Div 1118 public static double DivMP25(double arg) { 1119 return arg / -0.25f; 1120 } 1121 1122 /** 1123 * Test strength reduction of factors of the form (2^n + 1). 1124 */ 1125 1126 /// CHECK-START: int Main.mulPow2Plus1(int) instruction_simplifier (before) 1127 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1128 /// CHECK-DAG: <<Const9:i\d+>> IntConstant 9 1129 /// CHECK: Mul [<<Arg>>,<<Const9>>] 1130 1131 /// CHECK-START: int Main.mulPow2Plus1(int) instruction_simplifier (after) 1132 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1133 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3 1134 /// CHECK: <<Shift:i\d+>> Shl [<<Arg>>,<<Const3>>] 1135 /// CHECK-NEXT: Add [<<Arg>>,<<Shift>>] 1136 1137 public static int mulPow2Plus1(int arg) { 1138 return arg * 9; 1139 } 1140 1141 /** 1142 * Test strength reduction of factors of the form (2^n - 1). 1143 */ 1144 1145 /// CHECK-START: long Main.mulPow2Minus1(long) instruction_simplifier (before) 1146 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 1147 /// CHECK-DAG: <<Const31:j\d+>> LongConstant 31 1148 /// CHECK: Mul [<<Const31>>,<<Arg>>] 1149 1150 /// CHECK-START: long Main.mulPow2Minus1(long) instruction_simplifier (after) 1151 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 1152 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5 1153 /// CHECK: <<Shift:j\d+>> Shl [<<Arg>>,<<Const5>>] 1154 /// CHECK-NEXT: Sub [<<Shift>>,<<Arg>>] 1155 1156 public static long mulPow2Minus1(long arg) { 1157 return arg * 31; 1158 } 1159 1160 /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_after_bce (before) 1161 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1162 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1163 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1164 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet 1165 /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<Field>>,<<Const1>>] 1166 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>] 1167 /// CHECK-DAG: Return [<<Select>>] 1168 1169 /// CHECK-START: int Main.booleanFieldNotEqualOne() instruction_simplifier_after_bce (after) 1170 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet 1171 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1172 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1173 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const54>>,<<Const13>>,<<Field>>] 1174 /// CHECK-DAG: Return [<<Select>>] 1175 1176 public static int booleanFieldNotEqualOne() { 1177 return (booleanField == $inline$true()) ? 13 : 54; 1178 } 1179 1180 /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_after_bce (before) 1181 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1182 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1183 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1184 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet 1185 /// CHECK-DAG: <<NE:z\d+>> Equal [<<Field>>,<<Const0>>] 1186 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>] 1187 /// CHECK-DAG: Return [<<Select>>] 1188 1189 /// CHECK-START: int Main.booleanFieldEqualZero() instruction_simplifier_after_bce (after) 1190 /// CHECK-DAG: <<Field:z\d+>> StaticFieldGet 1191 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1192 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1193 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const54>>,<<Const13>>,<<Field>>] 1194 /// CHECK-DAG: Return [<<Select>>] 1195 1196 public static int booleanFieldEqualZero() { 1197 return (booleanField != $inline$false()) ? 13 : 54; 1198 } 1199 1200 /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (before) 1201 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1202 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1203 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1204 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1205 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 1206 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1207 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Arg>>,<<Const42>>] 1208 /// CHECK-DAG: <<GT:i\d+>> Select [<<Const1>>,<<Const0>>,<<LE>>] 1209 /// CHECK-DAG: <<NE:z\d+>> NotEqual [<<GT>>,<<Const1>>] 1210 /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>] 1211 /// CHECK-DAG: Return [<<Result>>] 1212 1213 /// CHECK-START: int Main.intConditionNotEqualOne(int) instruction_simplifier_after_bce (after) 1214 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1215 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1216 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 1217 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1218 /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE:z\d+>>] 1219 /// CHECK-DAG: <<LE>> LessThanOrEqual [<<Arg>>,<<Const42>>] 1220 /// CHECK-DAG: Return [<<Result>>] 1221 // Note that we match `LE` from Select because there are two identical 1222 // LessThanOrEqual instructions. 1223 1224 public static int intConditionNotEqualOne(int i) { 1225 return ((i > 42) == $inline$true()) ? 13 : 54; 1226 } 1227 1228 /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (before) 1229 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1230 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 1231 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 1232 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1233 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 1234 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1235 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Arg>>,<<Const42>>] 1236 /// CHECK-DAG: <<GT:i\d+>> Select [<<Const1>>,<<Const0>>,<<LE>>] 1237 /// CHECK-DAG: <<NE:z\d+>> Equal [<<GT>>,<<Const0>>] 1238 /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<NE>>] 1239 /// CHECK-DAG: Return [<<Result>>] 1240 1241 /// CHECK-START: int Main.intConditionEqualZero(int) instruction_simplifier_after_bce (after) 1242 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1243 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1244 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 1245 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1246 /// CHECK-DAG: <<Result:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE:z\d+>>] 1247 /// CHECK-DAG: <<LE>> LessThanOrEqual [<<Arg>>,<<Const42>>] 1248 /// CHECK-DAG: Return [<<Result>>] 1249 // Note that we match `LE` from Select because there are two identical 1250 // LessThanOrEqual instructions. 1251 1252 public static int intConditionEqualZero(int i) { 1253 return ((i > 42) != $inline$false()) ? 13 : 54; 1254 } 1255 1256 // Test that conditions on float/double are not flipped. 1257 1258 /// CHECK-START: int Main.floatConditionNotEqualOne(float) builder (after) 1259 /// CHECK: LessThanOrEqual 1260 1261 /// CHECK-START: int Main.floatConditionNotEqualOne(float) instruction_simplifier_before_codegen (after) 1262 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1263 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1264 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1265 /// CHECK-DAG: <<Const42:f\d+>> FloatConstant 42 1266 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Arg>>,<<Const42>>] 1267 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE>>] 1268 /// CHECK-DAG: Return [<<Select>>] 1269 1270 public static int floatConditionNotEqualOne(float f) { 1271 return ((f > 42.0f) == true) ? 13 : 54; 1272 } 1273 1274 /// CHECK-START: int Main.doubleConditionEqualZero(double) builder (after) 1275 /// CHECK: LessThanOrEqual 1276 1277 /// CHECK-START: int Main.doubleConditionEqualZero(double) instruction_simplifier_before_codegen (after) 1278 /// CHECK-DAG: <<Arg:d\d+>> ParameterValue 1279 /// CHECK-DAG: <<Const13:i\d+>> IntConstant 13 1280 /// CHECK-DAG: <<Const54:i\d+>> IntConstant 54 1281 /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42 1282 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Arg>>,<<Const42>>] 1283 /// CHECK-DAG: <<Select:i\d+>> Select [<<Const13>>,<<Const54>>,<<LE>>] 1284 /// CHECK-DAG: Return [<<Select>>] 1285 1286 public static int doubleConditionEqualZero(double d) { 1287 return ((d > 42.0) != false) ? 13 : 54; 1288 } 1289 1290 /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (before) 1291 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1292 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1293 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] 1294 /// CHECK-DAG: Return [<<Int>>] 1295 1296 /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (after) 1297 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1298 /// CHECK-DAG: Return [<<Arg>>] 1299 1300 /// CHECK-START: int Main.intToDoubleToInt(int) instruction_simplifier (after) 1301 /// CHECK-NOT: TypeConversion 1302 1303 public static int intToDoubleToInt(int value) { 1304 // Lossless conversion followed by a conversion back. 1305 return (int) (double) value; 1306 } 1307 1308 /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (before) 1309 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1310 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1311 /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>] 1312 1313 /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (after) 1314 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1315 /// CHECK-DAG: {{d\d+}} TypeConversion [<<Arg>>] 1316 1317 /// CHECK-START: java.lang.String Main.intToDoubleToIntPrint(int) instruction_simplifier (after) 1318 /// CHECK-DAG: TypeConversion 1319 /// CHECK-NOT: TypeConversion 1320 1321 public static String intToDoubleToIntPrint(int value) { 1322 // Lossless conversion followed by a conversion back 1323 // with another use of the intermediate result. 1324 double d = (double) value; 1325 int i = (int) d; 1326 return "d=" + d + ", i=" + i; 1327 } 1328 1329 /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (before) 1330 /// CHECK-DAG: <<Arg:b\d+>> ParameterValue 1331 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1332 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] 1333 /// CHECK-DAG: Return [<<Int>>] 1334 1335 /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (after) 1336 /// CHECK-DAG: <<Arg:b\d+>> ParameterValue 1337 /// CHECK-DAG: Return [<<Arg>>] 1338 1339 /// CHECK-START: int Main.byteToDoubleToInt(byte) instruction_simplifier (after) 1340 /// CHECK-NOT: TypeConversion 1341 1342 public static int byteToDoubleToInt(byte value) { 1343 // Lossless conversion followed by another conversion, use implicit conversion. 1344 return (int) (double) value; 1345 } 1346 1347 /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (before) 1348 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1349 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1350 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] 1351 /// CHECK-DAG: Return [<<Int>>] 1352 1353 /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (after) 1354 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1355 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] 1356 /// CHECK-DAG: Return [<<Int>>] 1357 1358 /// CHECK-START: int Main.floatToDoubleToInt(float) instruction_simplifier (after) 1359 /// CHECK-DAG: TypeConversion 1360 /// CHECK-NOT: TypeConversion 1361 1362 public static int floatToDoubleToInt(float value) { 1363 // Lossless conversion followed by another conversion. 1364 return (int) (double) value; 1365 } 1366 1367 /// CHECK-START: java.lang.String Main.floatToDoubleToIntPrint(float) instruction_simplifier (before) 1368 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1369 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1370 /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>] 1371 1372 /// CHECK-START: java.lang.String Main.floatToDoubleToIntPrint(float) instruction_simplifier (after) 1373 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1374 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1375 /// CHECK-DAG: {{i\d+}} TypeConversion [<<Double>>] 1376 1377 public static String floatToDoubleToIntPrint(float value) { 1378 // Lossless conversion followed by another conversion with 1379 // an extra use of the intermediate result. 1380 double d = (double) value; 1381 int i = (int) d; 1382 return "d=" + d + ", i=" + i; 1383 } 1384 1385 /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (before) 1386 /// CHECK-DAG: <<Arg:b\d+>> ParameterValue 1387 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1388 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] 1389 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>] 1390 /// CHECK-DAG: Return [<<Short>>] 1391 1392 /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (after) 1393 /// CHECK-DAG: <<Arg:b\d+>> ParameterValue 1394 /// CHECK-DAG: Return [<<Arg>>] 1395 1396 /// CHECK-START: short Main.byteToDoubleToShort(byte) instruction_simplifier (after) 1397 /// CHECK-NOT: TypeConversion 1398 1399 public static short byteToDoubleToShort(byte value) { 1400 // Originally, this is byte->double->int->short. The first conversion is lossless, 1401 // so we merge this with the second one to byte->int which we omit as it's an implicit 1402 // conversion. Then we eliminate the resulting byte->short as an implicit conversion. 1403 return (short) (double) value; 1404 } 1405 1406 /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (before) 1407 /// CHECK-DAG: <<Arg:c\d+>> ParameterValue 1408 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1409 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Double>>] 1410 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>] 1411 /// CHECK-DAG: Return [<<Short>>] 1412 1413 /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (after) 1414 /// CHECK-DAG: <<Arg:c\d+>> ParameterValue 1415 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Arg>>] 1416 /// CHECK-DAG: Return [<<Short>>] 1417 1418 /// CHECK-START: short Main.charToDoubleToShort(char) instruction_simplifier (after) 1419 /// CHECK-DAG: TypeConversion 1420 /// CHECK-NOT: TypeConversion 1421 1422 public static short charToDoubleToShort(char value) { 1423 // Originally, this is char->double->int->short. The first conversion is lossless, 1424 // so we merge this with the second one to char->int which we omit as it's an implicit 1425 // conversion. Then we are left with the resulting char->short conversion. 1426 return (short) (double) value; 1427 } 1428 1429 /// CHECK-START: short Main.floatToIntToShort(float) instruction_simplifier (before) 1430 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1431 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] 1432 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>] 1433 /// CHECK-DAG: Return [<<Short>>] 1434 1435 /// CHECK-START: short Main.floatToIntToShort(float) instruction_simplifier (after) 1436 /// CHECK-DAG: <<Arg:f\d+>> ParameterValue 1437 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] 1438 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Int>>] 1439 /// CHECK-DAG: Return [<<Short>>] 1440 1441 public static short floatToIntToShort(float value) { 1442 // Lossy FP to integral conversion followed by another conversion: no simplification. 1443 return (short) value; 1444 } 1445 1446 /// CHECK-START: int Main.intToFloatToInt(int) instruction_simplifier (before) 1447 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1448 /// CHECK-DAG: <<Float:f\d+>> TypeConversion [<<Arg>>] 1449 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Float>>] 1450 /// CHECK-DAG: Return [<<Int>>] 1451 1452 /// CHECK-START: int Main.intToFloatToInt(int) instruction_simplifier (after) 1453 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1454 /// CHECK-DAG: <<Float:f\d+>> TypeConversion [<<Arg>>] 1455 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Float>>] 1456 /// CHECK-DAG: Return [<<Int>>] 1457 1458 public static int intToFloatToInt(int value) { 1459 // Lossy integral to FP conversion followed another conversion: no simplification. 1460 return (int) (float) value; 1461 } 1462 1463 /// CHECK-START: double Main.longToIntToDouble(long) instruction_simplifier (before) 1464 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 1465 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] 1466 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Int>>] 1467 /// CHECK-DAG: Return [<<Double>>] 1468 1469 /// CHECK-START: double Main.longToIntToDouble(long) instruction_simplifier (after) 1470 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 1471 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] 1472 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Int>>] 1473 /// CHECK-DAG: Return [<<Double>>] 1474 1475 public static double longToIntToDouble(long value) { 1476 // Lossy long-to-int conversion followed an integral to FP conversion: no simplification. 1477 return (double) (int) value; 1478 } 1479 1480 /// CHECK-START: long Main.longToIntToLong(long) instruction_simplifier (before) 1481 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 1482 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] 1483 /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Int>>] 1484 /// CHECK-DAG: Return [<<Long>>] 1485 1486 /// CHECK-START: long Main.longToIntToLong(long) instruction_simplifier (after) 1487 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 1488 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Arg>>] 1489 /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Int>>] 1490 /// CHECK-DAG: Return [<<Long>>] 1491 1492 public static long longToIntToLong(long value) { 1493 // Lossy long-to-int conversion followed an int-to-long conversion: no simplification. 1494 return (long) (int) value; 1495 } 1496 1497 /// CHECK-START: short Main.shortToCharToShort(short) instruction_simplifier (before) 1498 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1499 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] 1500 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<Char>>] 1501 /// CHECK-DAG: Return [<<Short>>] 1502 1503 /// CHECK-START: short Main.shortToCharToShort(short) instruction_simplifier (after) 1504 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1505 /// CHECK-DAG: Return [<<Arg>>] 1506 1507 public static short shortToCharToShort(short value) { 1508 // Integral conversion followed by non-widening integral conversion to original type. 1509 return (short) (char) value; 1510 } 1511 1512 /// CHECK-START: int Main.shortToLongToInt(short) instruction_simplifier (before) 1513 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1514 /// CHECK-DAG: <<Long:j\d+>> TypeConversion [<<Arg>>] 1515 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<Long>>] 1516 /// CHECK-DAG: Return [<<Int>>] 1517 1518 /// CHECK-START: int Main.shortToLongToInt(short) instruction_simplifier (after) 1519 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1520 /// CHECK-DAG: Return [<<Arg>>] 1521 1522 public static int shortToLongToInt(short value) { 1523 // Integral conversion followed by non-widening integral conversion, use implicit conversion. 1524 return (int) (long) value; 1525 } 1526 1527 /// CHECK-START: byte Main.shortToCharToByte(short) instruction_simplifier (before) 1528 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1529 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] 1530 /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Char>>] 1531 /// CHECK-DAG: Return [<<Byte>>] 1532 1533 /// CHECK-START: byte Main.shortToCharToByte(short) instruction_simplifier (after) 1534 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1535 /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Arg>>] 1536 /// CHECK-DAG: Return [<<Byte>>] 1537 1538 public static byte shortToCharToByte(short value) { 1539 // Integral conversion followed by non-widening integral conversion losing bits 1540 // from the original type. Simplify to use only one conversion. 1541 return (byte) (char) value; 1542 } 1543 1544 /// CHECK-START: java.lang.String Main.shortToCharToBytePrint(short) instruction_simplifier (before) 1545 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1546 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] 1547 /// CHECK-DAG: {{b\d+}} TypeConversion [<<Char>>] 1548 1549 /// CHECK-START: java.lang.String Main.shortToCharToBytePrint(short) instruction_simplifier (after) 1550 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1551 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] 1552 /// CHECK-DAG: {{b\d+}} TypeConversion [<<Char>>] 1553 1554 public static String shortToCharToBytePrint(short value) { 1555 // Integral conversion followed by non-widening integral conversion losing bits 1556 // from the original type with an extra use of the intermediate result. 1557 char c = (char) value; 1558 byte b = (byte) c; 1559 return "c=" + ((int) c) + ", b=" + ((int) b); // implicit conversions. 1560 } 1561 1562 /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (before) 1563 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 1564 /// CHECK-DAG: <<Mask:j\d+>> LongConstant 255 1565 /// CHECK-DAG: <<And:j\d+>> And [<<Mask>>,<<Arg>>] 1566 /// CHECK-DAG: <<Int:i\d+>> TypeConversion [<<And>>] 1567 /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Int>>] 1568 /// CHECK-DAG: Return [<<Byte>>] 1569 1570 /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (after) 1571 /// CHECK-DAG: <<Arg:j\d+>> ParameterValue 1572 /// CHECK-DAG: <<Byte:b\d+>> TypeConversion [<<Arg>>] 1573 /// CHECK-DAG: Return [<<Byte>>] 1574 1575 /// CHECK-START: byte Main.longAnd0xffToByte(long) instruction_simplifier (after) 1576 /// CHECK-NOT: And 1577 1578 public static byte longAnd0xffToByte(long value) { 1579 return (byte) (value & 0xff); 1580 } 1581 1582 /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (before) 1583 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1584 /// CHECK-DAG: <<Mask:i\d+>> IntConstant 131071 1585 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>] 1586 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<And>>] 1587 /// CHECK-DAG: Return [<<Char>>] 1588 1589 /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (after) 1590 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1591 /// CHECK-DAG: <<Char:c\d+>> TypeConversion [<<Arg>>] 1592 /// CHECK-DAG: Return [<<Char>>] 1593 1594 /// CHECK-START: char Main.intAnd0x1ffffToChar(int) instruction_simplifier (after) 1595 /// CHECK-NOT: And 1596 1597 public static char intAnd0x1ffffToChar(int value) { 1598 // Keeping all significant bits and one more. 1599 return (char) (value & 0x1ffff); 1600 } 1601 1602 /// CHECK-START: short Main.intAnd0x17fffToShort(int) instruction_simplifier (before) 1603 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1604 /// CHECK-DAG: <<Mask:i\d+>> IntConstant 98303 1605 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>] 1606 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<And>>] 1607 /// CHECK-DAG: Return [<<Short>>] 1608 1609 /// CHECK-START: short Main.intAnd0x17fffToShort(int) instruction_simplifier (after) 1610 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1611 /// CHECK-DAG: <<Mask:i\d+>> IntConstant 98303 1612 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>] 1613 /// CHECK-DAG: <<Short:s\d+>> TypeConversion [<<And>>] 1614 /// CHECK-DAG: Return [<<Short>>] 1615 1616 public static short intAnd0x17fffToShort(int value) { 1617 // No simplification: clearing a significant bit. 1618 return (short) (value & 0x17fff); 1619 } 1620 1621 /// CHECK-START: double Main.shortAnd0xffffToShortToDouble(short) instruction_simplifier (before) 1622 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1623 /// CHECK-DAG: <<Mask:i\d+>> IntConstant 65535 1624 /// CHECK-DAG: <<And:i\d+>> And [<<Mask>>,<<Arg>>] 1625 /// CHECK-DAG: <<Same:s\d+>> TypeConversion [<<And>>] 1626 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Same>>] 1627 /// CHECK-DAG: Return [<<Double>>] 1628 1629 /// CHECK-START: double Main.shortAnd0xffffToShortToDouble(short) instruction_simplifier (after) 1630 /// CHECK-DAG: <<Arg:s\d+>> ParameterValue 1631 /// CHECK-DAG: <<Double:d\d+>> TypeConversion [<<Arg>>] 1632 /// CHECK-DAG: Return [<<Double>>] 1633 1634 public static double shortAnd0xffffToShortToDouble(short value) { 1635 short same = (short) (value & 0xffff); 1636 return (double) same; 1637 } 1638 1639 /// CHECK-START: int Main.intReverseCondition(int) instruction_simplifier (before) 1640 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1641 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 1642 /// CHECK-DAG: <<LE:z\d+>> LessThanOrEqual [<<Const42>>,<<Arg>>] 1643 1644 /// CHECK-START: int Main.intReverseCondition(int) instruction_simplifier (after) 1645 /// CHECK-DAG: <<Arg:i\d+>> ParameterValue 1646 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42 1647 /// CHECK-DAG: <<GE:z\d+>> GreaterThanOrEqual [<<Arg>>,<<Const42>>] 1648 1649 public static int intReverseCondition(int i) { 1650 return (42 > i) ? 13 : 54; 1651 } 1652 1653 /// CHECK-START: int Main.intReverseConditionNaN(int) instruction_simplifier (before) 1654 /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42 1655 /// CHECK-DAG: <<Result:d\d+>> InvokeStaticOrDirect 1656 /// CHECK-DAG: <<CMP:i\d+>> Compare [<<Const42>>,<<Result>>] 1657 1658 /// CHECK-START: int Main.intReverseConditionNaN(int) instruction_simplifier (after) 1659 /// CHECK-DAG: <<Const42:d\d+>> DoubleConstant 42 1660 /// CHECK-DAG: <<Result:d\d+>> InvokeStaticOrDirect 1661 /// CHECK-DAG: <<EQ:z\d+>> Equal [<<Result>>,<<Const42>>] 1662 1663 public static int intReverseConditionNaN(int i) { 1664 return (42 != Math.sqrt(i)) ? 13 : 54; 1665 } 1666 1667 public static int runSmaliTest(String name, boolean input) { 1668 try { 1669 Class<?> c = Class.forName("SmaliTests"); 1670 Method m = c.getMethod(name, new Class[] { boolean.class }); 1671 return (Integer) m.invoke(null, input); 1672 } catch (Exception ex) { 1673 throw new Error(ex); 1674 } 1675 } 1676 1677 public static void main(String[] args) { 1678 int arg = 123456; 1679 1680 assertLongEquals(Add0(arg), arg); 1681 assertIntEquals(AndAllOnes(arg), arg); 1682 assertLongEquals(Div1(arg), arg); 1683 assertIntEquals(DivN1(arg), -arg); 1684 assertLongEquals(Mul1(arg), arg); 1685 assertIntEquals(MulN1(arg), -arg); 1686 assertLongEquals(MulPowerOfTwo128(arg), (128 * arg)); 1687 assertIntEquals(Or0(arg), arg); 1688 assertLongEquals(OrSame(arg), arg); 1689 assertIntEquals(Shl0(arg), arg); 1690 assertLongEquals(Shr0(arg), arg); 1691 assertLongEquals(Shr64(arg), arg); 1692 assertLongEquals(Sub0(arg), arg); 1693 assertIntEquals(SubAliasNeg(arg), -arg); 1694 assertLongEquals(UShr0(arg), arg); 1695 assertIntEquals(Xor0(arg), arg); 1696 assertIntEquals(XorAllOnes(arg), ~arg); 1697 assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1)); 1698 assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1)); 1699 assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1)); 1700 assertLongEquals(AddNeg1(arg, arg + 1), 1); 1701 assertLongEquals(AddNeg2(arg, arg + 1), -1); 1702 assertLongEquals(NegNeg1(arg), arg); 1703 assertIntEquals(NegNeg2(arg), 0); 1704 assertLongEquals(NegNeg3(arg), arg); 1705 assertIntEquals(NegSub1(arg, arg + 1), 1); 1706 assertIntEquals(NegSub2(arg, arg + 1), 1); 1707 assertLongEquals(NotNot1(arg), arg); 1708 assertIntEquals(NotNot2(arg), -1); 1709 assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1)); 1710 assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1)); 1711 assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1)); 1712 assertBooleanEquals(EqualBoolVsIntConst(true), true); 1713 assertBooleanEquals(EqualBoolVsIntConst(true), true); 1714 assertBooleanEquals(NotEqualBoolVsIntConst(false), false); 1715 assertBooleanEquals(NotEqualBoolVsIntConst(false), false); 1716 assertBooleanEquals(NotNotBool(true), true); 1717 assertBooleanEquals(NotNotBool(false), false); 1718 assertFloatEquals(Div2(100.0f), 50.0f); 1719 assertDoubleEquals(Div2(150.0), 75.0); 1720 assertFloatEquals(DivMP25(100.0f), -400.0f); 1721 assertDoubleEquals(DivMP25(150.0), -600.0); 1722 assertIntEquals(UShr28And15(0xc1234567), 0xc); 1723 assertLongEquals(UShr60And15(0xc123456787654321L), 0xcL); 1724 assertIntEquals(UShr28And7(0xc1234567), 0x4); 1725 assertLongEquals(UShr60And7(0xc123456787654321L), 0x4L); 1726 assertIntEquals(Shr24And255(0xc1234567), 0xc1); 1727 assertLongEquals(Shr56And255(0xc123456787654321L), 0xc1L); 1728 assertIntEquals(Shr24And127(0xc1234567), 0x41); 1729 assertLongEquals(Shr56And127(0xc123456787654321L), 0x41L); 1730 assertIntEquals(0, mulPow2Plus1(0)); 1731 assertIntEquals(9, mulPow2Plus1(1)); 1732 assertIntEquals(18, mulPow2Plus1(2)); 1733 assertIntEquals(900, mulPow2Plus1(100)); 1734 assertIntEquals(111105, mulPow2Plus1(12345)); 1735 assertLongEquals(0, mulPow2Minus1(0)); 1736 assertLongEquals(31, mulPow2Minus1(1)); 1737 assertLongEquals(62, mulPow2Minus1(2)); 1738 assertLongEquals(3100, mulPow2Minus1(100)); 1739 assertLongEquals(382695, mulPow2Minus1(12345)); 1740 1741 booleanField = false; 1742 assertIntEquals(booleanFieldNotEqualOne(), 54); 1743 assertIntEquals(booleanFieldEqualZero(), 54); 1744 booleanField = true; 1745 assertIntEquals(booleanFieldNotEqualOne(), 13); 1746 assertIntEquals(booleanFieldEqualZero(), 13); 1747 assertIntEquals(intConditionNotEqualOne(6), 54); 1748 assertIntEquals(intConditionNotEqualOne(43), 13); 1749 assertIntEquals(intConditionEqualZero(6), 54); 1750 assertIntEquals(intConditionEqualZero(43), 13); 1751 assertIntEquals(floatConditionNotEqualOne(6.0f), 54); 1752 assertIntEquals(floatConditionNotEqualOne(43.0f), 13); 1753 assertIntEquals(doubleConditionEqualZero(6.0), 54); 1754 assertIntEquals(doubleConditionEqualZero(43.0), 13); 1755 1756 assertIntEquals(1234567, intToDoubleToInt(1234567)); 1757 assertIntEquals(Integer.MIN_VALUE, intToDoubleToInt(Integer.MIN_VALUE)); 1758 assertIntEquals(Integer.MAX_VALUE, intToDoubleToInt(Integer.MAX_VALUE)); 1759 assertStringEquals("d=7654321.0, i=7654321", intToDoubleToIntPrint(7654321)); 1760 assertIntEquals(12, byteToDoubleToInt((byte) 12)); 1761 assertIntEquals(Byte.MIN_VALUE, byteToDoubleToInt(Byte.MIN_VALUE)); 1762 assertIntEquals(Byte.MAX_VALUE, byteToDoubleToInt(Byte.MAX_VALUE)); 1763 assertIntEquals(11, floatToDoubleToInt(11.3f)); 1764 assertStringEquals("d=12.25, i=12", floatToDoubleToIntPrint(12.25f)); 1765 assertIntEquals(123, byteToDoubleToShort((byte) 123)); 1766 assertIntEquals(Byte.MIN_VALUE, byteToDoubleToShort(Byte.MIN_VALUE)); 1767 assertIntEquals(Byte.MAX_VALUE, byteToDoubleToShort(Byte.MAX_VALUE)); 1768 assertIntEquals(1234, charToDoubleToShort((char) 1234)); 1769 assertIntEquals(Character.MIN_VALUE, charToDoubleToShort(Character.MIN_VALUE)); 1770 assertIntEquals(/* sign-extended */ -1, charToDoubleToShort(Character.MAX_VALUE)); 1771 assertIntEquals(12345, floatToIntToShort(12345.75f)); 1772 assertIntEquals(Short.MAX_VALUE, floatToIntToShort((float)(Short.MIN_VALUE - 1))); 1773 assertIntEquals(Short.MIN_VALUE, floatToIntToShort((float)(Short.MAX_VALUE + 1))); 1774 assertIntEquals(-54321, intToFloatToInt(-54321)); 1775 assertDoubleEquals((double) 0x12345678, longToIntToDouble(0x1234567812345678L)); 1776 assertDoubleEquals(0.0, longToIntToDouble(Long.MIN_VALUE)); 1777 assertDoubleEquals(-1.0, longToIntToDouble(Long.MAX_VALUE)); 1778 assertLongEquals(0x0000000012345678L, longToIntToLong(0x1234567812345678L)); 1779 assertLongEquals(0xffffffff87654321L, longToIntToLong(0x1234567887654321L)); 1780 assertLongEquals(0L, longToIntToLong(Long.MIN_VALUE)); 1781 assertLongEquals(-1L, longToIntToLong(Long.MAX_VALUE)); 1782 assertIntEquals((short) -5678, shortToCharToShort((short) -5678)); 1783 assertIntEquals(Short.MIN_VALUE, shortToCharToShort(Short.MIN_VALUE)); 1784 assertIntEquals(Short.MAX_VALUE, shortToCharToShort(Short.MAX_VALUE)); 1785 assertIntEquals(5678, shortToLongToInt((short) 5678)); 1786 assertIntEquals(Short.MIN_VALUE, shortToLongToInt(Short.MIN_VALUE)); 1787 assertIntEquals(Short.MAX_VALUE, shortToLongToInt(Short.MAX_VALUE)); 1788 assertIntEquals(0x34, shortToCharToByte((short) 0x1234)); 1789 assertIntEquals(-0x10, shortToCharToByte((short) 0x12f0)); 1790 assertIntEquals(0, shortToCharToByte(Short.MIN_VALUE)); 1791 assertIntEquals(-1, shortToCharToByte(Short.MAX_VALUE)); 1792 assertStringEquals("c=1025, b=1", shortToCharToBytePrint((short) 1025)); 1793 assertStringEquals("c=1023, b=-1", shortToCharToBytePrint((short) 1023)); 1794 assertStringEquals("c=65535, b=-1", shortToCharToBytePrint((short) -1)); 1795 1796 assertIntEquals(0x21, longAnd0xffToByte(0x1234432112344321L)); 1797 assertIntEquals(0, longAnd0xffToByte(Long.MIN_VALUE)); 1798 assertIntEquals(-1, longAnd0xffToByte(Long.MAX_VALUE)); 1799 assertIntEquals(0x1234, intAnd0x1ffffToChar(0x43211234)); 1800 assertIntEquals(0, intAnd0x1ffffToChar(Integer.MIN_VALUE)); 1801 assertIntEquals(Character.MAX_VALUE, intAnd0x1ffffToChar(Integer.MAX_VALUE)); 1802 assertIntEquals(0x4321, intAnd0x17fffToShort(0x87654321)); 1803 assertIntEquals(0x0888, intAnd0x17fffToShort(0x88888888)); 1804 assertIntEquals(0, intAnd0x17fffToShort(Integer.MIN_VALUE)); 1805 assertIntEquals(Short.MAX_VALUE, intAnd0x17fffToShort(Integer.MAX_VALUE)); 1806 1807 assertDoubleEquals(0.0, shortAnd0xffffToShortToDouble((short) 0)); 1808 assertDoubleEquals(1.0, shortAnd0xffffToShortToDouble((short) 1)); 1809 assertDoubleEquals(-2.0, shortAnd0xffffToShortToDouble((short) -2)); 1810 assertDoubleEquals(12345.0, shortAnd0xffffToShortToDouble((short) 12345)); 1811 assertDoubleEquals((double)Short.MAX_VALUE, shortAnd0xffffToShortToDouble(Short.MAX_VALUE)); 1812 assertDoubleEquals((double)Short.MIN_VALUE, shortAnd0xffffToShortToDouble(Short.MIN_VALUE)); 1813 1814 assertIntEquals(intReverseCondition(41), 13); 1815 assertIntEquals(intReverseConditionNaN(-5), 13); 1816 1817 for (String condition : new String[] { "Equal", "NotEqual" }) { 1818 for (String constant : new String[] { "True", "False" }) { 1819 for (String side : new String[] { "Rhs", "Lhs" }) { 1820 String name = condition + constant + side; 1821 assertIntEquals(runSmaliTest(name, true), 5); 1822 assertIntEquals(runSmaliTest(name, false), 3); 1823 } 1824 } 1825 } 1826 } 1827 1828 private static boolean $inline$true() { return true; } 1829 private static boolean $inline$false() { return false; } 1830 1831 public static boolean booleanField; 1832 } 1833