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 assertBooleanEquals(boolean expected, boolean result)19 public static void assertBooleanEquals(boolean expected, boolean result) { 20 if (expected != result) { 21 throw new Error("Expected: " + expected + ", found: " + result); 22 } 23 } 24 assertIntEquals(int expected, int result)25 public static void assertIntEquals(int expected, int result) { 26 if (expected != result) { 27 throw new Error("Expected: " + expected + ", found: " + result); 28 } 29 } 30 assertLongEquals(long expected, long result)31 public static void assertLongEquals(long expected, long result) { 32 if (expected != result) { 33 throw new Error("Expected: " + expected + ", found: " + result); 34 } 35 } 36 assertFloatEquals(float expected, float result)37 public static void assertFloatEquals(float expected, float result) { 38 if (expected != result) { 39 throw new Error("Expected: " + expected + ", found: " + result); 40 } 41 } 42 assertDoubleEquals(double expected, double result)43 public static void assertDoubleEquals(double expected, double result) { 44 if (expected != result) { 45 throw new Error("Expected: " + expected + ", found: " + result); 46 } 47 } 48 49 /** 50 * Tiny programs exercising optimizations of arithmetic identities. 51 */ 52 53 // CHECK-START: long Main.Add0(long) instruction_simplifier (before) 54 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 55 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0 56 // CHECK-DAG: [[Add:j\d+]] Add [ [[Const0]] [[Arg]] ] 57 // CHECK-DAG: Return [ [[Add]] ] 58 59 // CHECK-START: long Main.Add0(long) instruction_simplifier (after) 60 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 61 // CHECK-DAG: Return [ [[Arg]] ] 62 63 // CHECK-START: long Main.Add0(long) instruction_simplifier (after) 64 // CHECK-NOT: Add 65 Add0(long arg)66 public static long Add0(long arg) { 67 return 0 + arg; 68 } 69 70 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (before) 71 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 72 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1 73 // CHECK-DAG: [[And:i\d+]] And [ [[Arg]] [[ConstF]] ] 74 // CHECK-DAG: Return [ [[And]] ] 75 76 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after) 77 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 78 // CHECK-DAG: Return [ [[Arg]] ] 79 80 // CHECK-START: int Main.AndAllOnes(int) instruction_simplifier (after) 81 // CHECK-NOT: And 82 AndAllOnes(int arg)83 public static int AndAllOnes(int arg) { 84 return arg & -1; 85 } 86 87 // CHECK-START: long Main.Div1(long) instruction_simplifier (before) 88 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 89 // CHECK-DAG: [[Const1:j\d+]] LongConstant 1 90 // CHECK-DAG: [[Div:j\d+]] Div [ [[Arg]] [[Const1]] ] 91 // CHECK-DAG: Return [ [[Div]] ] 92 93 // CHECK-START: long Main.Div1(long) instruction_simplifier (after) 94 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 95 // CHECK-DAG: Return [ [[Arg]] ] 96 97 // CHECK-START: long Main.Div1(long) instruction_simplifier (after) 98 // CHECK-NOT: Div 99 Div1(long arg)100 public static long Div1(long arg) { 101 return arg / 1; 102 } 103 104 // CHECK-START: int Main.DivN1(int) instruction_simplifier (before) 105 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 106 // CHECK-DAG: [[ConstN1:i\d+]] IntConstant -1 107 // CHECK-DAG: [[Div:i\d+]] Div [ [[Arg]] [[ConstN1]] ] 108 // CHECK-DAG: Return [ [[Div]] ] 109 110 // CHECK-START: int Main.DivN1(int) instruction_simplifier (after) 111 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 112 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ] 113 // CHECK-DAG: Return [ [[Neg]] ] 114 115 // CHECK-START: int Main.DivN1(int) instruction_simplifier (after) 116 // CHECK-NOT: Div 117 DivN1(int arg)118 public static int DivN1(int arg) { 119 return arg / -1; 120 } 121 122 // CHECK-START: long Main.Mul1(long) instruction_simplifier (before) 123 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 124 // CHECK-DAG: [[Const1:j\d+]] LongConstant 1 125 // CHECK-DAG: [[Mul:j\d+]] Mul [ [[Arg]] [[Const1]] ] 126 // CHECK-DAG: Return [ [[Mul]] ] 127 128 // CHECK-START: long Main.Mul1(long) instruction_simplifier (after) 129 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 130 // CHECK-DAG: Return [ [[Arg]] ] 131 132 // CHECK-START: long Main.Mul1(long) instruction_simplifier (after) 133 // CHECK-NOT: Mul 134 Mul1(long arg)135 public static long Mul1(long arg) { 136 return arg * 1; 137 } 138 139 // CHECK-START: int Main.MulN1(int) instruction_simplifier (before) 140 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 141 // CHECK-DAG: [[ConstN1:i\d+]] IntConstant -1 142 // CHECK-DAG: [[Mul:i\d+]] Mul [ [[Arg]] [[ConstN1]] ] 143 // CHECK-DAG: Return [ [[Mul]] ] 144 145 // CHECK-START: int Main.MulN1(int) instruction_simplifier (after) 146 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 147 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg]] ] 148 // CHECK-DAG: Return [ [[Neg]] ] 149 150 // CHECK-START: int Main.MulN1(int) instruction_simplifier (after) 151 // CHECK-NOT: Mul 152 MulN1(int arg)153 public static int MulN1(int arg) { 154 return arg * -1; 155 } 156 157 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (before) 158 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 159 // CHECK-DAG: [[Const128:j\d+]] LongConstant 128 160 // CHECK-DAG: [[Mul:j\d+]] Mul [ [[Arg]] [[Const128]] ] 161 // CHECK-DAG: Return [ [[Mul]] ] 162 163 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after) 164 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 165 // CHECK-DAG: [[Const7:i\d+]] IntConstant 7 166 // CHECK-DAG: [[Shl:j\d+]] Shl [ [[Arg]] [[Const7]] ] 167 // CHECK-DAG: Return [ [[Shl]] ] 168 169 // CHECK-START: long Main.MulPowerOfTwo128(long) instruction_simplifier (after) 170 // CHECK-NOT: Mul 171 MulPowerOfTwo128(long arg)172 public static long MulPowerOfTwo128(long arg) { 173 return arg * 128; 174 } 175 176 // CHECK-START: int Main.Or0(int) instruction_simplifier (before) 177 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 178 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 179 // CHECK-DAG: [[Or:i\d+]] Or [ [[Arg]] [[Const0]] ] 180 // CHECK-DAG: Return [ [[Or]] ] 181 182 // CHECK-START: int Main.Or0(int) instruction_simplifier (after) 183 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 184 // CHECK-DAG: Return [ [[Arg]] ] 185 186 // CHECK-START: int Main.Or0(int) instruction_simplifier (after) 187 // CHECK-NOT: Or 188 Or0(int arg)189 public static int Or0(int arg) { 190 return arg | 0; 191 } 192 193 // CHECK-START: long Main.OrSame(long) instruction_simplifier (before) 194 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 195 // CHECK-DAG: [[Or:j\d+]] Or [ [[Arg]] [[Arg]] ] 196 // CHECK-DAG: Return [ [[Or]] ] 197 198 // CHECK-START: long Main.OrSame(long) instruction_simplifier (after) 199 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 200 // CHECK-DAG: Return [ [[Arg]] ] 201 202 // CHECK-START: long Main.OrSame(long) instruction_simplifier (after) 203 // CHECK-NOT: Or 204 OrSame(long arg)205 public static long OrSame(long arg) { 206 return arg | arg; 207 } 208 209 // CHECK-START: int Main.Shl0(int) instruction_simplifier (before) 210 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 211 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 212 // CHECK-DAG: [[Shl:i\d+]] Shl [ [[Arg]] [[Const0]] ] 213 // CHECK-DAG: Return [ [[Shl]] ] 214 215 // CHECK-START: int Main.Shl0(int) instruction_simplifier (after) 216 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 217 // CHECK-DAG: Return [ [[Arg]] ] 218 219 // CHECK-START: int Main.Shl0(int) instruction_simplifier (after) 220 // CHECK-NOT: Shl 221 Shl0(int arg)222 public static int Shl0(int arg) { 223 return arg << 0; 224 } 225 226 // CHECK-START: int Main.Shl1(int) instruction_simplifier (before) 227 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 228 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 229 // CHECK-DAG: [[Shl:i\d+]] Shl [ [[Arg]] [[Const1]] ] 230 // CHECK-DAG: Return [ [[Shl]] ] 231 232 // CHECK-START: int Main.Shl1(int) instruction_simplifier (after) 233 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 234 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg]] [[Arg]] ] 235 // CHECK-DAG: Return [ [[Add]] ] 236 237 // CHECK-START: int Main.Shl1(int) instruction_simplifier (after) 238 // CHECK-NOT: Shl 239 Shl1(int arg)240 public static int Shl1(int arg) { 241 return arg << 1; 242 } 243 244 // CHECK-START: long Main.Shr0(long) instruction_simplifier (before) 245 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 246 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 247 // CHECK-DAG: [[Shr:j\d+]] Shr [ [[Arg]] [[Const0]] ] 248 // CHECK-DAG: Return [ [[Shr]] ] 249 250 // CHECK-START: long Main.Shr0(long) instruction_simplifier (after) 251 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 252 // CHECK-DAG: Return [ [[Arg]] ] 253 254 // CHECK-START: long Main.Shr0(long) instruction_simplifier (after) 255 // CHECK-NOT: Shr 256 Shr0(long arg)257 public static long Shr0(long arg) { 258 return arg >> 0; 259 } 260 261 // CHECK-START: long Main.Sub0(long) instruction_simplifier (before) 262 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 263 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0 264 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg]] [[Const0]] ] 265 // CHECK-DAG: Return [ [[Sub]] ] 266 267 // CHECK-START: long Main.Sub0(long) instruction_simplifier (after) 268 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 269 // CHECK-DAG: Return [ [[Arg]] ] 270 271 // CHECK-START: long Main.Sub0(long) instruction_simplifier (after) 272 // CHECK-NOT: Sub 273 Sub0(long arg)274 public static long Sub0(long arg) { 275 return arg - 0; 276 } 277 278 // CHECK-START: int Main.SubAliasNeg(int) instruction_simplifier (before) 279 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 280 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 281 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Const0]] [[Arg]] ] 282 // CHECK-DAG: Return [ [[Sub]] ] 283 284 // CHECK-START: int Main.SubAliasNeg(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.SubAliasNeg(int) instruction_simplifier (after) 290 // CHECK-NOT: Sub 291 SubAliasNeg(int arg)292 public static int SubAliasNeg(int arg) { 293 return 0 - arg; 294 } 295 296 // CHECK-START: long Main.UShr0(long) instruction_simplifier (before) 297 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 298 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 299 // CHECK-DAG: [[UShr:j\d+]] UShr [ [[Arg]] [[Const0]] ] 300 // CHECK-DAG: Return [ [[UShr]] ] 301 302 // CHECK-START: long Main.UShr0(long) instruction_simplifier (after) 303 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 304 // CHECK-DAG: Return [ [[Arg]] ] 305 306 // CHECK-START: long Main.UShr0(long) instruction_simplifier (after) 307 // CHECK-NOT: UShr 308 UShr0(long arg)309 public static long UShr0(long arg) { 310 return arg >>> 0; 311 } 312 313 // CHECK-START: int Main.Xor0(int) instruction_simplifier (before) 314 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 315 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 316 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[Const0]] ] 317 // CHECK-DAG: Return [ [[Xor]] ] 318 319 // CHECK-START: int Main.Xor0(int) instruction_simplifier (after) 320 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 321 // CHECK-DAG: Return [ [[Arg]] ] 322 323 // CHECK-START: int Main.Xor0(int) instruction_simplifier (after) 324 // CHECK-NOT: Xor 325 Xor0(int arg)326 public static int Xor0(int arg) { 327 return arg ^ 0; 328 } 329 330 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (before) 331 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 332 // CHECK-DAG: [[ConstF:i\d+]] IntConstant -1 333 // CHECK-DAG: [[Xor:i\d+]] Xor [ [[Arg]] [[ConstF]] ] 334 // CHECK-DAG: Return [ [[Xor]] ] 335 336 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after) 337 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 338 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ] 339 // CHECK-DAG: Return [ [[Not]] ] 340 341 // CHECK-START: int Main.XorAllOnes(int) instruction_simplifier (after) 342 // CHECK-NOT: Xor 343 XorAllOnes(int arg)344 public static int XorAllOnes(int arg) { 345 return arg ^ -1; 346 } 347 348 /** 349 * Test that addition or subtraction operation with both inputs negated are 350 * optimized to use a single negation after the operation. 351 * The transformation tested is implemented in 352 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`. 353 */ 354 355 // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (before) 356 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 357 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 358 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ] 359 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ] 360 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ] 361 // CHECK-DAG: Return [ [[Add]] ] 362 363 // CHECK-START: int Main.AddNegs1(int, int) instruction_simplifier (after) 364 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 365 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 366 // CHECK-NOT: Neg 367 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ] 368 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ] 369 // CHECK-DAG: Return [ [[Neg]] ] 370 AddNegs1(int arg1, int arg2)371 public static int AddNegs1(int arg1, int arg2) { 372 return -arg1 + -arg2; 373 } 374 375 /** 376 * This is similar to the test-case AddNegs1, but the negations have 377 * multiple uses. 378 * The transformation tested is implemented in 379 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`. 380 * The current code won't perform the previous optimization. The 381 * transformations do not look at other uses of their inputs. As they don't 382 * know what will happen with other uses, they do not take the risk of 383 * increasing the register pressure by creating or extending live ranges. 384 */ 385 386 // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (before) 387 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 388 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 389 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ] 390 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ] 391 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Neg1]] [[Neg2]] ] 392 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Neg1]] [[Neg2]] ] 393 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add1]] [[Add2]] ] 394 // CHECK-DAG: Return [ [[Or]] ] 395 396 // CHECK-START: int Main.AddNegs2(int, int) instruction_simplifier (after) 397 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 398 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 399 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ] 400 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ] 401 // CHECK-DAG: [[Add1:i\d+]] Add [ [[Neg1]] [[Neg2]] ] 402 // CHECK-DAG: [[Add2:i\d+]] Add [ [[Neg1]] [[Neg2]] ] 403 // CHECK-NOT: Neg 404 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add1]] [[Add2]] ] 405 // CHECK-DAG: Return [ [[Or]] ] 406 407 // CHECK-START: int Main.AddNegs2(int, int) GVN (after) 408 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 409 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 410 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg1]] ] 411 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Arg2]] ] 412 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ] 413 // CHECK-DAG: [[Or:i\d+]] Or [ [[Add]] [[Add]] ] 414 // CHECK-DAG: Return [ [[Or]] ] 415 AddNegs2(int arg1, int arg2)416 public static int AddNegs2(int arg1, int arg2) { 417 int temp1 = -arg1; 418 int temp2 = -arg2; 419 return (temp1 + temp2) | (temp1 + temp2); 420 } 421 422 /** 423 * This follows test-cases AddNegs1 and AddNegs2. 424 * The transformation tested is implemented in 425 * `InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop`. 426 * The optimization should not happen if it moves an additional instruction in 427 * the loop. 428 */ 429 430 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (before) 431 // -------------- Arguments and initial negation operations. 432 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue 433 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue 434 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ] 435 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ] 436 // CHECK: Goto 437 // -------------- Loop 438 // CHECK: SuspendCheck 439 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ] 440 // CHECK: Goto 441 442 // CHECK-START: long Main.AddNegs3(long, long) instruction_simplifier (after) 443 // -------------- Arguments and initial negation operations. 444 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue 445 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue 446 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg1]] ] 447 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Arg2]] ] 448 // CHECK: Goto 449 // -------------- Loop 450 // CHECK: SuspendCheck 451 // CHECK: [[Add:j\d+]] Add [ [[Neg1]] [[Neg2]] ] 452 // CHECK-NOT: Neg 453 // CHECK: Goto 454 AddNegs3(long arg1, long arg2)455 public static long AddNegs3(long arg1, long arg2) { 456 long res = 0; 457 long n_arg1 = -arg1; 458 long n_arg2 = -arg2; 459 for (long i = 0; i < 1; i++) { 460 res += n_arg1 + n_arg2 + i; 461 } 462 return res; 463 } 464 465 /** 466 * Test the simplification of an addition with a negated argument into a 467 * subtraction. 468 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`. 469 */ 470 471 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (before) 472 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue 473 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue 474 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ] 475 // CHECK-DAG: [[Add:j\d+]] Add [ [[Neg]] [[Arg2]] ] 476 // CHECK-DAG: Return [ [[Add]] ] 477 478 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after) 479 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue 480 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue 481 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Arg2]] [[Arg1]] ] 482 // CHECK-DAG: Return [ [[Sub]] ] 483 484 // CHECK-START: long Main.AddNeg1(long, long) instruction_simplifier (after) 485 // CHECK-NOT: Neg 486 // CHECK-NOT: Add 487 AddNeg1(long arg1, long arg2)488 public static long AddNeg1(long arg1, long arg2) { 489 return -arg1 + arg2; 490 } 491 492 /** 493 * This is similar to the test-case AddNeg1, but the negation has two uses. 494 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitAdd`. 495 * The current code won't perform the previous optimization. The 496 * transformations do not look at other uses of their inputs. As they don't 497 * know what will happen with other uses, they do not take the risk of 498 * increasing the register pressure by creating or extending live ranges. 499 */ 500 501 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (before) 502 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue 503 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue 504 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ] 505 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ] 506 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ] 507 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ] 508 // CHECK-DAG: Return [ [[Res]] ] 509 510 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after) 511 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue 512 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue 513 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg2]] ] 514 // CHECK-DAG: [[Add1:j\d+]] Add [ [[Arg1]] [[Neg]] ] 515 // CHECK-DAG: [[Add2:j\d+]] Add [ [[Arg1]] [[Neg]] ] 516 // CHECK-DAG: [[Res:j\d+]] Or [ [[Add1]] [[Add2]] ] 517 // CHECK-DAG: Return [ [[Res]] ] 518 519 // CHECK-START: long Main.AddNeg2(long, long) instruction_simplifier (after) 520 // CHECK-NOT: Sub 521 AddNeg2(long arg1, long arg2)522 public static long AddNeg2(long arg1, long arg2) { 523 long temp = -arg2; 524 return (arg1 + temp) | (arg1 + temp); 525 } 526 527 /** 528 * Test simplification of the `-(-var)` pattern. 529 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`. 530 */ 531 532 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (before) 533 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 534 // CHECK-DAG: [[Neg1:j\d+]] Neg [ [[Arg]] ] 535 // CHECK-DAG: [[Neg2:j\d+]] Neg [ [[Neg1]] ] 536 // CHECK-DAG: Return [ [[Neg2]] ] 537 538 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after) 539 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 540 // CHECK-DAG: Return [ [[Arg]] ] 541 542 // CHECK-START: long Main.NegNeg1(long) instruction_simplifier (after) 543 // CHECK-NOT: Neg 544 NegNeg1(long arg)545 public static long NegNeg1(long arg) { 546 return -(-arg); 547 } 548 549 /** 550 * Test 'multi-step' simplification, where a first transformation yields a 551 * new simplification possibility for the current instruction. 552 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg` 553 * and in `InstructionSimplifierVisitor::VisitAdd`. 554 */ 555 556 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (before) 557 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 558 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Arg]] ] 559 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Neg1]] ] 560 // CHECK-DAG: [[Add:i\d+]] Add [ [[Neg1]] [[Neg2]] ] 561 // CHECK-DAG: Return [ [[Add]] ] 562 563 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after) 564 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 565 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg]] [[Arg]] ] 566 // CHECK-DAG: Return [ [[Sub]] ] 567 568 // CHECK-START: int Main.NegNeg2(int) instruction_simplifier (after) 569 // CHECK-NOT: Neg 570 // CHECK-NOT: Add 571 572 // CHECK-START: int Main.NegNeg2(int) constant_folding_after_inlining (after) 573 // CHECK: [[Const0:i\d+]] IntConstant 0 574 // CHECK-NOT: Neg 575 // CHECK-NOT: Add 576 // CHECK: Return [ [[Const0]] ] 577 NegNeg2(int arg)578 public static int NegNeg2(int arg) { 579 int temp = -arg; 580 return temp + -temp; 581 } 582 583 /** 584 * Test another 'multi-step' simplification, where a first transformation 585 * yields a new simplification possibility for the current instruction. 586 * The transformations tested are implemented in `InstructionSimplifierVisitor::VisitNeg` 587 * and in `InstructionSimplifierVisitor::VisitSub`. 588 */ 589 590 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (before) 591 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 592 // CHECK-DAG: [[Const0:j\d+]] LongConstant 0 593 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg]] ] 594 // CHECK-DAG: [[Sub:j\d+]] Sub [ [[Const0]] [[Neg]] ] 595 // CHECK-DAG: Return [ [[Sub]] ] 596 597 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after) 598 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 599 // CHECK-DAG: Return [ [[Arg]] ] 600 601 // CHECK-START: long Main.NegNeg3(long) instruction_simplifier (after) 602 // CHECK-NOT: Neg 603 // CHECK-NOT: Sub 604 NegNeg3(long arg)605 public static long NegNeg3(long arg) { 606 return 0 - -arg; 607 } 608 609 /** 610 * Test that a negated subtraction is simplified to a subtraction with its 611 * arguments reversed. 612 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`. 613 */ 614 615 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (before) 616 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 617 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 618 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ] 619 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Sub]] ] 620 // CHECK-DAG: Return [ [[Neg]] ] 621 622 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after) 623 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 624 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 625 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg2]] [[Arg1]] ] 626 // CHECK-DAG: Return [ [[Sub]] ] 627 628 // CHECK-START: int Main.NegSub1(int, int) instruction_simplifier (after) 629 // CHECK-NOT: Neg 630 NegSub1(int arg1, int arg2)631 public static int NegSub1(int arg1, int arg2) { 632 return -(arg1 - arg2); 633 } 634 635 /** 636 * This is similar to the test-case NegSub1, but the subtraction has 637 * multiple uses. 638 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNeg`. 639 * The current code won't perform the previous optimization. The 640 * transformations do not look at other uses of their inputs. As they don't 641 * know what will happen with other uses, they do not take the risk of 642 * increasing the register pressure by creating or extending live ranges. 643 */ 644 645 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (before) 646 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 647 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 648 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ] 649 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ] 650 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ] 651 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ] 652 // CHECK-DAG: Return [ [[Or]] ] 653 654 // CHECK-START: int Main.NegSub2(int, int) instruction_simplifier (after) 655 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 656 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 657 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Arg1]] [[Arg2]] ] 658 // CHECK-DAG: [[Neg1:i\d+]] Neg [ [[Sub]] ] 659 // CHECK-DAG: [[Neg2:i\d+]] Neg [ [[Sub]] ] 660 // CHECK-DAG: [[Or:i\d+]] Or [ [[Neg1]] [[Neg2]] ] 661 // CHECK-DAG: Return [ [[Or]] ] 662 NegSub2(int arg1, int arg2)663 public static int NegSub2(int arg1, int arg2) { 664 int temp = arg1 - arg2; 665 return -temp | -temp; 666 } 667 668 /** 669 * Test simplification of the `~~var` pattern. 670 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`. 671 */ 672 673 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (before) 674 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 675 // CHECK-DAG: [[ConstF1:j\d+]] LongConstant -1 676 // CHECK-DAG: [[Xor1:j\d+]] Xor [ [[Arg]] [[ConstF1]] ] 677 // CHECK-DAG: [[Xor2:j\d+]] Xor [ [[Xor1]] [[ConstF1]] ] 678 // CHECK-DAG: Return [ [[Xor2]] ] 679 680 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after) 681 // CHECK-DAG: [[Arg:j\d+]] ParameterValue 682 // CHECK-DAG: Return [ [[Arg]] ] 683 684 // CHECK-START: long Main.NotNot1(long) instruction_simplifier (after) 685 // CHECK-NOT: Xor 686 NotNot1(long arg)687 public static long NotNot1(long arg) { 688 return ~~arg; 689 } 690 691 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (before) 692 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 693 // CHECK-DAG: [[ConstF1:i\d+]] IntConstant -1 694 // CHECK-DAG: [[Xor1:i\d+]] Xor [ [[Arg]] [[ConstF1]] ] 695 // CHECK-DAG: [[Xor2:i\d+]] Xor [ [[Xor1]] [[ConstF1]] ] 696 // CHECK-DAG: [[Add:i\d+]] Add [ [[Xor1]] [[Xor2]] ] 697 // CHECK-DAG: Return [ [[Add]] ] 698 699 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after) 700 // CHECK-DAG: [[Arg:i\d+]] ParameterValue 701 // CHECK-DAG: [[Not:i\d+]] Not [ [[Arg]] ] 702 // CHECK-DAG: [[Add:i\d+]] Add [ [[Not]] [[Arg]] ] 703 // CHECK-DAG: Return [ [[Add]] ] 704 705 // CHECK-START: int Main.NotNot2(int) instruction_simplifier (after) 706 // CHECK-NOT: Xor 707 NotNot2(int arg)708 public static int NotNot2(int arg) { 709 int temp = ~arg; 710 return temp + ~temp; 711 } 712 713 /** 714 * Test the simplification of a subtraction with a negated argument. 715 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`. 716 */ 717 718 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (before) 719 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 720 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 721 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ] 722 // CHECK-DAG: [[Sub:i\d+]] Sub [ [[Neg]] [[Arg2]] ] 723 // CHECK-DAG: Return [ [[Sub]] ] 724 725 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after) 726 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 727 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 728 // CHECK-DAG: [[Add:i\d+]] Add [ [[Arg1]] [[Arg2]] ] 729 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Add]] ] 730 // CHECK-DAG: Return [ [[Neg]] ] 731 732 // CHECK-START: int Main.SubNeg1(int, int) instruction_simplifier (after) 733 // CHECK-NOT: Sub 734 SubNeg1(int arg1, int arg2)735 public static int SubNeg1(int arg1, int arg2) { 736 return -arg1 - arg2; 737 } 738 739 /** 740 * This is similar to the test-case SubNeg1, but the negation has 741 * multiple uses. 742 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`. 743 * The current code won't perform the previous optimization. The 744 * transformations do not look at other uses of their inputs. As they don't 745 * know what will happen with other uses, they do not take the risk of 746 * increasing the register pressure by creating or extending live ranges. 747 */ 748 749 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (before) 750 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 751 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 752 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ] 753 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ] 754 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ] 755 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ] 756 // CHECK-DAG: Return [ [[Or]] ] 757 758 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after) 759 // CHECK-DAG: [[Arg1:i\d+]] ParameterValue 760 // CHECK-DAG: [[Arg2:i\d+]] ParameterValue 761 // CHECK-DAG: [[Neg:i\d+]] Neg [ [[Arg1]] ] 762 // CHECK-DAG: [[Sub1:i\d+]] Sub [ [[Neg]] [[Arg2]] ] 763 // CHECK-DAG: [[Sub2:i\d+]] Sub [ [[Neg]] [[Arg2]] ] 764 // CHECK-DAG: [[Or:i\d+]] Or [ [[Sub1]] [[Sub2]] ] 765 // CHECK-DAG: Return [ [[Or]] ] 766 767 // CHECK-START: int Main.SubNeg2(int, int) instruction_simplifier (after) 768 // CHECK-NOT: Add 769 SubNeg2(int arg1, int arg2)770 public static int SubNeg2(int arg1, int arg2) { 771 int temp = -arg1; 772 return (temp - arg2) | (temp - arg2); 773 } 774 775 /** 776 * This follows test-cases SubNeg1 and SubNeg2. 777 * The transformation tested is implemented in `InstructionSimplifierVisitor::VisitSub`. 778 * The optimization should not happen if it moves an additional instruction in 779 * the loop. 780 */ 781 782 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (before) 783 // -------------- Arguments and initial negation operation. 784 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue 785 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue 786 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ] 787 // CHECK: Goto 788 // -------------- Loop 789 // CHECK: SuspendCheck 790 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ] 791 // CHECK: Goto 792 793 // CHECK-START: long Main.SubNeg3(long, long) instruction_simplifier (after) 794 // -------------- Arguments and initial negation operation. 795 // CHECK-DAG: [[Arg1:j\d+]] ParameterValue 796 // CHECK-DAG: [[Arg2:j\d+]] ParameterValue 797 // CHECK-DAG: [[Neg:j\d+]] Neg [ [[Arg1]] ] 798 // CHECK-DAG: Goto 799 // -------------- Loop 800 // CHECK: SuspendCheck 801 // CHECK: [[Sub:j\d+]] Sub [ [[Neg]] [[Arg2]] ] 802 // CHECK-NOT: Neg 803 // CHECK: Goto 804 SubNeg3(long arg1, long arg2)805 public static long SubNeg3(long arg1, long arg2) { 806 long res = 0; 807 long temp = -arg1; 808 for (long i = 0; i < 1; i++) { 809 res += temp - arg2 - i; 810 } 811 return res; 812 } 813 814 // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (before) 815 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 816 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 817 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Arg]] [[Const1]] ] 818 // CHECK-DAG: If [ [[Cond]] ] 819 820 // CHECK-START: int Main.EqualTrueRhs(boolean) instruction_simplifier (after) 821 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 822 // CHECK-DAG: If [ [[Arg]] ] 823 EqualTrueRhs(boolean arg)824 public static int EqualTrueRhs(boolean arg) { 825 return (arg != true) ? 3 : 5; 826 } 827 828 // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (before) 829 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 830 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 831 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Const1]] [[Arg]] ] 832 // CHECK-DAG: If [ [[Cond]] ] 833 834 // CHECK-START: int Main.EqualTrueLhs(boolean) instruction_simplifier (after) 835 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 836 // CHECK-DAG: If [ [[Arg]] ] 837 EqualTrueLhs(boolean arg)838 public static int EqualTrueLhs(boolean arg) { 839 return (true != arg) ? 3 : 5; 840 } 841 842 // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (before) 843 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 844 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 845 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Arg]] [[Const0]] ] 846 // CHECK-DAG: If [ [[Cond]] ] 847 848 // CHECK-START: int Main.EqualFalseRhs(boolean) instruction_simplifier (after) 849 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 850 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ] 851 // CHECK-DAG: If [ [[NotArg]] ] 852 EqualFalseRhs(boolean arg)853 public static int EqualFalseRhs(boolean arg) { 854 return (arg != false) ? 3 : 5; 855 } 856 857 // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (before) 858 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 859 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 860 // CHECK-DAG: [[Cond:z\d+]] Equal [ [[Const0]] [[Arg]] ] 861 // CHECK-DAG: If [ [[Cond]] ] 862 863 // CHECK-START: int Main.EqualFalseLhs(boolean) instruction_simplifier (after) 864 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 865 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ] 866 // CHECK-DAG: If [ [[NotArg]] ] 867 EqualFalseLhs(boolean arg)868 public static int EqualFalseLhs(boolean arg) { 869 return (false != arg) ? 3 : 5; 870 } 871 872 // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (before) 873 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 874 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 875 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Arg]] [[Const1]] ] 876 // CHECK-DAG: If [ [[Cond]] ] 877 878 // CHECK-START: int Main.NotEqualTrueRhs(boolean) instruction_simplifier (after) 879 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 880 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ] 881 // CHECK-DAG: If [ [[NotArg]] ] 882 NotEqualTrueRhs(boolean arg)883 public static int NotEqualTrueRhs(boolean arg) { 884 return (arg == true) ? 3 : 5; 885 } 886 887 // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (before) 888 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 889 // CHECK-DAG: [[Const1:i\d+]] IntConstant 1 890 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Const1]] [[Arg]] ] 891 // CHECK-DAG: If [ [[Cond]] ] 892 893 // CHECK-START: int Main.NotEqualTrueLhs(boolean) instruction_simplifier (after) 894 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 895 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ] 896 // CHECK-DAG: If [ [[NotArg]] ] 897 NotEqualTrueLhs(boolean arg)898 public static int NotEqualTrueLhs(boolean arg) { 899 return (true == arg) ? 3 : 5; 900 } 901 902 // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (before) 903 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 904 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 905 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Arg]] [[Const0]] ] 906 // CHECK-DAG: If [ [[Cond]] ] 907 908 // CHECK-START: int Main.NotEqualFalseRhs(boolean) instruction_simplifier (after) 909 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 910 // CHECK-DAG: If [ [[Arg]] ] 911 NotEqualFalseRhs(boolean arg)912 public static int NotEqualFalseRhs(boolean arg) { 913 return (arg == false) ? 3 : 5; 914 } 915 916 // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (before) 917 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 918 // CHECK-DAG: [[Const0:i\d+]] IntConstant 0 919 // CHECK-DAG: [[Cond:z\d+]] NotEqual [ [[Const0]] [[Arg]] ] 920 // CHECK-DAG: If [ [[Cond]] ] 921 922 // CHECK-START: int Main.NotEqualFalseLhs(boolean) instruction_simplifier (after) 923 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 924 // CHECK-DAG: If [ [[Arg]] ] 925 NotEqualFalseLhs(boolean arg)926 public static int NotEqualFalseLhs(boolean arg) { 927 return (false == arg) ? 3 : 5; 928 } 929 930 /* 931 * Test simplification of double Boolean negation. Note that sometimes 932 * both negations can be removed but we only expect the simplifier to 933 * remove the second. 934 */ 935 936 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (before) 937 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 938 // CHECK-DAG: [[NotArg:z\d+]] BooleanNot [ [[Arg]] ] 939 // CHECK-DAG: [[NotNotArg:z\d+]] BooleanNot [ [[NotArg]] ] 940 // CHECK-DAG: Return [ [[NotNotArg]] ] 941 942 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after) 943 // CHECK-DAG: [[Arg:z\d+]] ParameterValue 944 // CHECK-DAG: BooleanNot [ [[Arg]] ] 945 // CHECK-DAG: Return [ [[Arg]] ] 946 947 // CHECK-START: boolean Main.NotNotBool(boolean) instruction_simplifier_after_types (after) 948 // CHECK: BooleanNot 949 // CHECK-NOT: BooleanNot 950 NegateValue(boolean arg)951 public static boolean NegateValue(boolean arg) { 952 return !arg; 953 } 954 NotNotBool(boolean arg)955 public static boolean NotNotBool(boolean arg) { 956 return !(NegateValue(arg)); 957 } 958 959 // CHECK-START: float Main.Div2(float) instruction_simplifier (before) 960 // CHECK-DAG: [[Arg:f\d+]] ParameterValue 961 // CHECK-DAG: [[Const2:f\d+]] FloatConstant 2 962 // CHECK-DAG: [[Div:f\d+]] Div [ [[Arg]] [[Const2]] ] 963 // CHECK-DAG: Return [ [[Div]] ] 964 965 // CHECK-START: float Main.Div2(float) instruction_simplifier (after) 966 // CHECK-DAG: [[Arg:f\d+]] ParameterValue 967 // CHECK-DAG: [[ConstP5:f\d+]] FloatConstant 0.5 968 // CHECK-DAG: [[Mul:f\d+]] Mul [ [[Arg]] [[ConstP5]] ] 969 // CHECK-DAG: Return [ [[Mul]] ] 970 971 // CHECK-START: float Main.Div2(float) instruction_simplifier (after) 972 // CHECK-NOT: Div 973 Div2(float arg)974 public static float Div2(float arg) { 975 return arg / 2.0f; 976 } 977 978 // CHECK-START: double Main.Div2(double) instruction_simplifier (before) 979 // CHECK-DAG: [[Arg:d\d+]] ParameterValue 980 // CHECK-DAG: [[Const2:d\d+]] DoubleConstant 2 981 // CHECK-DAG: [[Div:d\d+]] Div [ [[Arg]] [[Const2]] ] 982 // CHECK-DAG: Return [ [[Div]] ] 983 984 // CHECK-START: double Main.Div2(double) instruction_simplifier (after) 985 // CHECK-DAG: [[Arg:d\d+]] ParameterValue 986 // CHECK-DAG: [[ConstP5:d\d+]] DoubleConstant 0.5 987 // CHECK-DAG: [[Mul:d\d+]] Mul [ [[Arg]] [[ConstP5]] ] 988 // CHECK-DAG: Return [ [[Mul]] ] 989 990 // CHECK-START: double Main.Div2(double) instruction_simplifier (after) 991 // CHECK-NOT: Div Div2(double arg)992 public static double Div2(double arg) { 993 return arg / 2.0; 994 } 995 996 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (before) 997 // CHECK-DAG: [[Arg:f\d+]] ParameterValue 998 // CHECK-DAG: [[ConstMP25:f\d+]] FloatConstant -0.25 999 // CHECK-DAG: [[Div:f\d+]] Div [ [[Arg]] [[ConstMP25]] ] 1000 // CHECK-DAG: Return [ [[Div]] ] 1001 1002 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after) 1003 // CHECK-DAG: [[Arg:f\d+]] ParameterValue 1004 // CHECK-DAG: [[ConstM4:f\d+]] FloatConstant -4 1005 // CHECK-DAG: [[Mul:f\d+]] Mul [ [[Arg]] [[ConstM4]] ] 1006 // CHECK-DAG: Return [ [[Mul]] ] 1007 1008 // CHECK-START: float Main.DivMP25(float) instruction_simplifier (after) 1009 // CHECK-NOT: Div 1010 DivMP25(float arg)1011 public static float DivMP25(float arg) { 1012 return arg / -0.25f; 1013 } 1014 1015 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (before) 1016 // CHECK-DAG: [[Arg:d\d+]] ParameterValue 1017 // CHECK-DAG: [[ConstMP25:d\d+]] DoubleConstant -0.25 1018 // CHECK-DAG: [[Div:d\d+]] Div [ [[Arg]] [[ConstMP25]] ] 1019 // CHECK-DAG: Return [ [[Div]] ] 1020 1021 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after) 1022 // CHECK-DAG: [[Arg:d\d+]] ParameterValue 1023 // CHECK-DAG: [[ConstM4:d\d+]] DoubleConstant -4 1024 // CHECK-DAG: [[Mul:d\d+]] Mul [ [[Arg]] [[ConstM4]] ] 1025 // CHECK-DAG: Return [ [[Mul]] ] 1026 1027 // CHECK-START: double Main.DivMP25(double) instruction_simplifier (after) 1028 // CHECK-NOT: Div DivMP25(double arg)1029 public static double DivMP25(double arg) { 1030 return arg / -0.25f; 1031 } 1032 main(String[] args)1033 public static void main(String[] args) { 1034 int arg = 123456; 1035 1036 assertLongEquals(Add0(arg), arg); 1037 assertIntEquals(AndAllOnes(arg), arg); 1038 assertLongEquals(Div1(arg), arg); 1039 assertIntEquals(DivN1(arg), -arg); 1040 assertLongEquals(Mul1(arg), arg); 1041 assertIntEquals(MulN1(arg), -arg); 1042 assertLongEquals(MulPowerOfTwo128(arg), (128 * arg)); 1043 assertIntEquals(Or0(arg), arg); 1044 assertLongEquals(OrSame(arg), arg); 1045 assertIntEquals(Shl0(arg), arg); 1046 assertLongEquals(Shr0(arg), arg); 1047 assertLongEquals(Sub0(arg), arg); 1048 assertIntEquals(SubAliasNeg(arg), -arg); 1049 assertLongEquals(UShr0(arg), arg); 1050 assertIntEquals(Xor0(arg), arg); 1051 assertIntEquals(XorAllOnes(arg), ~arg); 1052 assertIntEquals(AddNegs1(arg, arg + 1), -(arg + arg + 1)); 1053 assertIntEquals(AddNegs2(arg, arg + 1), -(arg + arg + 1)); 1054 assertLongEquals(AddNegs3(arg, arg + 1), -(2 * arg + 1)); 1055 assertLongEquals(AddNeg1(arg, arg + 1), 1); 1056 assertLongEquals(AddNeg2(arg, arg + 1), -1); 1057 assertLongEquals(NegNeg1(arg), arg); 1058 assertIntEquals(NegNeg2(arg), 0); 1059 assertLongEquals(NegNeg3(arg), arg); 1060 assertIntEquals(NegSub1(arg, arg + 1), 1); 1061 assertIntEquals(NegSub2(arg, arg + 1), 1); 1062 assertLongEquals(NotNot1(arg), arg); 1063 assertIntEquals(NotNot2(arg), -1); 1064 assertIntEquals(SubNeg1(arg, arg + 1), -(arg + arg + 1)); 1065 assertIntEquals(SubNeg2(arg, arg + 1), -(arg + arg + 1)); 1066 assertLongEquals(SubNeg3(arg, arg + 1), -(2 * arg + 1)); 1067 assertIntEquals(EqualTrueRhs(true), 5); 1068 assertIntEquals(EqualTrueLhs(true), 5); 1069 assertIntEquals(EqualFalseRhs(true), 3); 1070 assertIntEquals(EqualFalseLhs(true), 3); 1071 assertIntEquals(NotEqualTrueRhs(true), 3); 1072 assertIntEquals(NotEqualTrueLhs(true), 3); 1073 assertIntEquals(NotEqualFalseRhs(true), 5); 1074 assertIntEquals(NotEqualFalseLhs(true), 5); 1075 assertBooleanEquals(NotNotBool(true), true); 1076 assertBooleanEquals(NotNotBool(false), false); 1077 assertFloatEquals(Div2(100.0f), 50.0f); 1078 assertDoubleEquals(Div2(150.0), 75.0); 1079 assertFloatEquals(DivMP25(100.0f), -400.0f); 1080 assertDoubleEquals(DivMP25(150.0), -600.0); 1081 assertLongEquals(Shl1(100), 200); 1082 } 1083 } 1084