/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.lang.reflect.Method;

public class Main {
  public static void assertFalse(boolean condition) {
    if (condition) {
      throw new Error();
    }
  }

  public static void assertIntEquals(int expected, int result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertLongEquals(long expected, long result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertFloatEquals(float expected, float result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  public static void assertDoubleEquals(double expected, double result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }


  // Wrappers around methods located in file TestCmp.smali.

  public int smaliCmpLongConstants() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpLongConstants");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpGtFloatConstants() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpGtFloatConstants");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpLtFloatConstants() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpLtFloatConstants");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpGtDoubleConstants() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpGtDoubleConstants");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpLtDoubleConstants() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpLtDoubleConstants");
    return (Integer)m.invoke(null);
  }

  public int smaliCmpLongSameConstant() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpLongSameConstant");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpGtFloatSameConstant() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpGtFloatSameConstant");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpLtFloatSameConstant() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpLtFloatSameConstant");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpGtDoubleSameConstant() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpGtDoubleSameConstant");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpLtDoubleSameConstant() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpLtDoubleSameConstant");
    return (Integer)m.invoke(null);
  }

  public int smaliCmpGtFloatConstantWithNaN() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpGtFloatConstantWithNaN");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpLtFloatConstantWithNaN() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpLtFloatConstantWithNaN");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpGtDoubleConstantWithNaN() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpGtDoubleConstantWithNaN");
    return (Integer)m.invoke(null);
  }
  public int smaliCmpLtDoubleConstantWithNaN() throws Exception {
    Method m = testCmp.getMethod("$opt$CmpLtDoubleConstantWithNaN");
    return (Integer)m.invoke(null);
  }

  public static int smaliIntAddition2() throws Exception {
    Method m = Class.forName("TestCmp").getMethod("IntAddition2");
    return (Integer)m.invoke(null);
  }
  public static int smaliIntAddition2AddAndMove() throws Exception {
    Method m = Class.forName("TestCmp").getMethod("IntAddition2AddAndMove");
    return (Integer)m.invoke(null);
  }
  public static int smaliJumpsAndConditionals(boolean cond) throws Exception {
    Method m = Class.forName("TestCmp").getMethod("JumpsAndConditionals", boolean.class);
    return (Integer)m.invoke(null, cond);
  }

  public static int smaliAnd0(int arg) throws Exception {
    Method m = Class.forName("TestCmp").getMethod("And0", int.class);
    return (Integer)m.invoke(null, arg);
  }

  public static int smaliOrAllOnes(int arg) throws Exception {
    Method m = Class.forName("TestCmp").getMethod("OrAllOnes", int.class);
    return (Integer)m.invoke(null, arg);
  }

  /**
   * Exercise constant folding on negation.
   */

  /// CHECK-START: int Main.IntNegation() constant_folding (before)
  /// CHECK-DAG:     <<Const42:i\d+>>  IntConstant 42
  /// CHECK-DAG:     <<Neg:i\d+>>      Neg [<<Const42>>]
  /// CHECK-DAG:                       Return [<<Neg>>]

  /// CHECK-START: int Main.IntNegation() constant_folding (after)
  /// CHECK-DAG:     <<ConstN42:i\d+>> IntConstant -42
  /// CHECK-DAG:                       Return [<<ConstN42>>]

  /// CHECK-START: int Main.IntNegation() constant_folding (after)
  /// CHECK-NOT:                       Neg

  public static int IntNegation() {
    int x, y;
    x = 42;
    y = -x;
    return y;
  }

  /// CHECK-START: long Main.LongNegation() constant_folding (before)
  /// CHECK-DAG:     <<Const42:j\d+>>  LongConstant 42
  /// CHECK-DAG:     <<Neg:j\d+>>      Neg [<<Const42>>]
  /// CHECK-DAG:                       Return [<<Neg>>]

  /// CHECK-START: long Main.LongNegation() constant_folding (after)
  /// CHECK-DAG:     <<ConstN42:j\d+>> LongConstant -42
  /// CHECK-DAG:                       Return [<<ConstN42>>]

  /// CHECK-START: long Main.LongNegation() constant_folding (after)
  /// CHECK-NOT:                       Neg

  public static long LongNegation() {
    long x, y;
    x = 42L;
    y = -x;
    return y;
  }

  /// CHECK-START: float Main.FloatNegation() constant_folding (before)
  /// CHECK-DAG:     <<Const42:f\d+>>  FloatConstant 42
  /// CHECK-DAG:     <<Neg:f\d+>>      Neg [<<Const42>>]
  /// CHECK-DAG:                       Return [<<Neg>>]

  /// CHECK-START: float Main.FloatNegation() constant_folding (after)
  /// CHECK-DAG:     <<ConstN42:f\d+>> FloatConstant -42
  /// CHECK-DAG:                       Return [<<ConstN42>>]

  /// CHECK-START: float Main.FloatNegation() constant_folding (after)
  /// CHECK-NOT:                       Neg

  public static float FloatNegation() {
    float x, y;
    x = 42F;
    y = -x;
    return y;
  }

  /// CHECK-START: double Main.DoubleNegation() constant_folding (before)
  /// CHECK-DAG:     <<Const42:d\d+>>  DoubleConstant 42
  /// CHECK-DAG:     <<Neg:d\d+>>      Neg [<<Const42>>]
  /// CHECK-DAG:                       Return [<<Neg>>]

  /// CHECK-START: double Main.DoubleNegation() constant_folding (after)
  /// CHECK-DAG:     <<ConstN42:d\d+>> DoubleConstant -42
  /// CHECK-DAG:                       Return [<<ConstN42>>]

  /// CHECK-START: double Main.DoubleNegation() constant_folding (after)
  /// CHECK-NOT:                       Neg

  public static double DoubleNegation() {
    double x, y;
    x = 42D;
    y = -x;
    return y;
  }


  /**
   * Exercise constant folding on addition.
   */

  /// CHECK-START: int Main.IntAddition1() constant_folding (before)
  /// CHECK-DAG:     <<Const1:i\d+>>  IntConstant 1
  /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
  /// CHECK-DAG:     <<Add:i\d+>>     Add [<<Const1>>,<<Const2>>]
  /// CHECK-DAG:                      Return [<<Add>>]

  /// CHECK-START: int Main.IntAddition1() constant_folding (after)
  /// CHECK-DAG:     <<Const3:i\d+>>  IntConstant 3
  /// CHECK-DAG:                      Return [<<Const3>>]

  /// CHECK-START: int Main.IntAddition1() constant_folding (after)
  /// CHECK-NOT:                      Add

  public static int IntAddition1() {
    int a, b, c;
    a = 1;
    b = 2;
    c = a + b;
    return c;
  }

  /// CHECK-START: int Main.IntAddition2() constant_folding (before)
  /// CHECK-DAG:     <<Const1:i\d+>>  IntConstant 1
  /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
  /// CHECK-DAG:     <<Const5:i\d+>>  IntConstant 5
  /// CHECK-DAG:     <<Const6:i\d+>>  IntConstant 6
  /// CHECK-DAG:     <<Add1:i\d+>>    Add [<<Const1>>,<<Const2>>]
  /// CHECK-DAG:                      Add [<<Const5>>,<<Const6>>]

  /// CHECK-START: int Main.IntAddition2() constant_folding (after)
  /// CHECK-DAG:     <<Const14:i\d+>> IntConstant 14
  /// CHECK-DAG:                      Return [<<Const14>>]

  /// CHECK-START: int Main.IntAddition2() constant_folding (after)
  /// CHECK-NOT:                      Add

  public static int IntAddition2() {
    int a, b, c;
    a = 1;
    b = 2;
    a += b;
    b = 5;
    c = 6;
    b += c;
    c = a + b;
    return c;
  }

  /// CHECK-START: long Main.LongAddition() constant_folding (before)
  /// CHECK-DAG:     <<Const1:j\d+>>  LongConstant 1
  /// CHECK-DAG:     <<Const2:j\d+>>  LongConstant 2
  /// CHECK-DAG:     <<Add:j\d+>>     Add [<<Const1>>,<<Const2>>]
  /// CHECK-DAG:                      Return [<<Add>>]

  /// CHECK-START: long Main.LongAddition() constant_folding (after)
  /// CHECK-DAG:     <<Const3:j\d+>>  LongConstant 3
  /// CHECK-DAG:                      Return [<<Const3>>]

  /// CHECK-START: long Main.LongAddition() constant_folding (after)
  /// CHECK-NOT:                      Add

  public static long LongAddition() {
    long a, b, c;
    a = 1L;
    b = 2L;
    c = a + b;
    return c;
  }

  /// CHECK-START: float Main.FloatAddition() constant_folding (before)
  /// CHECK-DAG:     <<Const1:f\d+>>  FloatConstant 1
  /// CHECK-DAG:     <<Const2:f\d+>>  FloatConstant 2
  /// CHECK-DAG:     <<Add:f\d+>>     Add [<<Const1>>,<<Const2>>]
  /// CHECK-DAG:                      Return [<<Add>>]

  /// CHECK-START: float Main.FloatAddition() constant_folding (after)
  /// CHECK-DAG:     <<Const3:f\d+>>  FloatConstant 3
  /// CHECK-DAG:                      Return [<<Const3>>]

  /// CHECK-START: float Main.FloatAddition() constant_folding (after)
  /// CHECK-NOT:                      Add

  public static float FloatAddition() {
    float a, b, c;
    a = 1F;
    b = 2F;
    c = a + b;
    return c;
  }

  /// CHECK-START: double Main.DoubleAddition() constant_folding (before)
  /// CHECK-DAG:     <<Const1:d\d+>>  DoubleConstant 1
  /// CHECK-DAG:     <<Const2:d\d+>>  DoubleConstant 2
  /// CHECK-DAG:     <<Add:d\d+>>     Add [<<Const1>>,<<Const2>>]
  /// CHECK-DAG:                      Return [<<Add>>]

  /// CHECK-START: double Main.DoubleAddition() constant_folding (after)
  /// CHECK-DAG:     <<Const3:d\d+>>  DoubleConstant 3
  /// CHECK-DAG:                      Return [<<Const3>>]

  /// CHECK-START: double Main.DoubleAddition() constant_folding (after)
  /// CHECK-NOT:                      Add

  public static double DoubleAddition() {
    double a, b, c;
    a = 1D;
    b = 2D;
    c = a + b;
    return c;
  }


  /**
   * Exercise constant folding on subtraction.
   */

  /// CHECK-START: int Main.IntSubtraction() constant_folding (before)
  /// CHECK-DAG:     <<Const6:i\d+>>  IntConstant 6
  /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
  /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<Const6>>,<<Const2>>]
  /// CHECK-DAG:                      Return [<<Sub>>]

  /// CHECK-START: int Main.IntSubtraction() constant_folding (after)
  /// CHECK-DAG:     <<Const4:i\d+>>  IntConstant 4
  /// CHECK-DAG:                      Return [<<Const4>>]

  /// CHECK-START: int Main.IntSubtraction() constant_folding (after)
  /// CHECK-NOT:                      Sub

  public static int IntSubtraction() {
    int a, b, c;
    a = 6;
    b = 2;
    c = a - b;
    return c;
  }

  /// CHECK-START: long Main.LongSubtraction() constant_folding (before)
  /// CHECK-DAG:     <<Const6:j\d+>>  LongConstant 6
  /// CHECK-DAG:     <<Const2:j\d+>>  LongConstant 2
  /// CHECK-DAG:     <<Sub:j\d+>>     Sub [<<Const6>>,<<Const2>>]
  /// CHECK-DAG:                      Return [<<Sub>>]

  /// CHECK-START: long Main.LongSubtraction() constant_folding (after)
  /// CHECK-DAG:     <<Const4:j\d+>>  LongConstant 4
  /// CHECK-DAG:                      Return [<<Const4>>]

  /// CHECK-START: long Main.LongSubtraction() constant_folding (after)
  /// CHECK-NOT:                      Sub

  public static long LongSubtraction() {
    long a, b, c;
    a = 6L;
    b = 2L;
    c = a - b;
    return c;
  }

  /// CHECK-START: float Main.FloatSubtraction() constant_folding (before)
  /// CHECK-DAG:     <<Const6:f\d+>>  FloatConstant 6
  /// CHECK-DAG:     <<Const2:f\d+>>  FloatConstant 2
  /// CHECK-DAG:     <<Sub:f\d+>>     Sub [<<Const6>>,<<Const2>>]
  /// CHECK-DAG:                      Return [<<Sub>>]

  /// CHECK-START: float Main.FloatSubtraction() constant_folding (after)
  /// CHECK-DAG:     <<Const4:f\d+>>  FloatConstant 4
  /// CHECK-DAG:                      Return [<<Const4>>]

  /// CHECK-START: float Main.FloatSubtraction() constant_folding (after)
  /// CHECK-NOT:                      Sub

  public static float FloatSubtraction() {
    float a, b, c;
    a = 6F;
    b = 2F;
    c = a - b;
    return c;
  }

  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (before)
  /// CHECK-DAG:     <<Const6:d\d+>>  DoubleConstant 6
  /// CHECK-DAG:     <<Const2:d\d+>>  DoubleConstant 2
  /// CHECK-DAG:     <<Sub:d\d+>>     Sub [<<Const6>>,<<Const2>>]
  /// CHECK-DAG:                      Return [<<Sub>>]

  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (after)
  /// CHECK-DAG:     <<Const4:d\d+>>  DoubleConstant 4
  /// CHECK-DAG:                      Return [<<Const4>>]

  /// CHECK-START: double Main.DoubleSubtraction() constant_folding (after)
  /// CHECK-NOT:                      Sub

  public static double DoubleSubtraction() {
    double a, b, c;
    a = 6D;
    b = 2D;
    c = a - b;
    return c;
  }


  /**
   * Exercise constant folding on multiplication.
   */

  /// CHECK-START: int Main.IntMultiplication() constant_folding (before)
  /// CHECK-DAG:     <<Const7:i\d+>>  IntConstant 7
  /// CHECK-DAG:     <<Const3:i\d+>>  IntConstant 3
  /// CHECK-DAG:     <<Mul:i\d+>>     Mul [<<Const7>>,<<Const3>>]
  /// CHECK-DAG:                      Return [<<Mul>>]

  /// CHECK-START: int Main.IntMultiplication() constant_folding (after)
  /// CHECK-DAG:     <<Const21:i\d+>> IntConstant 21
  /// CHECK-DAG:                      Return [<<Const21>>]

  /// CHECK-START: int Main.IntMultiplication() constant_folding (after)
  /// CHECK-NOT:                      Mul

  public static int IntMultiplication() {
    int a, b, c;
    a = 7;
    b = 3;
    c = a * b;
    return c;
  }

  /// CHECK-START: long Main.LongMultiplication() constant_folding (before)
  /// CHECK-DAG:     <<Const7:j\d+>>  LongConstant 7
  /// CHECK-DAG:     <<Const3:j\d+>>  LongConstant 3
  /// CHECK-DAG:     <<Mul:j\d+>>     Mul [<<Const7>>,<<Const3>>]
  /// CHECK-DAG:                      Return [<<Mul>>]

  /// CHECK-START: long Main.LongMultiplication() constant_folding (after)
  /// CHECK-DAG:     <<Const21:j\d+>> LongConstant 21
  /// CHECK-DAG:                      Return [<<Const21>>]

  /// CHECK-START: long Main.LongMultiplication() constant_folding (after)
  /// CHECK-NOT:                      Mul

  public static long LongMultiplication() {
    long a, b, c;
    a = 7L;
    b = 3L;
    c = a * b;
    return c;
  }

  /// CHECK-START: float Main.FloatMultiplication() constant_folding (before)
  /// CHECK-DAG:     <<Const7:f\d+>>  FloatConstant 7
  /// CHECK-DAG:     <<Const3:f\d+>>  FloatConstant 3
  /// CHECK-DAG:     <<Mul:f\d+>>     Mul [<<Const7>>,<<Const3>>]
  /// CHECK-DAG:                      Return [<<Mul>>]

  /// CHECK-START: float Main.FloatMultiplication() constant_folding (after)
  /// CHECK-DAG:     <<Const21:f\d+>> FloatConstant 21
  /// CHECK-DAG:                      Return [<<Const21>>]

  /// CHECK-START: float Main.FloatMultiplication() constant_folding (after)
  /// CHECK-NOT:                      Mul

  public static float FloatMultiplication() {
    float a, b, c;
    a = 7F;
    b = 3F;
    c = a * b;
    return c;
  }

  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (before)
  /// CHECK-DAG:     <<Const7:d\d+>>  DoubleConstant 7
  /// CHECK-DAG:     <<Const3:d\d+>>  DoubleConstant 3
  /// CHECK-DAG:     <<Mul:d\d+>>     Mul [<<Const7>>,<<Const3>>]
  /// CHECK-DAG:                      Return [<<Mul>>]

  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (after)
  /// CHECK-DAG:     <<Const21:d\d+>> DoubleConstant 21
  /// CHECK-DAG:                      Return [<<Const21>>]

  /// CHECK-START: double Main.DoubleMultiplication() constant_folding (after)
  /// CHECK-NOT:                      Mul

  public static double DoubleMultiplication() {
    double a, b, c;
    a = 7D;
    b = 3D;
    c = a * b;
    return c;
  }


  /**
   * Exercise constant folding on division.
   */

  /// CHECK-START: int Main.IntDivision() constant_folding (before)
  /// CHECK-DAG:     <<Const8:i\d+>>   IntConstant 8
  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
  /// CHECK-DAG:     <<Div0Chk:i\d+>>  DivZeroCheck [<<Const3>>]
  /// CHECK-DAG:     <<Div:i\d+>>      Div [<<Const8>>,<<Div0Chk>>]
  /// CHECK-DAG:                       Return [<<Div>>]

  /// CHECK-START: int Main.IntDivision() constant_folding (after)
  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
  /// CHECK-DAG:                       Return [<<Const2>>]

  /// CHECK-START: int Main.IntDivision() constant_folding (after)
  /// CHECK-NOT:                       DivZeroCheck
  /// CHECK-NOT:                       Div

  public static int IntDivision() {
    int a, b, c;
    a = 8;
    b = 3;
    c = a / b;
    return c;
  }

  /// CHECK-START: long Main.LongDivision() constant_folding (before)
  /// CHECK-DAG:     <<Const8:j\d+>>   LongConstant 8
  /// CHECK-DAG:     <<Const3:j\d+>>   LongConstant 3
  /// CHECK-DAG:     <<Div0Chk:j\d+>>  DivZeroCheck [<<Const3>>]
  /// CHECK-DAG:     <<Div:j\d+>>      Div [<<Const8>>,<<Div0Chk>>]
  /// CHECK-DAG:                       Return [<<Div>>]

  /// CHECK-START: long Main.LongDivision() constant_folding (after)
  /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
  /// CHECK-DAG:                       Return [<<Const2>>]

  /// CHECK-START: long Main.LongDivision() constant_folding (after)
  /// CHECK-NOT:                       DivZeroCheck
  /// CHECK-NOT:                       Div

  public static long LongDivision() {
    long a, b, c;
    a = 8L;
    b = 3L;
    c = a / b;
    return c;
  }

  /// CHECK-START: float Main.FloatDivision() constant_folding (before)
  /// CHECK-DAG:     <<Const8:f\d+>>   FloatConstant 8
  /// CHECK-DAG:     <<Const2P5:f\d+>> FloatConstant 2.5
  /// CHECK-DAG:     <<Div:f\d+>>      Div [<<Const8>>,<<Const2P5>>]
  /// CHECK-DAG:                       Return [<<Div>>]

  /// CHECK-START: float Main.FloatDivision() constant_folding (after)
  /// CHECK-DAG:     <<Const3P2:f\d+>> FloatConstant 3.2
  /// CHECK-DAG:                       Return [<<Const3P2>>]

  /// CHECK-START: float Main.FloatDivision() constant_folding (after)
  /// CHECK-NOT:                       Div

  public static float FloatDivision() {
    float a, b, c;
    a = 8F;
    b = 2.5F;
    c = a / b;
    return c;
  }

  /// CHECK-START: double Main.DoubleDivision() constant_folding (before)
  /// CHECK-DAG:     <<Const8:d\d+>>   DoubleConstant 8
  /// CHECK-DAG:     <<Const2P5:d\d+>> DoubleConstant 2.5
  /// CHECK-DAG:     <<Div:d\d+>>      Div [<<Const8>>,<<Const2P5>>]
  /// CHECK-DAG:                       Return [<<Div>>]

  /// CHECK-START: double Main.DoubleDivision() constant_folding (after)
  /// CHECK-DAG:     <<Const3P2:d\d+>> DoubleConstant 3.2
  /// CHECK-DAG:                       Return [<<Const3P2>>]

  /// CHECK-START: double Main.DoubleDivision() constant_folding (after)
  /// CHECK-NOT:                       Div

  public static double DoubleDivision() {
    double a, b, c;
    a = 8D;
    b = 2.5D;
    c = a / b;
    return c;
  }


  /**
   * Exercise constant folding on remainder.
   */

  /// CHECK-START: int Main.IntRemainder() constant_folding (before)
  /// CHECK-DAG:     <<Const8:i\d+>>   IntConstant 8
  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
  /// CHECK-DAG:     <<Div0Chk:i\d+>>  DivZeroCheck [<<Const3>>]
  /// CHECK-DAG:     <<Rem:i\d+>>      Rem [<<Const8>>,<<Div0Chk>>]
  /// CHECK-DAG:                       Return [<<Rem>>]

  /// CHECK-START: int Main.IntRemainder() constant_folding (after)
  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
  /// CHECK-DAG:                       Return [<<Const2>>]

  /// CHECK-START: int Main.IntRemainder() constant_folding (after)
  /// CHECK-NOT:                       DivZeroCheck
  /// CHECK-NOT:                       Rem

  public static int IntRemainder() {
    int a, b, c;
    a = 8;
    b = 3;
    c = a % b;
    return c;
  }

  /// CHECK-START: long Main.LongRemainder() constant_folding (before)
  /// CHECK-DAG:     <<Const8:j\d+>>   LongConstant 8
  /// CHECK-DAG:     <<Const3:j\d+>>   LongConstant 3
  /// CHECK-DAG:     <<Div0Chk:j\d+>>  DivZeroCheck [<<Const3>>]
  /// CHECK-DAG:     <<Rem:j\d+>>      Rem [<<Const8>>,<<Div0Chk>>]
  /// CHECK-DAG:                       Return [<<Rem>>]

  /// CHECK-START: long Main.LongRemainder() constant_folding (after)
  /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
  /// CHECK-DAG:                       Return [<<Const2>>]

  /// CHECK-START: long Main.LongRemainder() constant_folding (after)
  /// CHECK-NOT:                       DivZeroCheck
  /// CHECK-NOT:                       Rem

  public static long LongRemainder() {
    long a, b, c;
    a = 8L;
    b = 3L;
    c = a % b;
    return c;
  }

  /// CHECK-START: float Main.FloatRemainder() constant_folding (before)
  /// CHECK-DAG:     <<Const8:f\d+>>   FloatConstant 8
  /// CHECK-DAG:     <<Const2P5:f\d+>> FloatConstant 2.5
  /// CHECK-DAG:     <<Rem:f\d+>>      Rem [<<Const8>>,<<Const2P5>>]
  /// CHECK-DAG:                       Return [<<Rem>>]

  /// CHECK-START: float Main.FloatRemainder() constant_folding (after)
  /// CHECK-DAG:     <<Const0P5:f\d+>> FloatConstant 0.5
  /// CHECK-DAG:                       Return [<<Const0P5>>]

  /// CHECK-START: float Main.FloatRemainder() constant_folding (after)
  /// CHECK-NOT:                       Rem

  public static float FloatRemainder() {
    float a, b, c;
    a = 8F;
    b = 2.5F;
    c = a % b;
    return c;
  }

  /// CHECK-START: double Main.DoubleRemainder() constant_folding (before)
  /// CHECK-DAG:     <<Const8:d\d+>>   DoubleConstant 8
  /// CHECK-DAG:     <<Const2P5:d\d+>> DoubleConstant 2.5
  /// CHECK-DAG:     <<Rem:d\d+>>      Rem [<<Const8>>,<<Const2P5>>]
  /// CHECK-DAG:                       Return [<<Rem>>]

  /// CHECK-START: double Main.DoubleRemainder() constant_folding (after)
  /// CHECK-DAG:     <<Const0P5:d\d+>> DoubleConstant 0.5
  /// CHECK-DAG:                       Return [<<Const0P5>>]

  /// CHECK-START: double Main.DoubleRemainder() constant_folding (after)
  /// CHECK-NOT:                       Rem

  public static double DoubleRemainder() {
    double a, b, c;
    a = 8D;
    b = 2.5D;
    c = a % b;
    return c;
  }


  /**
   * Exercise constant folding on left shift.
   */

  /// CHECK-START: int Main.ShlIntLong() constant_folding (before)
  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
  /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
  /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
  /// CHECK-DAG:     <<Shl:i\d+>>      Shl [<<Const1>>,<<TypeConv>>]
  /// CHECK-DAG:                       Return [<<Shl>>]

  /// CHECK-START: int Main.ShlIntLong() constant_folding (after)
  /// CHECK-DAG:     <<Const4:i\d+>>   IntConstant 4
  /// CHECK-DAG:                       Return [<<Const4>>]

  /// CHECK-START: int Main.ShlIntLong() constant_folding (after)
  /// CHECK-NOT:                       Shl

  public static int ShlIntLong() {
    int lhs = 1;
    long rhs = 2;
    return lhs << rhs;
  }

  /// CHECK-START: long Main.ShlLongInt() constant_folding (before)
  /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
  /// CHECK-DAG:     <<Shl:j\d+>>      Shl [<<Const3L>>,<<Const2>>]
  /// CHECK-DAG:                       Return [<<Shl>>]

  /// CHECK-START: long Main.ShlLongInt() constant_folding (after)
  /// CHECK-DAG:     <<Const12L:j\d+>> LongConstant 12
  /// CHECK-DAG:                       Return [<<Const12L>>]

  /// CHECK-START: long Main.ShlLongInt() constant_folding (after)
  /// CHECK-NOT:                       Shl

  public static long ShlLongInt() {
    long lhs = 3;
    int rhs = 2;
    return lhs << rhs;
  }


  /**
   * Exercise constant folding on right shift.
   */

  /// CHECK-START: int Main.ShrIntLong() constant_folding (before)
  /// CHECK-DAG:     <<Const7:i\d+>>   IntConstant 7
  /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
  /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
  /// CHECK-DAG:     <<Shr:i\d+>>      Shr [<<Const7>>,<<TypeConv>>]
  /// CHECK-DAG:                       Return [<<Shr>>]

  /// CHECK-START: int Main.ShrIntLong() constant_folding (after)
  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
  /// CHECK-DAG:                       Return [<<Const1>>]

  /// CHECK-START: int Main.ShrIntLong() constant_folding (after)
  /// CHECK-NOT:                       Shr

  public static int ShrIntLong() {
    int lhs = 7;
    long rhs = 2;
    return lhs >> rhs;
  }

  /// CHECK-START: long Main.ShrLongInt() constant_folding (before)
  /// CHECK-DAG:     <<Const9L:j\d+>>  LongConstant 9
  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
  /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Const9L>>,<<Const2>>]
  /// CHECK-DAG:                       Return [<<Shr>>]

  /// CHECK-START: long Main.ShrLongInt() constant_folding (after)
  /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
  /// CHECK-DAG:                       Return [<<Const2L>>]

  /// CHECK-START: long Main.ShrLongInt() constant_folding (after)
  /// CHECK-NOT:                       Shr

  public static long ShrLongInt() {
    long lhs = 9;
    int rhs = 2;
    return lhs >> rhs;
  }


  /**
   * Exercise constant folding on unsigned right shift.
   */

  /// CHECK-START: int Main.UShrIntLong() constant_folding (before)
  /// CHECK-DAG:     <<ConstM7:i\d+>>  IntConstant -7
  /// CHECK-DAG:     <<Const2L:j\d+>>  LongConstant 2
  /// CHECK-DAG:     <<TypeConv:i\d+>> TypeConversion [<<Const2L>>]
  /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<ConstM7>>,<<TypeConv>>]
  /// CHECK-DAG:                       Return [<<UShr>>]

  /// CHECK-START: int Main.UShrIntLong() constant_folding (after)
  /// CHECK-DAG:     <<ConstRes:i\d+>> IntConstant 1073741822
  /// CHECK-DAG:                       Return [<<ConstRes>>]

  /// CHECK-START: int Main.UShrIntLong() constant_folding (after)
  /// CHECK-NOT:                       UShr

  public static int UShrIntLong() {
    int lhs = -7;
    long rhs = 2;
    return lhs >>> rhs;
  }

  /// CHECK-START: long Main.UShrLongInt() constant_folding (before)
  /// CHECK-DAG:     <<ConstM9L:j\d+>> LongConstant -9
  /// CHECK-DAG:     <<Const2:i\d+>>   IntConstant 2
  /// CHECK-DAG:     <<UShr:j\d+>>     UShr [<<ConstM9L>>,<<Const2>>]
  /// CHECK-DAG:                       Return [<<UShr>>]

  /// CHECK-START: long Main.UShrLongInt() constant_folding (after)
  /// CHECK-DAG:     <<ConstRes:j\d+>> LongConstant 4611686018427387901
  /// CHECK-DAG:                       Return [<<ConstRes>>]

  /// CHECK-START: long Main.UShrLongInt() constant_folding (after)
  /// CHECK-NOT:                       UShr

  public static long UShrLongInt() {
    long lhs = -9;
    int rhs = 2;
    return lhs >>> rhs;
  }


  /**
   * Exercise constant folding on logical and.
   */

  /// CHECK-START: long Main.AndIntLong() constant_folding (before)
  /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
  /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
  /// CHECK-DAG:     <<And:j\d+>>      And [<<TypeConv>>,<<Const3L>>]
  /// CHECK-DAG:                       Return [<<And>>]

  /// CHECK-START: long Main.AndIntLong() constant_folding (after)
  /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
  /// CHECK-DAG:                       Return [<<Const2>>]

  /// CHECK-START: long Main.AndIntLong() constant_folding (after)
  /// CHECK-NOT:                       And

  public static long AndIntLong() {
    int lhs = 10;
    long rhs = 3;
    return lhs & rhs;
  }

  /// CHECK-START: long Main.AndLongInt() constant_folding (before)
  /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
  /// CHECK-DAG:     <<And:j\d+>>      And [<<TypeConv>>,<<Const10L>>]
  /// CHECK-DAG:                       Return [<<And>>]

  /// CHECK-START: long Main.AndLongInt() constant_folding (after)
  /// CHECK-DAG:     <<Const2:j\d+>>   LongConstant 2
  /// CHECK-DAG:                       Return [<<Const2>>]

  /// CHECK-START: long Main.AndLongInt() constant_folding (after)
  /// CHECK-NOT:                       And

  public static long AndLongInt() {
    long lhs = 10;
    int rhs = 3;
    return lhs & rhs;
  }

  /// CHECK-START: int Main.AndSelfNegated(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
  /// CHECK-DAG:     <<Not:i\d+>>     Not [<<Arg>>]
  /// CHECK-DAG:     <<And:i\d+>>     And [<<Not>>,<<Arg>>]
  /// CHECK-DAG:                      Return [<<And>>]

  /// CHECK-START: int Main.AndSelfNegated(int) constant_folding (after)
  /// CHECK-DAG:     <<Const0:i\d+>>  IntConstant 0
  /// CHECK-DAG:                      Return [<<Const0>>]

  /// CHECK-START: int Main.AndSelfNegated(int) constant_folding (after)
  /// CHECK-NOT:                      And

  public static int AndSelfNegated(int arg) {
    return arg & ~arg;
  }

  /// CHECK-START: int Main.OrSelfNegated(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
  /// CHECK-DAG:     <<Not:i\d+>>     Not [<<Arg>>]
  /// CHECK-DAG:     <<Or:i\d+>>      Or [<<Not>>,<<Arg>>]
  /// CHECK-DAG:                      Return [<<Or>>]

  /// CHECK-START: int Main.OrSelfNegated(int) constant_folding (after)
  /// CHECK-DAG:     <<Const:i\d+>>  IntConstant -1
  /// CHECK-DAG:                     Return [<<Const>>]

  /// CHECK-START: int Main.OrSelfNegated(int) constant_folding (after)
  /// CHECK-NOT:                      Or

  public static int OrSelfNegated(int arg) {
    return arg | ~arg;
  }

  /// CHECK-START: int Main.XorSelfNegated(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>     ParameterValue
  /// CHECK-DAG:     <<Not:i\d+>>     Not [<<Arg>>]
  /// CHECK-DAG:     <<Xor:i\d+>>     Xor [<<Not>>,<<Arg>>]
  /// CHECK-DAG:                      Return [<<Xor>>]

  /// CHECK-START: int Main.XorSelfNegated(int) constant_folding (after)
  /// CHECK-DAG:     <<Const:i\d+>>  IntConstant -1
  /// CHECK-DAG:                     Return [<<Const>>]

  /// CHECK-START: int Main.XorSelfNegated(int) constant_folding (after)
  /// CHECK-NOT:                      Xor

  public static int XorSelfNegated(int arg) {
    return arg ^ ~arg;
  }

  /// CHECK-START: long Main.AndSelfNegated(long) constant_folding (before)
  /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
  /// CHECK-DAG:     <<Not:j\d+>>     Not [<<Arg>>]
  /// CHECK-DAG:     <<And:j\d+>>     And [<<Not>>,<<Arg>>]
  /// CHECK-DAG:                      Return [<<And>>]

  /// CHECK-START: long Main.AndSelfNegated(long) constant_folding (after)
  /// CHECK-DAG:     <<Const0:j\d+>>  LongConstant 0
  /// CHECK-DAG:                      Return [<<Const0>>]

  /// CHECK-START: long Main.AndSelfNegated(long) constant_folding (after)
  /// CHECK-NOT:                      And

  public static long AndSelfNegated(long arg) {
    return arg & ~arg;
  }

  /// CHECK-START: long Main.OrSelfNegated(long) constant_folding (before)
  /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
  /// CHECK-DAG:     <<Not:j\d+>>     Not [<<Arg>>]
  /// CHECK-DAG:     <<Or:j\d+>>      Or [<<Not>>,<<Arg>>]
  /// CHECK-DAG:                      Return [<<Or>>]

  /// CHECK-START: long Main.OrSelfNegated(long) constant_folding (after)
  /// CHECK-DAG:     <<Const:j\d+>>  LongConstant -1
  /// CHECK-DAG:                     Return [<<Const>>]

  /// CHECK-START: long Main.OrSelfNegated(long) constant_folding (after)
  /// CHECK-NOT:                      Or

  public static long OrSelfNegated(long arg) {
    return arg | ~arg;
  }

  /// CHECK-START: long Main.XorSelfNegated(long) constant_folding (before)
  /// CHECK-DAG:     <<Arg:j\d+>>     ParameterValue
  /// CHECK-DAG:     <<Not:j\d+>>     Not [<<Arg>>]
  /// CHECK-DAG:     <<Xor:j\d+>>     Xor [<<Not>>,<<Arg>>]
  /// CHECK-DAG:                      Return [<<Xor>>]

  /// CHECK-START: long Main.XorSelfNegated(long) constant_folding (after)
  /// CHECK-DAG:     <<Const:j\d+>>  LongConstant -1
  /// CHECK-DAG:                     Return [<<Const>>]

  /// CHECK-START: long Main.XorSelfNegated(long) constant_folding (after)
  /// CHECK-NOT:                      Xor

  public static long XorSelfNegated(long arg) {
    return arg ^ ~arg;
  }


  /**
   * Exercise constant folding on logical or.
   */

  /// CHECK-START: long Main.OrIntLong() constant_folding (before)
  /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
  /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
  /// CHECK-DAG:     <<Or:j\d+>>       Or [<<TypeConv>>,<<Const3L>>]
  /// CHECK-DAG:                       Return [<<Or>>]

  /// CHECK-START: long Main.OrIntLong() constant_folding (after)
  /// CHECK-DAG:     <<Const11:j\d+>>  LongConstant 11
  /// CHECK-DAG:                       Return [<<Const11>>]

  /// CHECK-START: long Main.OrIntLong() constant_folding (after)
  /// CHECK-NOT:                       Or

  public static long OrIntLong() {
    int lhs = 10;
    long rhs = 3;
    return lhs | rhs;
  }

  /// CHECK-START: long Main.OrLongInt() constant_folding (before)
  /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
  /// CHECK-DAG:     <<Or:j\d+>>       Or [<<TypeConv>>,<<Const10L>>]
  /// CHECK-DAG:                       Return [<<Or>>]

  /// CHECK-START: long Main.OrLongInt() constant_folding (after)
  /// CHECK-DAG:     <<Const11:j\d+>>  LongConstant 11
  /// CHECK-DAG:                       Return [<<Const11>>]

  /// CHECK-START: long Main.OrLongInt() constant_folding (after)
  /// CHECK-NOT:                       Or

  public static long OrLongInt() {
    long lhs = 10;
    int rhs = 3;
    return lhs | rhs;
  }


  /**
   * Exercise constant folding on logical exclusive or.
   */

  /// CHECK-START: long Main.XorIntLong() constant_folding (before)
  /// CHECK-DAG:     <<Const10:i\d+>>  IntConstant 10
  /// CHECK-DAG:     <<Const3L:j\d+>>  LongConstant 3
  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const10>>]
  /// CHECK-DAG:     <<Xor:j\d+>>      Xor [<<TypeConv>>,<<Const3L>>]
  /// CHECK-DAG:                       Return [<<Xor>>]

  /// CHECK-START: long Main.XorIntLong() constant_folding (after)
  /// CHECK-DAG:     <<Const9:j\d+>>   LongConstant 9
  /// CHECK-DAG:                       Return [<<Const9>>]

  /// CHECK-START: long Main.XorIntLong() constant_folding (after)
  /// CHECK-NOT:                       Xor

  public static long XorIntLong() {
    int lhs = 10;
    long rhs = 3;
    return lhs ^ rhs;
  }

  /// CHECK-START: long Main.XorLongInt() constant_folding (before)
  /// CHECK-DAG:     <<Const10L:j\d+>> LongConstant 10
  /// CHECK-DAG:     <<Const3:i\d+>>   IntConstant 3
  /// CHECK-DAG:     <<TypeConv:j\d+>> TypeConversion [<<Const3>>]
  /// CHECK-DAG:     <<Xor:j\d+>>      Xor [<<TypeConv>>,<<Const10L>>]
  /// CHECK-DAG:                       Return [<<Xor>>]

  /// CHECK-START: long Main.XorLongInt() constant_folding (after)
  /// CHECK-DAG:     <<Const9:j\d+>>   LongConstant 9
  /// CHECK-DAG:                       Return [<<Const9>>]

  /// CHECK-START: long Main.XorLongInt() constant_folding (after)
  /// CHECK-NOT:                       Xor

  public static long XorLongInt() {
    long lhs = 10;
    int rhs = 3;
    return lhs ^ rhs;
  }


  /**
   * Exercise constant folding on constant (static) condition.
   */

  /// CHECK-START: int Main.StaticCondition() constant_folding (before)
  /// CHECK-DAG:     <<Const7:i\d+>>  IntConstant 7
  /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
  /// CHECK-DAG:     <<Cond:z\d+>>    GreaterThanOrEqual [<<Const7>>,<<Const2>>]
  /// CHECK-DAG:                      If [<<Cond>>]

  /// CHECK-START: int Main.StaticCondition() constant_folding (after)
  /// CHECK-DAG:     <<Const1:i\d+>>  IntConstant 1
  /// CHECK-DAG:                      If [<<Const1>>]

  /// CHECK-START: int Main.StaticCondition() constant_folding (after)
  /// CHECK-NOT:                      GreaterThanOrEqual

  public static int StaticCondition() {
    int a, b, c;
    a = 7;
    b = 2;
    if (a < b)
      c = a + b;
    else
      c = a - b;
    return c;
  }


  /**
   * Exercise constant folding on constant (static) condition for null references.
   */

  /// CHECK-START: int Main.StaticConditionNulls() constant_folding$after_inlining (before)
  /// CHECK-DAG:     <<Null:l\d+>>    NullConstant
  /// CHECK-DAG:     <<Cond:z\d+>>    NotEqual [<<Null>>,<<Null>>]
  /// CHECK-DAG:                      If [<<Cond>>]

  /// CHECK-START: int Main.StaticConditionNulls() constant_folding$after_inlining (after)
  /// CHECK-DAG:     <<Const0:i\d+>>  IntConstant 0
  /// CHECK-DAG:                      If [<<Const0>>]

  /// CHECK-START: int Main.StaticConditionNulls() constant_folding$after_inlining (after)
  /// CHECK-NOT:                      NotEqual

  /// CHECK-START: int Main.StaticConditionNulls() dead_code_elimination$after_inlining (before)
  /// CHECK-DAG:     <<Phi:i\d+>>     Phi
  /// CHECK-DAG:                      Return [<<Phi>>]
  //
  /// CHECK-START: int Main.StaticConditionNulls() dead_code_elimination$after_inlining (after)
  /// CHECK-DAG:     <<Const5:i\d+>>  IntConstant 5
  /// CHECK-DAG:                      Return [<<Const5>>]

  private static Object getNull() {
    return null;
  }

  public static int StaticConditionNulls() {
    Object a = getNull();
    Object b = getNull();
    return (a == b) ? 5 : 2;
  }


  /**
   * Exercise constant folding on a program with condition
   * (i.e. jumps) leading to the creation of many blocks.
   *
   * The intent of this test is to ensure that all constant expressions
   * are actually evaluated at compile-time, thanks to the reverse
   * (forward) post-order traversal of the the dominator tree.
   */

  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (before)
  /// CHECK-DAG:     <<Const2:i\d+>>  IntConstant 2
  /// CHECK-DAG:     <<Const5:i\d+>>  IntConstant 5
  /// CHECK-DAG:     <<Add:i\d+>>     Add [<<Const5>>,<<Const2>>]
  /// CHECK-DAG:     <<Sub:i\d+>>     Sub [<<Const5>>,<<Const2>>]
  /// CHECK-DAG:     <<Phi:i\d+>>     Phi [<<Add>>,<<Sub>>]
  /// CHECK-DAG:                      Return [<<Phi>>]

  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (after)
  /// CHECK-DAG:     <<Const3:i\d+>>  IntConstant 3
  /// CHECK-DAG:     <<Const7:i\d+>>  IntConstant 7
  /// CHECK-DAG:     <<Phi:i\d+>>     Phi [<<Const7>>,<<Const3>>]
  /// CHECK-DAG:                      Return [<<Phi>>]

  /// CHECK-START: int Main.JumpsAndConditionals(boolean) constant_folding (after)
  /// CHECK-NOT:                      Add
  /// CHECK-NOT:                      Sub

  public static int JumpsAndConditionals(boolean cond) {
    int a, b, c;
    a = 5;
    b = 2;
    if (cond)
      c = a + b;
    else
      c = a - b;
    return c;
  }


  /**
   * Test optimizations of arithmetic identities yielding a constant result.
   */

  /// CHECK-START: long Main.Mul0(long) constant_folding (before)
  /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
  /// CHECK-DAG:     <<Mul:j\d+>>      Mul [<<Const0>>,<<Arg>>]
  /// CHECK-DAG:                       Return [<<Mul>>]

  /// CHECK-START: long Main.Mul0(long) constant_folding (after)
  /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: long Main.Mul0(long) constant_folding (after)
  /// CHECK-NOT:                       Mul

  public static long Mul0(long arg) {
    return arg * 0;
  }

  /// CHECK-START: long Main.Rem0(long) constant_folding (before)
  /// CHECK-DAG:     <<Arg:j\d+>>           ParameterValue
  /// CHECK-DAG:     <<Const0:j\d+>>        LongConstant 0
  /// CHECK-DAG:     <<DivZeroCheck:j\d+>>  DivZeroCheck [<<Arg>>]
  /// CHECK-DAG:     <<Rem:j\d+>>           Rem [<<Const0>>,<<DivZeroCheck>>]
  /// CHECK-DAG:                            Return [<<Rem>>]

  /// CHECK-START: long Main.Rem0(long) constant_folding (after)
  /// CHECK-DAG:     <<Const0:j\d+>>        LongConstant 0
  /// CHECK-DAG:                            Return [<<Const0>>]

  /// CHECK-START: long Main.Rem0(long) constant_folding (after)
  /// CHECK-NOT:                            Rem

  public static long Rem0(long arg) {
    return 0 % arg;
  }

  /// CHECK-START: int Main.Rem1(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
  /// CHECK-DAG:     <<Rem:i\d+>>      Rem [<<Arg>>,<<Const1>>]
  /// CHECK-DAG:                       Return [<<Rem>>]

  /// CHECK-START: int Main.Rem1(int) constant_folding (after)
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: int Main.Rem1(int) constant_folding (after)
  /// CHECK-NOT:                       Rem

  public static int Rem1(int arg) {
    return arg % 1;
  }

  /// CHECK-START: int Main.RemN1(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<ConstN1:i\d+>>  IntConstant -1
  /// CHECK-DAG:     <<Rem:i\d+>>      Rem [<<Arg>>,<<ConstN1>>]
  /// CHECK-DAG:                       Return [<<Rem>>]

  /// CHECK-START: int Main.RemN1(int) constant_folding (after)
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: int Main.RemN1(int) constant_folding (after)
  /// CHECK-NOT:                       Rem

  public static int RemN1(int arg) {
    return arg % -1;
  }

  /// CHECK-START: long Main.Rem1(long) constant_folding (before)
  /// CHECK-DAG:     <<Arg:j\d+>>           ParameterValue
  /// CHECK-DAG:     <<Const1:j\d+>>        LongConstant 1
  /// CHECK-DAG:     <<DivZeroCheck:j\d+>>  DivZeroCheck [<<Const1>>]
  /// CHECK-DAG:     <<Rem:j\d+>>           Rem [<<Arg>>,<<DivZeroCheck>>]
  /// CHECK-DAG:                            Return [<<Rem>>]

  /// CHECK-START: long Main.Rem1(long) constant_folding (after)
  /// CHECK-DAG:     <<Const0:j\d+>>        LongConstant 0
  /// CHECK-DAG:                            Return [<<Const0>>]

  /// CHECK-START: long Main.Rem1(long) constant_folding (after)
  /// CHECK-NOT:                            Rem

  public static long Rem1(long arg) {
    return arg % 1;
  }

  /// CHECK-START: long Main.RemN1(long) constant_folding (before)
  /// CHECK-DAG:     <<Arg:j\d+>>           ParameterValue
  /// CHECK-DAG:     <<ConstN1:j\d+>>       LongConstant -1
  /// CHECK-DAG:     <<DivZeroCheck:j\d+>>  DivZeroCheck [<<ConstN1>>]
  /// CHECK-DAG:     <<Rem:j\d+>>           Rem [<<Arg>>,<<DivZeroCheck>>]
  /// CHECK-DAG:                            Return [<<Rem>>]

  /// CHECK-START: long Main.RemN1(long) constant_folding (after)
  /// CHECK-DAG:     <<Const0:j\d+>>        LongConstant 0
  /// CHECK-DAG:                            Return [<<Const0>>]

  /// CHECK-START: long Main.RemN1(long) constant_folding (after)
  /// CHECK-NOT:                            Rem

  public static long RemN1(long arg) {
    return arg % -1;
  }

  /// CHECK-START: int Main.Shl0(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:     <<Shl:i\d+>>      Shl [<<Const0>>,<<Arg>>]
  /// CHECK-DAG:                       Return [<<Shl>>]

  /// CHECK-START: int Main.Shl0(int) constant_folding (after)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: int Main.Shl0(int) constant_folding (after)
  /// CHECK-NOT:                       Shl

  public static int Shl0(int arg) {
    return 0 << arg;
  }

  /// CHECK-START: long Main.ShlLong0WithInt(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0L:j\d+>>  LongConstant 0
  /// CHECK-DAG:     <<Shl:j\d+>>      Shl [<<Const0L>>,<<Arg>>]
  /// CHECK-DAG:                       Return [<<Shl>>]

  /// CHECK-START: long Main.ShlLong0WithInt(int) constant_folding (after)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0L:j\d+>>  LongConstant 0
  /// CHECK-DAG:                       Return [<<Const0L>>]

  /// CHECK-START: long Main.ShlLong0WithInt(int) constant_folding (after)
  /// CHECK-NOT:                       Shl

  public static long ShlLong0WithInt(int arg) {
    long long_zero = 0;
    return long_zero << arg;
  }

  /// CHECK-START: long Main.Shr0(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
  /// CHECK-DAG:     <<Shr:j\d+>>      Shr [<<Const0>>,<<Arg>>]
  /// CHECK-DAG:                       Return [<<Shr>>]

  /// CHECK-START: long Main.Shr0(int) constant_folding (after)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: long Main.Shr0(int) constant_folding (after)
  /// CHECK-NOT:                       Shr

  public static long Shr0(int arg) {
    return (long)0 >> arg;
  }

  /// CHECK-START: long Main.SubSameLong(long) constant_folding (before)
  /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
  /// CHECK-DAG:     <<Sub:j\d+>>      Sub [<<Arg>>,<<Arg>>]
  /// CHECK-DAG:                       Return [<<Sub>>]

  /// CHECK-START: long Main.SubSameLong(long) constant_folding (after)
  /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: long Main.SubSameLong(long) constant_folding (after)
  /// CHECK-NOT:                       Sub

  public static long SubSameLong(long arg) {
    return arg - arg;
  }

  /// CHECK-START: int Main.UShr0(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:     <<UShr:i\d+>>     UShr [<<Const0>>,<<Arg>>]
  /// CHECK-DAG:                       Return [<<UShr>>]

  /// CHECK-START: int Main.UShr0(int) constant_folding (after)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: int Main.UShr0(int) constant_folding (after)
  /// CHECK-NOT:                       UShr

  public static int UShr0(int arg) {
    return 0 >>> arg;
  }

  /// CHECK-START: int Main.XorSameInt(int) constant_folding (before)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Xor:i\d+>>      Xor [<<Arg>>,<<Arg>>]
  /// CHECK-DAG:                       Return [<<Xor>>]

  /// CHECK-START: int Main.XorSameInt(int) constant_folding (after)
  /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: int Main.XorSameInt(int) constant_folding (after)
  /// CHECK-NOT:                       Xor

  public static int XorSameInt(int arg) {
    return arg ^ arg;
  }

  /// CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (before)
  /// CHECK-DAG:     <<Arg:f\d+>>      ParameterValue
  /// CHECK-DAG:     <<ConstNan:f\d+>> FloatConstant nan
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:                       IntConstant 1
  /// CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Arg>>,<<ConstNan>>]
  /// CHECK-DAG:     <<Le:z\d+>>       LessThanOrEqual [<<Cmp>>,<<Const0>>]
  /// CHECK-DAG:                       If [<<Le>>]

  /// CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (after)
  /// CHECK-DAG:                       ParameterValue
  /// CHECK-DAG:                       FloatConstant nan
  /// CHECK-DAG:                       IntConstant 0
  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
  /// CHECK-DAG:                       If [<<Const1>>]

  /// CHECK-START: boolean Main.CmpFloatGreaterThanNaN(float) constant_folding (after)
  /// CHECK-NOT:                       Compare
  /// CHECK-NOT:                       LessThanOrEqual

  public static boolean CmpFloatGreaterThanNaN(float arg) {
    return arg > Float.NaN;
  }

  /// CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (before)
  /// CHECK-DAG:     <<Arg:d\d+>>      ParameterValue
  /// CHECK-DAG:     <<ConstNan:d\d+>> DoubleConstant nan
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:                       IntConstant 1
  /// CHECK-DAG:     <<Cmp:i\d+>>      Compare [<<Arg>>,<<ConstNan>>]
  /// CHECK-DAG:     <<Ge:z\d+>>       GreaterThanOrEqual [<<Cmp>>,<<Const0>>]
  /// CHECK-DAG:                       If [<<Ge>>]

  /// CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (after)
  /// CHECK-DAG:                       ParameterValue
  /// CHECK-DAG:                       DoubleConstant nan
  /// CHECK-DAG:                       IntConstant 0
  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
  /// CHECK-DAG:                       If [<<Const1>>]

  /// CHECK-START: boolean Main.CmpDoubleLessThanNaN(double) constant_folding (after)
  /// CHECK-NOT:                       Compare
  /// CHECK-NOT:                       GreaterThanOrEqual

  public static boolean CmpDoubleLessThanNaN(double arg) {
    return arg < Double.NaN;
  }


  /**
   * Exercise constant folding on type conversions.
   */

  /// CHECK-START: int Main.ReturnInt33() constant_folding (before)
  /// CHECK-DAG:     <<Const33:j\d+>>  LongConstant 33
  /// CHECK-DAG:     <<Convert:i\d+>>  TypeConversion [<<Const33>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: int Main.ReturnInt33() constant_folding (after)
  /// CHECK-DAG:     <<Const33:i\d+>>  IntConstant 33
  /// CHECK-DAG:                       Return [<<Const33>>]

  /// CHECK-START: int Main.ReturnInt33() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static int ReturnInt33() {
    long imm = 33L;
    return (int) imm;
  }

  /// CHECK-START: int Main.ReturnIntMax() constant_folding (before)
  /// CHECK-DAG:     <<ConstMax:f\d+>> FloatConstant 1e+34
  /// CHECK-DAG:     <<Convert:i\d+>>  TypeConversion [<<ConstMax>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: int Main.ReturnIntMax() constant_folding (after)
  /// CHECK-DAG:     <<ConstMax:i\d+>> IntConstant 2147483647
  /// CHECK-DAG:                       Return [<<ConstMax>>]

  /// CHECK-START: int Main.ReturnIntMax() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static int ReturnIntMax() {
    float imm = 1.0e34f;
    return (int) imm;
  }

  /// CHECK-START: int Main.ReturnInt0() constant_folding (before)
  /// CHECK-DAG:     <<ConstNaN:d\d+>> DoubleConstant nan
  /// CHECK-DAG:     <<Convert:i\d+>>  TypeConversion [<<ConstNaN>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: int Main.ReturnInt0() constant_folding (after)
  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: int Main.ReturnInt0() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static int ReturnInt0() {
    double imm = Double.NaN;
    return (int) imm;
  }

  /// CHECK-START: long Main.ReturnLong33() constant_folding (before)
  /// CHECK-DAG:     <<Const33:i\d+>>  IntConstant 33
  /// CHECK-DAG:     <<Convert:j\d+>>  TypeConversion [<<Const33>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: long Main.ReturnLong33() constant_folding (after)
  /// CHECK-DAG:     <<Const33:j\d+>>  LongConstant 33
  /// CHECK-DAG:                       Return [<<Const33>>]

  /// CHECK-START: long Main.ReturnLong33() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static long ReturnLong33() {
    int imm = 33;
    return (long) imm;
  }

  /// CHECK-START: long Main.ReturnLong34() constant_folding (before)
  /// CHECK-DAG:     <<Const34:f\d+>>  FloatConstant 34
  /// CHECK-DAG:     <<Convert:j\d+>>  TypeConversion [<<Const34>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: long Main.ReturnLong34() constant_folding (after)
  /// CHECK-DAG:     <<Const34:j\d+>>  LongConstant 34
  /// CHECK-DAG:                       Return [<<Const34>>]

  /// CHECK-START: long Main.ReturnLong34() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static long ReturnLong34() {
    float imm = 34.0f;
    return (long) imm;
  }

  /// CHECK-START: long Main.ReturnLong0() constant_folding (before)
  /// CHECK-DAG:     <<ConstNaN:d\d+>> DoubleConstant nan
  /// CHECK-DAG:     <<Convert:j\d+>>  TypeConversion [<<ConstNaN>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: long Main.ReturnLong0() constant_folding (after)
  /// CHECK-DAG:     <<Const0:j\d+>>   LongConstant 0
  /// CHECK-DAG:                       Return [<<Const0>>]

  /// CHECK-START: long Main.ReturnLong0() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static long ReturnLong0() {
    double imm = -Double.NaN;
    return (long) imm;
  }

  /// CHECK-START: float Main.ReturnFloat33() constant_folding (before)
  /// CHECK-DAG:     <<Const33:i\d+>>  IntConstant 33
  /// CHECK-DAG:     <<Convert:f\d+>>  TypeConversion [<<Const33>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: float Main.ReturnFloat33() constant_folding (after)
  /// CHECK-DAG:     <<Const33:f\d+>>  FloatConstant 33
  /// CHECK-DAG:                       Return [<<Const33>>]

  /// CHECK-START: float Main.ReturnFloat33() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static float ReturnFloat33() {
    int imm = 33;
    return (float) imm;
  }

  /// CHECK-START: float Main.ReturnFloat34() constant_folding (before)
  /// CHECK-DAG:     <<Const34:j\d+>>  LongConstant 34
  /// CHECK-DAG:     <<Convert:f\d+>>  TypeConversion [<<Const34>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: float Main.ReturnFloat34() constant_folding (after)
  /// CHECK-DAG:     <<Const34:f\d+>>  FloatConstant 34
  /// CHECK-DAG:                       Return [<<Const34>>]

  /// CHECK-START: float Main.ReturnFloat34() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static float ReturnFloat34() {
    long imm = 34L;
    return (float) imm;
  }

  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding (before)
  /// CHECK-DAG:     <<Const:d\d+>>    DoubleConstant 99.25
  /// CHECK-DAG:     <<Convert:f\d+>>  TypeConversion [<<Const>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding (after)
  /// CHECK-DAG:     <<Const:f\d+>>    FloatConstant 99.25
  /// CHECK-DAG:                       Return [<<Const>>]

  /// CHECK-START: float Main.ReturnFloat99P25() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static float ReturnFloat99P25() {
    double imm = 99.25;
    return (float) imm;
  }

  /// CHECK-START: double Main.ReturnDouble33() constant_folding (before)
  /// CHECK-DAG:     <<Const33:i\d+>>  IntConstant 33
  /// CHECK-DAG:     <<Convert:d\d+>>  TypeConversion [<<Const33>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: double Main.ReturnDouble33() constant_folding (after)
  /// CHECK-DAG:     <<Const33:d\d+>>  DoubleConstant 33
  /// CHECK-DAG:                       Return [<<Const33>>]

  public static double ReturnDouble33() {
    int imm = 33;
    return (double) imm;
  }

  /// CHECK-START: double Main.ReturnDouble34() constant_folding (before)
  /// CHECK-DAG:     <<Const34:j\d+>>  LongConstant 34
  /// CHECK-DAG:     <<Convert:d\d+>>  TypeConversion [<<Const34>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: double Main.ReturnDouble34() constant_folding (after)
  /// CHECK-DAG:     <<Const34:d\d+>>  DoubleConstant 34
  /// CHECK-DAG:                       Return [<<Const34>>]

  /// CHECK-START: double Main.ReturnDouble34() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static double ReturnDouble34() {
    long imm = 34L;
    return (double) imm;
  }

  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding (before)
  /// CHECK-DAG:     <<Const:f\d+>>    FloatConstant 99.25
  /// CHECK-DAG:     <<Convert:d\d+>>  TypeConversion [<<Const>>]
  /// CHECK-DAG:                       Return [<<Convert>>]

  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding (after)
  /// CHECK-DAG:     <<Const:d\d+>>    DoubleConstant 99.25
  /// CHECK-DAG:                       Return [<<Const>>]

  /// CHECK-START: double Main.ReturnDouble99P25() constant_folding (after)
  /// CHECK-NOT:                       TypeConversion

  public static double ReturnDouble99P25() {
    float imm = 99.25f;
    return (double) imm;
  }

  /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (before)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Mul

  /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (before)
  /// CHECK-NOT:     IntConstant 6

  /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (after)
  /// CHECK-NOT:     Add

  /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (after)
  /// CHECK-NOT:     Mul

  /// CHECK-START: int Main.$inline$SpecialCaseForZeroInt(int) constant_folding (after)
  /// CHECK-DAG:     <<Const:i\d+>>    IntConstant 6
  /// CHECK-DAG:                       Return [<<Const>>]
  private static int $inline$SpecialCaseForZeroInt(int value) {
    if (value == 0) {
      return (value + 2) * 3;
    }
    return value;
  }

  /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (before)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Mul

  /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (before)
  /// CHECK-NOT:     LongConstant 6

  /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (after)
  /// CHECK-NOT:     Add

  /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (after)
  /// CHECK-NOT:     Mul

  /// CHECK-START: long Main.$inline$SpecialCaseForZeroLong(long) constant_folding (after)
  /// CHECK-DAG:     <<Const:j\d+>>    LongConstant 6
  /// CHECK-DAG:                       Return [<<Const>>]
  private static long $inline$SpecialCaseForZeroLong(long value) {
    if (value == 0L) {
      return (value + 2) * 3;
    }
    return value;
  }

  /// CHECK-START: float Main.$noinline$SpecialCaseForZeroFloat(float) constant_folding (before)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Mul

  /// CHECK-START: float Main.$noinline$SpecialCaseForZeroFloat(float) constant_folding (after)
  /// CHECK-NOT:     FloatConstant 6

  /// CHECK-START: float Main.$noinline$SpecialCaseForZeroFloat(float) constant_folding (after)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Mul
  private static float $noinline$SpecialCaseForZeroFloat(float value) {
    if (value == 0F) {
      return (value + 2F) * 3F;
    }
    return value;
  }

  /// CHECK-START: double Main.$noinline$SpecialCaseForZeroDouble(double) constant_folding (before)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Mul

  /// CHECK-START: double Main.$noinline$SpecialCaseForZeroDouble(double) constant_folding (after)
  /// CHECK-NOT:     DoubleConstant 6

  /// CHECK-START: double Main.$noinline$SpecialCaseForZeroDouble(double) constant_folding (after)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Mul
  private static double $noinline$SpecialCaseForZeroDouble(double value) {
    if (value == 0D) {
      return (value + 2D) * 3D;
    }
    return value;
  }

  // Note that we have Add instead of sub since internally we do `Add(value, -1)`.
  /// CHECK-START: int Main.$noinline$NotEqualsPropagationInt(int) constant_folding (before)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Div

  /// CHECK-START: int Main.$noinline$NotEqualsPropagationInt(int) constant_folding (after)
  /// CHECK-NOT:     Add

  /// CHECK-START: int Main.$noinline$NotEqualsPropagationInt(int) constant_folding (after)
  /// CHECK-NOT:     Div

  /// CHECK-START: int Main.$noinline$NotEqualsPropagationInt(int) constant_folding (after)
  /// CHECK-DAG:     <<Const:i\d+>>    IntConstant 1
  /// CHECK-DAG:                       Return [<<Const>>]
  private static int $noinline$NotEqualsPropagationInt(int value) {
    if (value != 3) {
      return value;
    } else {
      return (value - 1) / 2;
    }
  }

  /// CHECK-START: long Main.$noinline$NotEqualsPropagationLong(long) constant_folding (before)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div

  /// CHECK-START: long Main.$noinline$NotEqualsPropagationLong(long) constant_folding (after)
  /// CHECK-NOT:     Sub

  /// CHECK-START: long Main.$noinline$NotEqualsPropagationLong(long) constant_folding (after)
  /// CHECK-NOT:     Div

  /// CHECK-START: long Main.$noinline$NotEqualsPropagationLong(long) constant_folding (after)
  /// CHECK-DAG:     <<Const:j\d+>>    LongConstant 1
  /// CHECK-DAG:                       Return [<<Const>>]
  private static long $noinline$NotEqualsPropagationLong(long value) {
    if (value != 3L) {
      return value;
    } else {
      return (value - 1L) / 2L;
    }
  }

  /// CHECK-START: float Main.$noinline$NotEqualsPropagationFloat(float) constant_folding (before)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div

  /// CHECK-START: float Main.$noinline$NotEqualsPropagationFloat(float) constant_folding (after)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div
  private static float $noinline$NotEqualsPropagationFloat(float value) {
    if (value != 3F) {
      return value;
    } else {
      return (value - 1F) / 2F;
    }
  }

  /// CHECK-START: double Main.$noinline$NotEqualsPropagationDouble(double) constant_folding (before)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div

  /// CHECK-START: double Main.$noinline$NotEqualsPropagationDouble(double) constant_folding (after)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div
  private static double $noinline$NotEqualsPropagationDouble(double value) {
    if (value != 3D) {
      return value;
    } else {
      return (value - 1D) / 2D;
    }
  }

  /// CHECK-START: int Main.$noinline$InlineCaleeWithSpecialCaseForZeroInt(int) inliner (after)
  /// CHECK-NOT:     Add

  /// CHECK-START: int Main.$noinline$InlineCaleeWithSpecialCaseForZeroInt(int) inliner (after)
  /// CHECK-NOT:     Mul

  /// CHECK-START: int Main.$noinline$InlineCaleeWithSpecialCaseForZeroInt(int) inliner (after)
  /// CHECK-DAG:     <<Const:i\d+>>    IntConstant 6
  /// CHECK-DAG:                       Return [<<Const>>]
  private static int $noinline$InlineCaleeWithSpecialCaseForZeroInt(int value) {
    if (value == 0) {
      return $inline$SpecialCaseForZeroInt(value);
    }
    return value;
  }

  /// CHECK-START: long Main.$noinline$InlineCaleeWithSpecialCaseForZeroLong(long) inliner (after)
  /// CHECK-NOT:     Add

  /// CHECK-START: long Main.$noinline$InlineCaleeWithSpecialCaseForZeroLong(long) inliner (after)
  /// CHECK-NOT:     Mul

  /// CHECK-START: long Main.$noinline$InlineCaleeWithSpecialCaseForZeroLong(long) inliner (after)
  /// CHECK-DAG:     <<Const:j\d+>>    LongConstant 6
  /// CHECK-DAG:                       Return [<<Const>>]
  private static long $noinline$InlineCaleeWithSpecialCaseForZeroLong(long value) {
    if (value == 0L) {
      return $inline$SpecialCaseForZeroLong(value);
    }
    return value;
  }

  // Check that don't propagate the value == 3 on `if not true` branch, as the `if true` branch also
  // flows into the same block.
  /// CHECK-START: int Main.$noinline$NotEqualsImplicitElseInt(int) constant_folding (before)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Div

  /// CHECK-START: int Main.$noinline$NotEqualsImplicitElseInt(int) constant_folding (after)
  /// CHECK-DAG:     Add
  /// CHECK-DAG:     Div
  private static int $noinline$NotEqualsImplicitElseInt(int value) {
    if (value != 3) {
      value++;
    }
    return (value - 1) / 2;
  }

  /// CHECK-START: long Main.$noinline$NotEqualsImplicitElseLong(long) constant_folding (before)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div

  /// CHECK-START: long Main.$noinline$NotEqualsImplicitElseLong(long) constant_folding (after)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div
  private static long $noinline$NotEqualsImplicitElseLong(long value) {
    if (value != 3L) {
      value += 1L;
    }
    return (value - 1L) / 2L;
  }

  /// CHECK-START: float Main.$noinline$NotEqualsImplicitElseFloat(float) constant_folding (before)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div

  /// CHECK-START: float Main.$noinline$NotEqualsImplicitElseFloat(float) constant_folding (after)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div
  private static float $noinline$NotEqualsImplicitElseFloat(float value) {
    if (value != 3F) {
      value += 1F;
    }
    return (value - 1F) / 2F;
  }

  /// CHECK-START: double Main.$noinline$NotEqualsImplicitElseDouble(double) constant_folding (before)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div

  /// CHECK-START: double Main.$noinline$NotEqualsImplicitElseDouble(double) constant_folding (after)
  /// CHECK-DAG:     Sub
  /// CHECK-DAG:     Div
  private static double $noinline$NotEqualsImplicitElseDouble(double value) {
    if (value != 3D) {
      value += 1D;
    }
    return (value - 1D) / 2D;
  }

  // By propagating the boolean we can elimniate some equality comparisons as we already know their
  // result. In turn, we also enable DeadCodeElimination to eliminate more code.
  /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) constant_folding (before)
  /// CHECK-DAG:     Equal
  /// CHECK-DAG:     Equal
  /// CHECK-DAG:     Equal

  /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) constant_folding (after)
  /// CHECK:         Equal
  /// CHECK-NOT:     Equal

  /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) dead_code_elimination$initial (before)
  /// CHECK-DAG:     IntConstant 1
  /// CHECK-DAG:     IntConstant 2
  /// CHECK-DAG:     IntConstant 3
  /// CHECK-DAG:     IntConstant 4

  /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) dead_code_elimination$initial (after)
  /// CHECK-DAG:     IntConstant 1
  /// CHECK-DAG:     IntConstant 4

  /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) dead_code_elimination$initial (after)
  /// CHECK-NOT:     IntConstant 2

  /// CHECK-START: int Main.$noinline$PropagatingParameterValue(boolean) dead_code_elimination$initial (after)
  /// CHECK-NOT:     IntConstant 3
  private static int $noinline$PropagatingParameterValue(boolean value) {
    if (value) {
      return value ? 1 : 2;
    } else {
      return value ? 3 : 4;
    }
  }

  public static void main(String[] args) throws Exception {
    assertIntEquals(-42, IntNegation());
    assertLongEquals(-42L, LongNegation());
    assertFloatEquals(-42F, FloatNegation());
    assertDoubleEquals(-42D, DoubleNegation());

    assertIntEquals(3, IntAddition1());
    assertIntEquals(14, IntAddition2());
    assertIntEquals(14, smaliIntAddition2());
    assertIntEquals(14, smaliIntAddition2AddAndMove());
    assertLongEquals(3L, LongAddition());
    assertFloatEquals(3F, FloatAddition());
    assertDoubleEquals(3D, DoubleAddition());

    assertIntEquals(4, IntSubtraction());
    assertLongEquals(4L, LongSubtraction());
    assertFloatEquals(4F, FloatSubtraction());
    assertDoubleEquals(4D, DoubleSubtraction());

    assertIntEquals(21, IntMultiplication());
    assertLongEquals(21L, LongMultiplication());
    assertFloatEquals(21F, FloatMultiplication());
    assertDoubleEquals(21D, DoubleMultiplication());

    assertIntEquals(2, IntDivision());
    assertLongEquals(2L, LongDivision());
    assertFloatEquals(3.2F, FloatDivision());
    assertDoubleEquals(3.2D, DoubleDivision());

    assertIntEquals(2, IntRemainder());
    assertLongEquals(2L, LongRemainder());
    assertFloatEquals(0.5F, FloatRemainder());
    assertDoubleEquals(0.5D, DoubleRemainder());

    assertIntEquals(4, ShlIntLong());
    assertLongEquals(12L, ShlLongInt());

    assertIntEquals(1, ShrIntLong());
    assertLongEquals(2L, ShrLongInt());

    assertIntEquals(1073741822, UShrIntLong());
    assertLongEquals(4611686018427387901L, UShrLongInt());

    assertLongEquals(2, AndIntLong());
    assertLongEquals(2, AndLongInt());

    assertLongEquals(11, OrIntLong());
    assertLongEquals(11, OrLongInt());

    assertLongEquals(9, XorIntLong());
    assertLongEquals(9, XorLongInt());

    assertIntEquals(5, StaticCondition());
    assertIntEquals(5, StaticConditionNulls());

    assertIntEquals(7, JumpsAndConditionals(true));
    assertIntEquals(3, JumpsAndConditionals(false));
    assertIntEquals(7, smaliJumpsAndConditionals(true));
    assertIntEquals(3, smaliJumpsAndConditionals(false));

    int arbitrary = 123456;  // Value chosen arbitrarily.

    assertIntEquals(0, Main.smaliAnd0(arbitrary));
    assertLongEquals(0, Mul0(arbitrary));
    assertIntEquals(-1, Main.smaliOrAllOnes(arbitrary));
    assertLongEquals(0, Rem0(arbitrary));
    assertIntEquals(0, Rem1(arbitrary));
    assertIntEquals(0, Rem1(0));
    assertIntEquals(0, Rem1(-1));
    assertIntEquals(0, Rem1(Integer.MAX_VALUE));
    assertIntEquals(0, Rem1(Integer.MIN_VALUE));
    assertIntEquals(0, RemN1(arbitrary));
    assertIntEquals(0, RemN1(0));
    assertIntEquals(0, RemN1(-1));
    assertIntEquals(0, RemN1(Integer.MAX_VALUE));
    assertIntEquals(0, RemN1(Integer.MIN_VALUE));
    assertIntEquals(0, RemN1(arbitrary));
    assertLongEquals(0, Rem1((long)arbitrary));
    assertLongEquals(0, Rem1(0L));
    assertLongEquals(0, Rem1(-1L));
    assertLongEquals(0, Rem1(Long.MAX_VALUE));
    assertLongEquals(0, Rem1(Long.MIN_VALUE));
    assertLongEquals(0, RemN1(arbitrary));
    assertLongEquals(0, RemN1(0L));
    assertLongEquals(0, RemN1(-1L));
    assertLongEquals(0, RemN1(Long.MAX_VALUE));
    assertLongEquals(0, RemN1(Long.MIN_VALUE));
    assertIntEquals(0, Shl0(arbitrary));
    assertLongEquals(0, ShlLong0WithInt(arbitrary));
    assertLongEquals(0, Shr0(arbitrary));
    assertLongEquals(0, SubSameLong(arbitrary));
    assertIntEquals(0, UShr0(arbitrary));
    assertIntEquals(0, XorSameInt(arbitrary));

    assertFalse(CmpFloatGreaterThanNaN(arbitrary));
    assertFalse(CmpDoubleLessThanNaN(arbitrary));

    Main main = new Main();
    assertIntEquals(1, main.smaliCmpLongConstants());
    assertIntEquals(-1, main.smaliCmpGtFloatConstants());
    assertIntEquals(-1, main.smaliCmpLtFloatConstants());
    assertIntEquals(-1, main.smaliCmpGtDoubleConstants());
    assertIntEquals(-1, main.smaliCmpLtDoubleConstants());

    assertIntEquals(0, main.smaliCmpLongSameConstant());
    assertIntEquals(0, main.smaliCmpGtFloatSameConstant());
    assertIntEquals(0, main.smaliCmpLtFloatSameConstant());
    assertIntEquals(0, main.smaliCmpGtDoubleSameConstant());
    assertIntEquals(0, main.smaliCmpLtDoubleSameConstant());

    assertIntEquals(1, main.smaliCmpGtFloatConstantWithNaN());
    assertIntEquals(-1, main.smaliCmpLtFloatConstantWithNaN());
    assertIntEquals(1, main.smaliCmpGtDoubleConstantWithNaN());
    assertIntEquals(-1, main.smaliCmpLtDoubleConstantWithNaN());

    assertIntEquals(33, ReturnInt33());
    assertIntEquals(2147483647, ReturnIntMax());
    assertIntEquals(0, ReturnInt0());

    assertLongEquals(33, ReturnLong33());
    assertLongEquals(34, ReturnLong34());
    assertLongEquals(0, ReturnLong0());

    assertFloatEquals(33, ReturnFloat33());
    assertFloatEquals(34, ReturnFloat34());
    assertFloatEquals(99.25f, ReturnFloat99P25());

    assertDoubleEquals(33, ReturnDouble33());
    assertDoubleEquals(34, ReturnDouble34());
    assertDoubleEquals(99.25, ReturnDouble99P25());

    // Tests for propagating known values due to if clauses.

    // Propagating within the same method. These are marked $inline$ since we used them in
    // `InlineCaleeWithSpecialCaseForZeroInt`.
    assertIntEquals(6, $inline$SpecialCaseForZeroInt(0));
    assertIntEquals(3, $inline$SpecialCaseForZeroInt(3));
    assertLongEquals(6L, $inline$SpecialCaseForZeroLong(0L));
    assertLongEquals(3L, $inline$SpecialCaseForZeroLong(3L));
    // Floats and doubles we do not optimize (here and below). These methods are here to guarantee
    // that.
    assertFloatEquals(6F, $noinline$SpecialCaseForZeroFloat(0F));
    assertFloatEquals(3F, $noinline$SpecialCaseForZeroFloat(3F));
    assertDoubleEquals(6D, $noinline$SpecialCaseForZeroDouble(0D));
    assertDoubleEquals(3D, $noinline$SpecialCaseForZeroDouble(3D));

    // Propagating within the same method, with not equals
    assertIntEquals(0, $noinline$NotEqualsPropagationInt(0));
    assertIntEquals(1, $noinline$NotEqualsPropagationInt(3));
    assertLongEquals(0L, $noinline$NotEqualsPropagationLong(0L));
    assertLongEquals(1L, $noinline$NotEqualsPropagationLong(3L));
    assertFloatEquals(0F, $noinline$NotEqualsPropagationFloat(0F));
    assertFloatEquals(1F, $noinline$NotEqualsPropagationFloat(3F));
    assertDoubleEquals(0D, $noinline$NotEqualsPropagationDouble(0D));
    assertDoubleEquals(1D, $noinline$NotEqualsPropagationDouble(3D));

    // Propagating so that the inliner can use it.
    assertIntEquals(6, $noinline$InlineCaleeWithSpecialCaseForZeroInt(0));
    assertIntEquals(3, $noinline$InlineCaleeWithSpecialCaseForZeroInt(3));
    assertLongEquals(6L, $noinline$InlineCaleeWithSpecialCaseForZeroLong(0L));
    assertLongEquals(3L, $noinline$InlineCaleeWithSpecialCaseForZeroLong(3L));

    // Propagating within the same method, with not equals
    assertIntEquals(0, $noinline$NotEqualsImplicitElseInt(0));
    assertIntEquals(1, $noinline$NotEqualsImplicitElseInt(3));
    assertLongEquals(0L, $noinline$NotEqualsImplicitElseLong(0L));
    assertLongEquals(1L, $noinline$NotEqualsImplicitElseLong(3L));
    assertFloatEquals(0F, $noinline$NotEqualsImplicitElseFloat(0F));
    assertFloatEquals(1F, $noinline$NotEqualsImplicitElseFloat(3F));
    assertDoubleEquals(0D, $noinline$NotEqualsImplicitElseDouble(0D));
    assertDoubleEquals(1D, $noinline$NotEqualsImplicitElseDouble(3D));

    // Propagating parameters.
    assertIntEquals(1, $noinline$PropagatingParameterValue(true));
    assertIntEquals(4, $noinline$PropagatingParameterValue(false));
  }

  Main() throws ClassNotFoundException {
    testCmp = Class.forName("TestCmp");
  }

  private Class<?> testCmp;
}
