Reland "Propagating values from if clauses to its successors"

This reverts commit fa1034c563b44c4f557814c50e2678e14dcd1d13.

Reason for revert: Relanding after float/double fix. In short,
don't deal with floats/doubles since they bring a lot of edge cases e.g.

  if (f == 0.0f) {
    // f is not guaranteed to be 0.0f, e.g. it could be -0.0f.
  }

Bug: 240543764
Change-Id: I400bdab71dba0934e6f1740538fe6e6c0a7bf5fc
diff --git a/test/2042-checker-dce-always-throw/src/Main.java b/test/2042-checker-dce-always-throw/src/Main.java
index b601f20..bc2e7a1 100644
--- a/test/2042-checker-dce-always-throw/src/Main.java
+++ b/test/2042-checker-dce-always-throw/src/Main.java
@@ -27,11 +27,11 @@
     // Try catch tests
     assertEquals(0, $noinline$testDoNotSimplifyInTry(1));
     assertEquals(0, $noinline$testSimplifyInCatch(1));
-    assertEquals(0, $noinline$testDoNotSimplifyInCatchInOuterTry(1));
+    assertEquals(0, $noinline$testDoNotSimplifyInCatchInOuterTry(1, 1));
 
     // Test that we update the phis correctly after simplifying an always throwing method, and
     // recomputing dominance.
-    assertEquals(0, $noinline$UpdatePhisCorrectly(1));
+    assertEquals(0, $noinline$UpdatePhisCorrectly(1, 1));
   }
 
   private static void alwaysThrows() throws Error {
@@ -251,25 +251,25 @@
     }
   }
 
-  /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int) dead_code_elimination$after_inlining (before)
+  /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (before)
   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
 
-  /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int) dead_code_elimination$after_inlining (after)
+  /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (after)
   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
 
   // Consistency check to make sure we have the try catches in the graph at this stage.
-  /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int) dead_code_elimination$after_inlining (before)
+  /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$after_inlining (before)
   /// CHECK-DAG:   TryBoundary kind:entry
   /// CHECK-DAG:   TryBoundary kind:entry
 
   // Consistency check to that we do not simplify it by the last DCE pass either
-  /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int) dead_code_elimination$final (after)
+  /// CHECK-START: int Main.$noinline$testDoNotSimplifyInCatchInOuterTry(int, int) dead_code_elimination$final (after)
   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
@@ -278,13 +278,15 @@
   // Similar to testSimplifyInCatch, but now the throw is in an outer try and we shouldn't simplify
   // it. Like in testDoNotSimplifyInTry, we need the help of the inliner to have an invoke followed
   // by a Goto.
-  private static int $noinline$testDoNotSimplifyInCatchInOuterTry(int num) {
+  private static int $noinline$testDoNotSimplifyInCatchInOuterTry(int num, int other_num) {
     try {
       try {
         throw new Error();
       } catch (Error e) {
         if (num == 0) {
-          $inline$testDoNotSimplifyInner(num);
+          // We use `other_num` here because otherwise we propagate the knowledge that `num` equals
+          // zero.
+          $inline$testDoNotSimplifyInner(other_num);
         }
         return 0;
       }
@@ -296,7 +298,7 @@
   // Check that when we perform SimplifyAlwaysThrows, that the phi for `phi_value` exists, and that
   // we correctly update it after running DCE.
 
-  /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int) dead_code_elimination$after_inlining (before)
+  /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int, int) dead_code_elimination$after_inlining (before)
   /// CHECK-DAG:   <<Const0:i\d+>> IntConstant 0
   /// CHECK-DAG:   <<Const5:i\d+>> IntConstant 5
   /// CHECK-DAG:   <<ReturnValue:i\d+>> Phi [<<Const0>>,<<Const5>>]
@@ -306,23 +308,24 @@
   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<TargetBlock:B\d+>>
   /// CHECK-EVAL:  "<<ExitBlock>>" != "<<TargetBlock>>"
 
-  /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int) dead_code_elimination$after_inlining (after)
+  /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int, int) dead_code_elimination$after_inlining (after)
   /// CHECK-DAG:   <<Const0:i\d+>> IntConstant 0
   /// CHECK-DAG:   Return [<<Const0>>]
   /// CHECK-DAG:   InvokeStaticOrDirect block:<<InvokeBlock:B\d+>> method_name:Main.alwaysThrows always_throws:true
   /// CHECK-DAG:   Exit block:<<ExitBlock:B\d+>>
   /// CHECK-DAG:   Goto block:<<InvokeBlock>> target:<<ExitBlock>>
 
-  /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int) dead_code_elimination$after_inlining (after)
+  /// CHECK-START: int Main.$noinline$UpdatePhisCorrectly(int, int) dead_code_elimination$after_inlining (after)
   /// CHECK-NOT:   Phi
-  private static int $noinline$UpdatePhisCorrectly(int num) {
+  private static int $noinline$UpdatePhisCorrectly(int num, int other_num) {
     int phi_value = 0;
     if (num == 0) {
       alwaysThrows();
 
       // This while loop is here so that the `if (num == 0)` will be several blocks instead of
-      // just one.
-      while (num == 0) {
+      // just one. We use `other_num` here because otherwise we propagate the knowledge that `num`
+      // equals zero.
+      while (other_num == 0) {
         // Assign to phi_value so that the loop is not empty.
         phi_value = 2;
       }
diff --git a/test/442-checker-constant-folding/src/Main.java b/test/442-checker-constant-folding/src/Main.java
index 1bdf7b5..168ebbf 100644
--- a/test/442-checker-constant-folding/src/Main.java
+++ b/test/442-checker-constant-folding/src/Main.java
@@ -1577,6 +1577,282 @@
     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());
@@ -1708,6 +1984,51 @@
     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 {
diff --git a/test/449-checker-bce/src/Main.java b/test/449-checker-bce/src/Main.java
index 1144366..fbe3586 100644
--- a/test/449-checker-bce/src/Main.java
+++ b/test/449-checker-bce/src/Main.java
@@ -1125,7 +1125,7 @@
   /// CHECK-DAG: <<Len:i\d+>> ArrayLength [<<Nul>>]         loop:none
   /// CHECK-DAG:              Equal [<<Len>>,<<Val>>]       loop:none
   /// CHECK-DAG: <<Idx:i\d+>> Phi                           loop:<<Loop:B\d+>>
-  /// CHECK-DAG:              BoundsCheck [<<Idx>>,<<Len>>] loop:<<Loop>>
+  /// CHECK-DAG:              BoundsCheck [<<Idx>>,<<Val>>] loop:<<Loop>>
   //
   /// CHECK-START: void Main.lengthAlias4(int[]) BCE (after)
   /// CHECK-NOT:              BoundsCheck
diff --git a/test/485-checker-dce-loop-update/smali/TestCase.smali b/test/485-checker-dce-loop-update/smali/TestCase.smali
index 5290bad..3e7bca9 100644
--- a/test/485-checker-dce-loop-update/smali/TestCase.smali
+++ b/test/485-checker-dce-loop-update/smali/TestCase.smali
@@ -224,7 +224,7 @@
 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
 #
 #                                ### Inner loop ###
-## CHECK-DAG:     <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<XorZ>>]                   loop:<<HeaderZ:B\d+>>
+## CHECK-DAG:     <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<Cst0>>]                   loop:<<HeaderZ:B\d+>>
 ## CHECK-DAG:     <<XorZ>>       Xor [<<PhiZ2>>,<<Cst1>>]                   loop:<<HeaderZ>>
 ## CHECK-DAG:     <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>]                  loop:<<HeaderZ>>
 ## CHECK-DAG:                    If [<<CondZ>>]                             loop:<<HeaderZ>>
@@ -246,8 +246,8 @@
 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
 #
 #                                ### Inner loop ###
-## CHECK-DAG:     <<PhiZ:i\d+>>  Phi [<<ArgZ>>,<<XorZ:i\d+>>]               loop:<<HeaderZ:B\d+>>
-## CHECK-DAG:     <<XorZ>>       Xor [<<PhiZ>>,<<Cst1>>]                    loop:<<HeaderZ>>
+## CHECK-DAG:     <<PhiZ:i\d+>>  Phi [<<ArgZ>>,<<Cst0>>]                    loop:<<HeaderZ:B\d+>>
+## CHECK-DAG:     <<XorZ:i\d+>>  Xor [<<PhiZ>>,<<Cst1>>]                    loop:<<HeaderZ>>
 ## CHECK-DAG:     <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>]                  loop:<<HeaderZ>>
 ## CHECK-DAG:                    If [<<CondZ>>]                             loop:<<HeaderZ>>
 #
diff --git a/test/543-checker-dce-trycatch/smali/TestCase.smali b/test/543-checker-dce-trycatch/smali/TestCase.smali
index 7ad9ba8..15eaabb 100644
--- a/test/543-checker-dce-trycatch/smali/TestCase.smali
+++ b/test/543-checker-dce-trycatch/smali/TestCase.smali
@@ -206,6 +206,7 @@
 ## CHECK-START: int TestCase.testCatchPhiInputs_DefinedInTryBlock(int, int, int, int) dead_code_elimination$after_inlining (before)
 ## CHECK-DAG:     <<Arg0:i\d+>>      ParameterValue
 ## CHECK-DAG:     <<Arg1:i\d+>>      ParameterValue
+## CHECK-DAG:     <<Const0x0:i\d+>>  IntConstant 0
 ## CHECK-DAG:     <<Const0xa:i\d+>>  IntConstant 10
 ## CHECK-DAG:     <<Const0xb:i\d+>>  IntConstant 11
 ## CHECK-DAG:     <<Const0xc:i\d+>>  IntConstant 12
@@ -215,7 +216,7 @@
 ## CHECK-DAG:     <<Const0x10:i\d+>> IntConstant 16
 ## CHECK-DAG:     <<Const0x11:i\d+>> IntConstant 17
 ## CHECK-DAG:     <<Add:i\d+>>       Add [<<Arg0>>,<<Arg1>>]
-## CHECK-DAG:     <<Phi:i\d+>>       Phi [<<Add>>,<<Const0xf>>] reg:3 is_catch_phi:false
+## CHECK-DAG:     <<Phi:i\d+>>       Phi [<<Const0x0>>,<<Const0xf>>] reg:3 is_catch_phi:false
 ## CHECK-DAG:                        Phi [<<Const0xa>>,<<Const0xb>>,<<Const0xd>>] reg:1 is_catch_phi:true
 ## CHECK-DAG:                        Phi [<<Add>>,<<Const0xc>>,<<Const0xe>>] reg:2 is_catch_phi:true
 ## CHECK-DAG:                        Phi [<<Phi>>,<<Const0x10>>,<<Const0x11>>] reg:3 is_catch_phi:true
@@ -248,7 +249,8 @@
     if-eqz v3, :define_phi
     const v3, 0xf
     :define_phi
-    # v3 = Phi [Add, 0xf]          # dead catch phi input, defined in the dead block (HPhi)
+    # v3 = Phi [Add, 0xf]          # dead catch phi input, defined in the dead block (HPhi).
+                                   # Note that the Add has to be equal to 0 since we do `if-eqz v3`
     div-int/2addr p0, v2
 
     :else
diff --git a/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali b/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali
index a30a11a..493567c 100644
--- a/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali
+++ b/test/559-checker-irreducible-loop/smali/IrreducibleLoop.smali
@@ -140,24 +140,23 @@
 #        other_loop_entry
 #        i1 = phi(p0, i0)
 #
-## CHECK-START: int IrreducibleLoop.liveness(int) liveness (after)
+## CHECK-START: int IrreducibleLoop.liveness(int, int) liveness (after)
 ## CHECK-DAG: <<Arg:i\d+>>      ParameterValue liveness:<<ArgLiv:\d+>> ranges:{[<<ArgLiv>>,<<ArgLoopPhiUse:\d+>>)}
 ## CHECK-DAG: <<LoopPhi:i\d+>>  Phi [<<Arg>>,<<PhiInLoop:i\d+>>] liveness:<<ArgLoopPhiUse>> ranges:{[<<ArgLoopPhiUse>>,<<PhiInLoopUse:\d+>>)}
 ## CHECK-DAG: <<PhiInLoop>>     Phi [<<Arg>>,<<LoopPhi>>] liveness:<<PhiInLoopUse>> ranges:{[<<PhiInLoopUse>>,<<BackEdgeLifetimeEnd:\d+>>)}
 ## CHECK:                       Return liveness:<<ReturnLiveness:\d+>>
 ## CHECK-EVAL:    <<ReturnLiveness>> == <<BackEdgeLifetimeEnd>> + 2
-.method public static liveness(I)I
+.method public static liveness(II)I
    .registers 2
-   const/16 v0, 42
-   if-eq p0, v0, :other_loop_entry
+   if-eq p0, p1, :other_loop_entry
    :loop_entry
-   add-int v0, v0, p0
-   if-ne v1, v0, :exit
+   add-int p1, p1, p0
+   if-ne v0, p1, :exit
    :other_loop_entry
-   add-int v0, v0, v0
+   add-int p1, p1, p1
    goto :loop_entry
    :exit
-   return v0
+   return p1
 .end method
 
 # Check that we don't GVN across irreducible loops:
diff --git a/test/559-checker-irreducible-loop/src/Main.java b/test/559-checker-irreducible-loop/src/Main.java
index 97165ec..b22e9b8 100644
--- a/test/559-checker-irreducible-loop/src/Main.java
+++ b/test/559-checker-irreducible-loop/src/Main.java
@@ -38,8 +38,8 @@
     }
 
     {
-      Method m = c.getMethod("liveness", int.class);
-      Object[] arguments = { 42 };
+      Method m = c.getMethod("liveness", int.class, int.class);
+      Object[] arguments = { 42, 42 };
       System.out.println(m.invoke(null, arguments));
     }
 
diff --git a/test/563-checker-fakestring/smali/TestCase.smali b/test/563-checker-fakestring/smali/TestCase.smali
index 4721eca..c6561d5 100644
--- a/test/563-checker-fakestring/smali/TestCase.smali
+++ b/test/563-checker-fakestring/smali/TestCase.smali
@@ -310,7 +310,7 @@
 ## CHECK-NOT:                    NewInstance
 ## CHECK-DAG:   <<Invoke1:l\d+>> InvokeStaticOrDirect method_name:java.lang.String.<init>
 ## CHECK-DAG:   <<Invoke2:l\d+>> InvokeStaticOrDirect method_name:java.lang.String.<init>
-## CHECK-DAG:   <<Phi:l\d+>>     Phi [<<Invoke2>>,<<Invoke1>>]
+## CHECK-DAG:   <<Phi:l\d+>>     Phi [<<Invoke1>>,<<Invoke2>>]
 ## CHECK-DAG:                    Return [<<Phi>>]
 .method public static loopAndStringInitAndPhi([BZ)Ljava/lang/String;
    .registers 4
diff --git a/test/564-checker-inline-loop/src/Main.java b/test/564-checker-inline-loop/src/Main.java
index 6929913..41eca35 100644
--- a/test/564-checker-inline-loop/src/Main.java
+++ b/test/564-checker-inline-loop/src/Main.java
@@ -21,9 +21,6 @@
   /// CHECK-DAG:                      Return [<<Invoke>>]
 
   /// CHECK-START: int Main.inlineLoop() inliner (after)
-  /// CHECK-NOT:                      InvokeStaticOrDirect
-
-  /// CHECK-START: int Main.inlineLoop() inliner (after)
   /// CHECK-DAG:     <<Constant:i\d+>>   IntConstant 42
   /// CHECK-DAG:                         Return [<<Constant>>]
 
@@ -31,31 +28,31 @@
   /// CHECK:                         Goto loop:{{B\d+}}
 
   public static int inlineLoop() {
-    return loopMethod();
+    return $inline$loopMethod();
   }
 
   /// CHECK-START: void Main.inlineWithinLoop() inliner (before)
   /// CHECK:      InvokeStaticOrDirect
 
-  /// CHECK-START: void Main.inlineWithinLoop() inliner (after)
-  /// CHECK-NOT:  InvokeStaticOrDirect
-
   /// CHECK-START: void Main.inlineWithinLoop() licm (after)
   /// CHECK-DAG:  Goto loop:<<OuterLoop:B\d+>> outer_loop:none
   /// CHECK-DAG:  Goto outer_loop:<<OuterLoop>>
 
   public static void inlineWithinLoop() {
     while (doLoop) {
-      loopMethod();
+      $inline$loopMethod();
     }
   }
 
-  public static int loopMethod() {
-    while (doLoop) {}
+  public static int $inline$loopMethod() {
+    // We use `otherDoLoop` here so we don't propagate the knowledge that `doLoop` is true when
+    // inlining from `inlineWithinLoop`.
+    while (otherDoLoop) {}
     return 42;
   }
 
   public static boolean doLoop = false;
+  public static boolean otherDoLoop = false;
 
   public static void main(String[] args) {
     inlineLoop();
diff --git a/test/596-checker-dead-phi/smali/IrreducibleLoop.smali b/test/596-checker-dead-phi/smali/IrreducibleLoop.smali
index bab2ba9..9f822bf 100644
--- a/test/596-checker-dead-phi/smali/IrreducibleLoop.smali
+++ b/test/596-checker-dead-phi/smali/IrreducibleLoop.smali
@@ -20,18 +20,19 @@
 # not adjacent. This revealed a bug in our SSA builder, where a dead loop phi would
 # be replaced by its incoming input during SsaRedundantPhiElimination.
 
-# Check that the outer loop suspend check environment only has the parameter vreg.
-## CHECK-START: int IrreducibleLoop.liveness(int) builder (after)
-## CHECK-DAG:     <<Phi:i\d+>> Phi reg:4 loop:{{B\d+}} irreducible:false
-## CHECK-DAG:     SuspendCheck env:[[_,_,_,_,<<Phi>>]] loop:{{B\d+}} irreducible:false
+# Check that the outer loop suspend check environment only has the two parameter vregs.
+## CHECK-START: int IrreducibleLoop.liveness(int, int) builder (after)
+## CHECK-DAG:     <<Phi1:i\d+>> Phi reg:3 loop:{{B\d+}} irreducible:false
+## CHECK-DAG:     <<Phi2:i\d+>> Phi reg:4 loop:{{B\d+}} irreducible:false
+## CHECK-DAG:     SuspendCheck env:[[_,_,_,<<Phi1>>,<<Phi2>>]] loop:{{B\d+}} irreducible:false
 
 # Check that the linear order has non-adjacent loop blocks.
-## CHECK-START: int IrreducibleLoop.liveness(int) liveness (after)
+## CHECK-START: int IrreducibleLoop.liveness(int, int) liveness (after)
 ## CHECK-DAG:     Mul liveness:<<LPreEntry2:\d+>>
 ## CHECK-DAG:     Add liveness:<<LBackEdge1:\d+>>
 ## CHECK-EVAL:    <<LBackEdge1>> < <<LPreEntry2>>
 
-.method public static liveness(I)I
+.method public static liveness(II)I
     .registers 5
 
     const-string v1, "MyString"
@@ -50,8 +51,9 @@
     if-ne v2, v3, :pre_header2
 
     :pre_entry2
-    # Add a marker on the irreducible loop entry.
-    mul-int/2addr p0, p0
+    # Add a marker on the irreducible loop entry. Here we use p1 because p0 is a
+    # known constant and we eliminate the Mul otherwise.
+    mul-int/2addr p1, p1
     goto :back_edge2
 
     :back_edge2
@@ -61,8 +63,9 @@
     if-eqz p0, :back_edge2
 
     :back_edge1
-    # Add a marker on the outer loop back edge.
-    add-int/2addr p0, p0
+    # Add a marker on the outer loop back edge. Here we use p1 because p0 is a
+    # known constant and we eliminate the Add otherwise.
+    add-int/2addr p1, p1
     # Set a wide register, to have v1 undefined at the back edge.
     const-wide/16 v0, 0x1
     goto :header1
diff --git a/test/596-checker-dead-phi/src/Main.java b/test/596-checker-dead-phi/src/Main.java
index f3a55df..c3384ad 100644
--- a/test/596-checker-dead-phi/src/Main.java
+++ b/test/596-checker-dead-phi/src/Main.java
@@ -22,8 +22,8 @@
     // Note that we don't actually enter the loops in the 'liveness'
     // method, so this is just a verification that that part of the code we
     // generated for that method is correct.
-    Method m = c.getMethod("liveness", int.class);
-    Object[] arguments = { 42 };
+    Method m = c.getMethod("liveness", int.class, int.class);
+    Object[] arguments = {42, 12};
     System.out.println(m.invoke(null, arguments));
   }
 }