ART: Simplify And(TypeConversion<Int64>(x), Const32).

Reorder the And and TypeConversion as
    TypeConversion<Int64>(And(x, Const32))
for 32-bit constant Const32.

For example, java.io.Bits.getLong(byte[] b, int off) yields
better generated code on 32-bit platforms for each of its
eight "b[off + .] & 0xFFL" sequences.

Also remove obsolete "doThrow" code that attempts to prevent
inlining; the $noinline$ tag is now honored by the compiler.

Test: Added tests to 458-checker-instruct-simplification.
Test: m test-art-host-gtest
Test: testrunner.py --host
Change-Id: Ib6e413517daa5206764653ebb6c4687a4c68d02d
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index a85354c..36ff2a9 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1230,6 +1230,37 @@
       RecordSimplification();
       return;
     }
+    if (input_other->IsTypeConversion() &&
+        input_other->GetType() == DataType::Type::kInt64 &&
+        DataType::IsIntegralType(input_other->InputAt(0)->GetType()) &&
+        IsInt<32>(value) &&
+        input_other->HasOnlyOneNonEnvironmentUse()) {
+      // The AND can be reordered before the TypeConversion. Replace
+      //   LongConstant cst, <32-bit-constant-sign-extended-to-64-bits>
+      //   TypeConversion<Int64> tmp, src
+      //   AND dst, tmp, cst
+      // with
+      //   IntConstant cst, <32-bit-constant>
+      //   AND tmp, src, cst
+      //   TypeConversion<Int64> dst, tmp
+      // This helps 32-bit targets and does not hurt 64-bit targets.
+      // This also simplifies detection of other patterns, such as Uint8 loads.
+      HInstruction* new_and_input = input_other->InputAt(0);
+      // Implicit conversion Int64->Int64 would have been removed previously.
+      DCHECK_NE(new_and_input->GetType(), DataType::Type::kInt64);
+      HConstant* new_const = GetGraph()->GetConstant(DataType::Type::kInt32, value);
+      HAnd* new_and =
+          new (GetGraph()->GetArena()) HAnd(DataType::Type::kInt32, new_and_input, new_const);
+      instruction->GetBlock()->InsertInstructionBefore(new_and, instruction);
+      HTypeConversion* new_conversion =
+          new (GetGraph()->GetArena()) HTypeConversion(DataType::Type::kInt64, new_and);
+      instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, new_conversion);
+      input_other->GetBlock()->RemoveInstruction(input_other);
+      RecordSimplification();
+      // Try to process the new And now, do not wait for the next round of simplifications.
+      instruction = new_and;
+      input_other = new_and_input;
+    }
     // Eliminate And from UShr+And if the And-mask contains all the bits that
     // can be non-zero after UShr. Transform Shr+And to UShr if the And-mask
     // precisely clears the shifted-in sign bits.
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index c75a512..411af2a 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -5197,7 +5197,7 @@
 class HTypeConversion FINAL : public HExpression<1> {
  public:
   // Instantiate a type conversion of `input` to `result_type`.
-  HTypeConversion(DataType::Type result_type, HInstruction* input, uint32_t dex_pc)
+  HTypeConversion(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
       : HExpression(result_type, SideEffects::None(), dex_pc) {
     SetRawInputAt(0, input);
     // Invariant: We should never generate a conversion to a Boolean value.
diff --git a/test/458-checker-instruct-simplification/smali/SmaliTests.smali b/test/458-checker-instruct-simplification/smali/SmaliTests.smali
index a8d7d94..d987398 100644
--- a/test/458-checker-instruct-simplification/smali/SmaliTests.smali
+++ b/test/458-checker-instruct-simplification/smali/SmaliTests.smali
@@ -331,70 +331,54 @@
 # Test simplification of the `~~var` pattern.
 # The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
 
-## CHECK-START: long SmaliTests.NotNot1(long) instruction_simplifier (before)
+## CHECK-START: long SmaliTests.$noinline$NotNot1(long) instruction_simplifier (before)
 ## CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
 ## CHECK-DAG:     <<Not1:j\d+>>     Not [<<Arg>>]
 ## CHECK-DAG:     <<Not2:j\d+>>     Not [<<Not1>>]
 ## CHECK-DAG:                       Return [<<Not2>>]
 
-## CHECK-START: long SmaliTests.NotNot1(long) instruction_simplifier (after)
+## CHECK-START: long SmaliTests.$noinline$NotNot1(long) instruction_simplifier (after)
 ## CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
 ## CHECK-DAG:                       Return [<<Arg>>]
 
-## CHECK-START: long SmaliTests.NotNot1(long) instruction_simplifier (after)
+## CHECK-START: long SmaliTests.$noinline$NotNot1(long) instruction_simplifier (after)
 ## CHECK-NOT:                       Not
 
-.method public static NotNot1(J)J
+.method public static $noinline$NotNot1(J)J
     .registers 4
     .param p0, "arg"    # J
 
     .prologue
-    sget-boolean v0, LMain;->doThrow:Z
 
-    # if (doThrow) throw new Error();
-    if-eqz v0, :cond_a
-    new-instance v0, Ljava/lang/Error;
-    invoke-direct {v0}, Ljava/lang/Error;-><init>()V
-    throw v0
-
-  :cond_a
     # return ~~arg
     not-long v0, p0
     not-long v0, v0
     return-wide v0
 .end method
 
-## CHECK-START: int SmaliTests.NotNot2(int) instruction_simplifier (before)
+## CHECK-START: int SmaliTests.$noinline$NotNot2(int) instruction_simplifier (before)
 ## CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
 ## CHECK-DAG:     <<Not1:i\d+>>     Not [<<Arg>>]
 ## CHECK-DAG:     <<Not2:i\d+>>     Not [<<Not1>>]
 ## CHECK-DAG:     <<Add:i\d+>>      Add [<<Not2>>,<<Not1>>]
 ## CHECK-DAG:                       Return [<<Add>>]
 
-## CHECK-START: int SmaliTests.NotNot2(int) instruction_simplifier (after)
+## CHECK-START: int SmaliTests.$noinline$NotNot2(int) instruction_simplifier (after)
 ## CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
 ## CHECK-DAG:     <<Not:i\d+>>      Not [<<Arg>>]
 ## CHECK-DAG:     <<Add:i\d+>>      Add [<<Arg>>,<<Not>>]
 ## CHECK-DAG:                       Return [<<Add>>]
 
-## CHECK-START: int SmaliTests.NotNot2(int) instruction_simplifier (after)
+## CHECK-START: int SmaliTests.$noinline$NotNot2(int) instruction_simplifier (after)
 ## CHECK:                           Not
 ## CHECK-NOT:                       Not
 
-.method public static NotNot2(I)I
+.method public static $noinline$NotNot2(I)I
     .registers 3
     .param p0, "arg"    # I
 
     .prologue
-    sget-boolean v1, LMain;->doThrow:Z
 
-    # if (doThrow) throw new Error();
-    if-eqz v1, :cond_a
-    new-instance v1, Ljava/lang/Error;
-    invoke-direct {v1}, Ljava/lang/Error;-><init>()V
-    throw v1
-
-  :cond_a
     # temp = ~arg; return temp + ~temp;
     not-int v0, p0
     not-int v1, v0
@@ -407,31 +391,31 @@
 # both negations can be removed but we only expect the simplifier to
 # remove the second.
 
-## CHECK-START: boolean SmaliTests.NotNotBool(boolean) instruction_simplifier (before)
+## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) instruction_simplifier (before)
 ## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
 ## CHECK-DAG:     <<Const1:i\d+>>    IntConstant 1
 ## CHECK-DAG:     <<Result:z\d+>>    InvokeStaticOrDirect
 ## CHECK-DAG:     <<NotResult:i\d+>> Xor [<<Result>>,<<Const1>>]
 ## CHECK-DAG:                        Return [<<NotResult>>]
 
-## CHECK-START: boolean SmaliTests.NotNotBool(boolean) instruction_simplifier (after)
+## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) instruction_simplifier (after)
 ## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
 ## CHECK-DAG:     <<Result:z\d+>>    InvokeStaticOrDirect
 ## CHECK-DAG:     <<NotResult:z\d+>> BooleanNot [<<Result>>]
 ## CHECK-DAG:                        Return [<<NotResult>>]
 
-## CHECK-START: boolean SmaliTests.NotNotBool(boolean) instruction_simplifier$after_inlining (before)
+## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) instruction_simplifier$after_inlining (before)
 ## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
 ## CHECK-DAG:     <<NotArg:z\d+>>    BooleanNot [<<Arg>>]
 ## CHECK-DAG:     <<NotNotArg:z\d+>> BooleanNot [<<NotArg>>]
 ## CHECK-DAG:                        Return [<<NotNotArg>>]
 
-## CHECK-START: boolean SmaliTests.NotNotBool(boolean) instruction_simplifier$after_inlining (after)
+## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) instruction_simplifier$after_inlining (after)
 ## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
 ## CHECK-DAG:     <<NotArg:z\d+>>    BooleanNot [<<Arg>>]
 ## CHECK-DAG:                        Return [<<Arg>>]
 
-## CHECK-START: boolean SmaliTests.NotNotBool(boolean) dead_code_elimination$final (after)
+## CHECK-START: boolean SmaliTests.$noinline$NotNotBool(boolean) dead_code_elimination$final (after)
 ## CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
 ## CHECK-DAG:                        Return [<<Arg>>]
 
@@ -447,20 +431,12 @@
 .end method
 
 
-.method public static NotNotBool(Z)Z
+.method public static $noinline$NotNotBool(Z)Z
     .registers 2
     .param p0, "arg"    # Z
 
     .prologue
-    sget-boolean v0, LMain;->doThrow:Z
 
-    # if (doThrow) throw new Error();
-    if-eqz v0, :cond_a
-    new-instance v0, Ljava/lang/Error;
-    invoke-direct {v0}, Ljava/lang/Error;-><init>()V
-    throw v0
-
-  :cond_a
     # return !Negate(arg)
     invoke-static {p0}, LSmaliTests;->NegateValue(Z)Z
     move-result v0
diff --git a/test/458-checker-instruct-simplification/src/Main.java b/test/458-checker-instruct-simplification/src/Main.java
index f36c261..20858f5 100644
--- a/test/458-checker-instruct-simplification/src/Main.java
+++ b/test/458-checker-instruct-simplification/src/Main.java
@@ -18,8 +18,6 @@
 
 public class Main {
 
-  static boolean doThrow = false;
-
   public static void assertBooleanEquals(boolean expected, boolean result) {
     if (expected != result) {
       throw new Error("Expected: " + expected + ", found: " + result);
@@ -74,7 +72,6 @@
   /// CHECK-NOT:                        Add
 
   public static long $noinline$Add0(long arg) {
-    if (doThrow) { throw new Error(); }
     return 0 + arg;
   }
 
@@ -97,7 +94,6 @@
   /// CHECK-DAG:                        Return [<<Add>>]
 
   public static int $noinline$AddAddSubAddConst(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg + 1 + 2 - 3 + 4;
   }
 
@@ -115,7 +111,6 @@
   /// CHECK-NOT:                      And
 
   public static int $noinline$AndAllOnes(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg & -1;
   }
 
@@ -137,7 +132,6 @@
   /// CHECK-NOT:                       And
 
   public static int $noinline$UShr28And15(int arg) {
-    if (doThrow) { throw new Error(); }
     return (arg >>> 28) & 15;
   }
 
@@ -159,7 +153,6 @@
   /// CHECK-NOT:                       And
 
   public static long $noinline$UShr60And15(long arg) {
-    if (doThrow) { throw new Error(); }
     return (arg >>> 60) & 15;
   }
 
@@ -180,7 +173,6 @@
   /// CHECK-DAG:                       Return [<<And>>]
 
   public static int $noinline$UShr28And7(int arg) {
-    if (doThrow) { throw new Error(); }
     return (arg >>> 28) & 7;
   }
 
@@ -201,7 +193,6 @@
   /// CHECK-DAG:                       Return [<<And>>]
 
   public static long $noinline$UShr60And7(long arg) {
-    if (doThrow) { throw new Error(); }
     return (arg >>> 60) & 7;
   }
 
@@ -224,7 +215,6 @@
   /// CHECK-NOT:                       And
 
   public static int $noinline$Shr24And255(int arg) {
-    if (doThrow) { throw new Error(); }
     return (arg >> 24) & 255;
   }
 
@@ -247,7 +237,6 @@
   /// CHECK-NOT:                       And
 
   public static long $noinline$Shr56And255(long arg) {
-    if (doThrow) { throw new Error(); }
     return (arg >> 56) & 255;
   }
 
@@ -268,7 +257,6 @@
   /// CHECK-DAG:                       Return [<<And>>]
 
   public static int $noinline$Shr24And127(int arg) {
-    if (doThrow) { throw new Error(); }
     return (arg >> 24) & 127;
   }
 
@@ -289,7 +277,6 @@
   /// CHECK-DAG:                       Return [<<And>>]
 
   public static long $noinline$Shr56And127(long arg) {
-    if (doThrow) { throw new Error(); }
     return (arg >> 56) & 127;
   }
 
@@ -307,7 +294,6 @@
   /// CHECK-NOT:                      Div
 
   public static long $noinline$Div1(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg / 1;
   }
 
@@ -326,7 +312,6 @@
   /// CHECK-NOT:                       Div
 
   public static int $noinline$DivN1(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg / -1;
   }
 
@@ -344,7 +329,6 @@
   /// CHECK-NOT:                       Mul
 
   public static long $noinline$Mul1(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg * 1;
   }
 
@@ -363,7 +347,6 @@
   /// CHECK-NOT:                       Mul
 
   public static int $noinline$MulN1(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg * -1;
   }
 
@@ -383,7 +366,6 @@
   /// CHECK-NOT:                        Mul
 
   public static long $noinline$MulPowerOfTwo128(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg * 128;
   }
 
@@ -404,7 +386,6 @@
   /// CHECK-DAG:                         Return [<<Mul>>]
 
   public static long $noinline$MulMulMulConst(long arg) {
-    if (doThrow) { throw new Error(); }
     return 10 * arg * 11 * 12;
   }
 
@@ -422,7 +403,6 @@
   /// CHECK-NOT:                       Or
 
   public static int $noinline$Or0(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg | 0;
   }
 
@@ -439,7 +419,6 @@
   /// CHECK-NOT:                        Or
 
   public static long $noinline$OrSame(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg | arg;
   }
 
@@ -457,7 +436,6 @@
   /// CHECK-NOT:                       Shl
 
   public static int $noinline$Shl0(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg << 0;
   }
 
@@ -475,7 +453,6 @@
   /// CHECK-NOT:                       Shr
 
   public static long $noinline$Shr0(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg >> 0;
   }
 
@@ -493,7 +470,6 @@
   /// CHECK-NOT:                       Shr
 
   public static long $noinline$Shr64(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg >> 64;
   }
 
@@ -511,7 +487,6 @@
   /// CHECK-NOT:                       Sub
 
   public static long $noinline$Sub0(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg - 0;
   }
 
@@ -530,7 +505,6 @@
   /// CHECK-NOT:                       Sub
 
   public static int $noinline$SubAliasNeg(int arg) {
-    if (doThrow) { throw new Error(); }
     return 0 - arg;
   }
 
@@ -549,7 +523,6 @@
   /// CHECK-DAG:                        Return [<<Sub>>]
 
   public static int $noinline$SubAddConst1(int arg) {
-    if (doThrow) { throw new Error(); }
     return 5 - arg + 6;
   }
 
@@ -568,7 +541,6 @@
   /// CHECK-DAG:                        Return [<<Sub>>]
 
   public static int $noinline$SubAddConst2(int arg) {
-    if (doThrow) { throw new Error(); }
     return 14 - (arg + 13);
   }
 
@@ -587,7 +559,6 @@
   /// CHECK-DAG:                        Return [<<Add>>]
 
   public static long $noinline$SubSubConst(long arg) {
-    if (doThrow) { throw new Error(); }
     return 17 - (18 - arg);
   }
 
@@ -605,7 +576,6 @@
   /// CHECK-NOT:                       UShr
 
   public static long $noinline$UShr0(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg >>> 0;
   }
 
@@ -623,7 +593,6 @@
   /// CHECK-NOT:                       Xor
 
   public static int $noinline$Xor0(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg ^ 0;
   }
 
@@ -642,7 +611,6 @@
   /// CHECK-NOT:                       Xor
 
   public static int $noinline$XorAllOnes(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg ^ -1;
   }
 
@@ -670,7 +638,6 @@
   /// CHECK-DAG:                       Return [<<Neg>>]
 
   public static int $noinline$AddNegs1(int arg1, int arg2) {
-    if (doThrow) { throw new Error(); }
     return -arg1 + -arg2;
   }
 
@@ -716,7 +683,6 @@
   /// CHECK-DAG:                       Return [<<Or>>]
 
   public static int $noinline$AddNegs2(int arg1, int arg2) {
-    if (doThrow) { throw new Error(); }
     int temp1 = -arg1;
     int temp2 = -arg2;
     return (temp1 + temp2) | (temp1 + temp2);
@@ -756,7 +722,6 @@
   /// CHECK:                           Goto
 
   public static long $noinline$AddNegs3(long arg1, long arg2) {
-    if (doThrow) { throw new Error(); }
     long res = 0;
     long n_arg1 = -arg1;
     long n_arg2 = -arg2;
@@ -790,7 +755,6 @@
   /// CHECK-NOT:                       Add
 
   public static long $noinline$AddNeg1(long arg1, long arg2) {
-    if (doThrow) { throw new Error(); }
     return -arg1 + arg2;
   }
 
@@ -825,7 +789,6 @@
   /// CHECK-NOT:                       Sub
 
   public static long $noinline$AddNeg2(long arg1, long arg2) {
-    if (doThrow) { throw new Error(); }
     long temp = -arg2;
     return (arg1 + temp) | (arg1 + temp);
   }
@@ -849,7 +812,6 @@
   /// CHECK-NOT:                       Neg
 
   public static long $noinline$NegNeg1(long arg) {
-    if (doThrow) { throw new Error(); }
     return -(-arg);
   }
 
@@ -883,7 +845,6 @@
   /// CHECK:                           Return [<<Const0>>]
 
   public static int $noinline$NegNeg2(int arg) {
-    if (doThrow) { throw new Error(); }
     int temp = -arg;
     return temp + -temp;
   }
@@ -911,7 +872,6 @@
   /// CHECK-NOT:                       Sub
 
   public static long $noinline$NegNeg3(long arg) {
-    if (doThrow) { throw new Error(); }
     return 0 - -arg;
   }
 
@@ -938,7 +898,6 @@
   /// CHECK-NOT:                       Neg
 
   public static int $noinline$NegSub1(int arg1, int arg2) {
-    if (doThrow) { throw new Error(); }
     return -(arg1 - arg2);
   }
 
@@ -971,7 +930,6 @@
   /// CHECK-DAG:                       Return [<<Or>>]
 
   public static int $noinline$NegSub2(int arg1, int arg2) {
-    if (doThrow) { throw new Error(); }
     int temp = arg1 - arg2;
     return -temp | -temp;
   }
@@ -996,7 +954,6 @@
   /// CHECK-NOT:                       Xor
 
   public static long $noinline$NotNot1(long arg) {
-    if (doThrow) { throw new Error(); }
     return ~~arg;
   }
 
@@ -1022,7 +979,6 @@
   /// CHECK-NOT:                       Xor
 
   public static int $noinline$NotNot2(int arg) {
-    if (doThrow) { throw new Error(); }
     int temp = ~arg;
     return temp + ~temp;
   }
@@ -1050,7 +1006,6 @@
   /// CHECK-NOT:                       Sub
 
   public static int $noinline$SubNeg1(int arg1, int arg2) {
-    if (doThrow) { throw new Error(); }
     return -arg1 - arg2;
   }
 
@@ -1086,7 +1041,6 @@
   /// CHECK-NOT:                       Add
 
   public static int $noinline$SubNeg2(int arg1, int arg2) {
-    if (doThrow) { throw new Error(); }
     int temp = -arg1;
     return (temp - arg2) | (temp - arg2);
   }
@@ -1122,7 +1076,6 @@
   /// CHECK:                           Goto
 
   public static long $noinline$SubNeg3(long arg1, long arg2) {
-    if (doThrow) { throw new Error(); }
     long res = 0;
     long temp = -arg1;
     for (long i = 0; i < 1; i++) {
@@ -1146,7 +1099,6 @@
   /// CHECK-DAG:                       Return [<<True>>]
 
   public static boolean $noinline$EqualBoolVsIntConst(boolean arg) {
-    if (doThrow) { throw new Error(); }
     // Make calls that will be inlined to make sure the instruction simplifier
     // sees the simplification (dead code elimination will also try to simplify it).
     return (arg ? $inline$ReturnArg(0) : $inline$ReturnArg(1)) != 2;
@@ -1171,7 +1123,6 @@
   /// CHECK-DAG:                       Return [<<False>>]
 
   public static boolean $noinline$NotEqualBoolVsIntConst(boolean arg) {
-    if (doThrow) { throw new Error(); }
     // Make calls that will be inlined to make sure the instruction simplifier
     // sees the simplification (dead code elimination will also try to simplify it).
     return (arg ? $inline$ReturnArg(0) : $inline$ReturnArg(1)) == 2;
@@ -1232,7 +1183,6 @@
   }
 
   public static boolean $noinline$NotNotBool(boolean arg) {
-    if (doThrow) { throw new Error(); }
     return !(NegateValue(arg));
   }
 
@@ -1252,7 +1202,6 @@
   /// CHECK-NOT:                        Div
 
   public static float $noinline$Div2(float arg) {
-    if (doThrow) { throw new Error(); }
     return arg / 2.0f;
   }
 
@@ -1271,7 +1220,6 @@
   /// CHECK-START: double Main.$noinline$Div2(double) instruction_simplifier (after)
   /// CHECK-NOT:                        Div
   public static double $noinline$Div2(double arg) {
-    if (doThrow) { throw new Error(); }
     return arg / 2.0;
   }
 
@@ -1291,7 +1239,6 @@
   /// CHECK-NOT:                        Div
 
   public static float $noinline$DivMP25(float arg) {
-    if (doThrow) { throw new Error(); }
     return arg / -0.25f;
   }
 
@@ -1310,7 +1257,6 @@
   /// CHECK-START: double Main.$noinline$DivMP25(double) instruction_simplifier (after)
   /// CHECK-NOT:                        Div
   public static double $noinline$DivMP25(double arg) {
-    if (doThrow) { throw new Error(); }
     return arg / -0.25f;
   }
 
@@ -1330,7 +1276,6 @@
   /// CHECK-NEXT:                       Add [<<Arg>>,<<Shift>>]
 
   public static int $noinline$mulPow2Plus1(int arg) {
-    if (doThrow) { throw new Error(); }
     return arg * 9;
   }
 
@@ -1350,7 +1295,6 @@
   /// CHECK-NEXT:                       Sub [<<Shift>>,<<Arg>>]
 
   public static long $noinline$mulPow2Minus1(long arg) {
-    if (doThrow) { throw new Error(); }
     return arg * 31;
   }
 
@@ -1358,14 +1302,12 @@
   /// CHECK-DAG:      <<Const1:i\d+>>   IntConstant 1
   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
-  /// CHECK-DAG:      <<doThrow:z\d+>>  StaticFieldGet
   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
   /// CHECK-DAG:      <<NE:z\d+>>       NotEqual [<<Field>>,<<Const1>>]
   /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Const13>>,<<Const54>>,<<NE>>]
   /// CHECK-DAG:                        Return [<<Select>>]
 
   /// CHECK-START: int Main.$noinline$booleanFieldNotEqualOne() instruction_simplifier$after_inlining (after)
-  /// CHECK-DAG:      <<doThrow:z\d+>>  StaticFieldGet
   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
@@ -1373,7 +1315,6 @@
   /// CHECK-DAG:                        Return [<<Select>>]
 
   public static int $noinline$booleanFieldNotEqualOne() {
-    if (doThrow) { throw new Error(); }
     return (booleanField == $inline$true()) ? 13 : 54;
   }
 
@@ -1381,14 +1322,12 @@
   /// CHECK-DAG:      <<Const0:i\d+>>   IntConstant 0
   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
-  /// CHECK-DAG:      <<doThrow:z\d+>>  StaticFieldGet
   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
   /// CHECK-DAG:      <<NE:z\d+>>       Equal [<<Field>>,<<Const0>>]
   /// CHECK-DAG:      <<Select:i\d+>>   Select [<<Const13>>,<<Const54>>,<<NE>>]
   /// CHECK-DAG:                        Return [<<Select>>]
 
   /// CHECK-START: int Main.$noinline$booleanFieldEqualZero() instruction_simplifier$after_inlining (after)
-  /// CHECK-DAG:      <<doThrow:z\d+>>  StaticFieldGet
   /// CHECK-DAG:      <<Field:z\d+>>    StaticFieldGet
   /// CHECK-DAG:      <<Const13:i\d+>>  IntConstant 13
   /// CHECK-DAG:      <<Const54:i\d+>>  IntConstant 54
@@ -1396,7 +1335,6 @@
   /// CHECK-DAG:                        Return [<<Select>>]
 
   public static int $noinline$booleanFieldEqualZero() {
-    if (doThrow) { throw new Error(); }
     return (booleanField != $inline$false()) ? 13 : 54;
   }
 
@@ -1425,7 +1363,6 @@
   // LessThanOrEqual instructions.
 
   public static int $noinline$intConditionNotEqualOne(int i) {
-    if (doThrow) { throw new Error(); }
     return ((i > 42) == $inline$true()) ? 13 : 54;
   }
 
@@ -1454,7 +1391,6 @@
   // LessThanOrEqual instructions.
 
   public static int $noinline$intConditionEqualZero(int i) {
-    if (doThrow) { throw new Error(); }
     return ((i > 42) != $inline$false()) ? 13 : 54;
   }
 
@@ -1473,7 +1409,6 @@
   /// CHECK-DAG:                        Return [<<Select>>]
 
   public static int $noinline$floatConditionNotEqualOne(float f) {
-    if (doThrow) { throw new Error(); }
     return ((f > 42.0f) == true) ? 13 : 54;
   }
 
@@ -1490,7 +1425,6 @@
   /// CHECK-DAG:                        Return [<<Select>>]
 
   public static int $noinline$doubleConditionEqualZero(double d) {
-    if (doThrow) { throw new Error(); }
     return ((d > 42.0) != false) ? 13 : 54;
   }
 
@@ -1508,7 +1442,6 @@
   /// CHECK-NOT:                        TypeConversion
 
   public static int $noinline$intToDoubleToInt(int value) {
-    if (doThrow) { throw new Error(); }
     // Lossless conversion followed by a conversion back.
     return (int) (double) value;
   }
@@ -1527,7 +1460,6 @@
   /// CHECK-NOT:                        TypeConversion
 
   public static String $noinline$intToDoubleToIntPrint(int value) {
-    if (doThrow) { throw new Error(); }
     // Lossless conversion followed by a conversion back
     // with another use of the intermediate result.
     double d = (double) value;
@@ -1549,7 +1481,6 @@
   /// CHECK-NOT:                        TypeConversion
 
   public static int $noinline$byteToDoubleToInt(byte value) {
-    if (doThrow) { throw new Error(); }
     // Lossless conversion followed by another conversion, use implicit conversion.
     return (int) (double) value;
   }
@@ -1570,7 +1501,6 @@
   /// CHECK-NOT:                        TypeConversion
 
   public static int $noinline$floatToDoubleToInt(float value) {
-    if (doThrow) { throw new Error(); }
     // Lossless conversion followed by another conversion.
     return (int) (double) value;
   }
@@ -1586,7 +1516,6 @@
   /// CHECK-DAG:      {{i\d+}}          TypeConversion [<<Double>>]
 
   public static String $noinline$floatToDoubleToIntPrint(float value) {
-    if (doThrow) { throw new Error(); }
     // Lossless conversion followed by another conversion with
     // an extra use of the intermediate result.
     double d = (double) value;
@@ -1609,7 +1538,6 @@
   /// CHECK-NOT:                        TypeConversion
 
   public static short $noinline$byteToDoubleToShort(byte value) {
-    if (doThrow) { throw new Error(); }
     // Originally, this is byte->double->int->short. The first conversion is lossless,
     // so we merge this with the second one to byte->int which we omit as it's an implicit
     // conversion. Then we eliminate the resulting byte->short as an implicit conversion.
@@ -1633,7 +1561,6 @@
   /// CHECK-NOT:                        TypeConversion
 
   public static short $noinline$charToDoubleToShort(char value) {
-    if (doThrow) { throw new Error(); }
     // Originally, this is char->double->int->short. The first conversion is lossless,
     // so we merge this with the second one to char->int which we omit as it's an implicit
     // conversion. Then we are left with the resulting char->short conversion.
@@ -1653,7 +1580,6 @@
   /// CHECK-DAG:                        Return [<<Short>>]
 
   public static short $noinline$floatToIntToShort(float value) {
-    if (doThrow) { throw new Error(); }
     // Lossy FP to integral conversion followed by another conversion: no simplification.
     return (short) value;
   }
@@ -1671,7 +1597,6 @@
   /// CHECK-DAG:                        Return [<<Int>>]
 
   public static int $noinline$intToFloatToInt(int value) {
-    if (doThrow) { throw new Error(); }
     // Lossy integral to FP conversion followed another conversion: no simplification.
     return (int) (float) value;
   }
@@ -1689,7 +1614,6 @@
   /// CHECK-DAG:                        Return [<<Double>>]
 
   public static double $noinline$longToIntToDouble(long value) {
-    if (doThrow) { throw new Error(); }
     // Lossy long-to-int conversion followed an integral to FP conversion: no simplification.
     return (double) (int) value;
   }
@@ -1707,7 +1631,6 @@
   /// CHECK-DAG:                        Return [<<Long>>]
 
   public static long $noinline$longToIntToLong(long value) {
-    if (doThrow) { throw new Error(); }
     // Lossy long-to-int conversion followed an int-to-long conversion: no simplification.
     return (long) (int) value;
   }
@@ -1723,7 +1646,6 @@
   /// CHECK-DAG:                        Return [<<Arg>>]
 
   public static short $noinline$shortToCharToShort(short value) {
-    if (doThrow) { throw new Error(); }
     // Integral conversion followed by non-widening integral conversion to original type.
     return (short) (char) value;
   }
@@ -1739,7 +1661,6 @@
   /// CHECK-DAG:                        Return [<<Arg>>]
 
   public static int $noinline$shortToLongToInt(short value) {
-    if (doThrow) { throw new Error(); }
     // Integral conversion followed by non-widening integral conversion, use implicit conversion.
     return (int) (long) value;
   }
@@ -1756,7 +1677,6 @@
   /// CHECK-DAG:                        Return [<<Byte>>]
 
   public static byte $noinline$shortToCharToByte(short value) {
-    if (doThrow) { throw new Error(); }
     // Integral conversion followed by non-widening integral conversion losing bits
     // from the original type. Simplify to use only one conversion.
     return (byte) (char) value;
@@ -1773,7 +1693,6 @@
   /// CHECK-DAG:      {{b\d+}}          TypeConversion [<<Char>>]
 
   public static String $noinline$shortToCharToBytePrint(short value) {
-    if (doThrow) { throw new Error(); }
     // Integral conversion followed by non-widening integral conversion losing bits
     // from the original type with an extra use of the intermediate result.
     char c = (char) value;
@@ -1781,6 +1700,62 @@
     return "c=" + ((int) c) + ", b=" + ((int) b);  // implicit conversions.
   }
 
+  /// CHECK-START: long Main.$noinline$intAndSmallLongConstant(int) instruction_simplifier (before)
+  /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
+  /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant -12345678
+  /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Arg>>]
+  /// CHECK-DAG:      <<And:j\d+>>      And [<<Long>>,<<Mask>>]
+  /// CHECK-DAG:                        Return [<<And>>]
+
+  /// CHECK-START: long Main.$noinline$intAndSmallLongConstant(int) instruction_simplifier (after)
+  /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
+  /// CHECK-DAG:      <<Mask:i\d+>>     IntConstant -12345678
+  /// CHECK-DAG:      <<And:i\d+>>      And [<<Arg>>,<<Mask>>]
+  /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<And>>]
+  /// CHECK-DAG:                        Return [<<Long>>]
+
+  public static long $noinline$intAndSmallLongConstant(int value) {
+    return value & -12345678L;  // Shall be simplified (constant is 32-bit).
+  }
+
+  /// CHECK-START: long Main.$noinline$intAndLargeLongConstant(int) instruction_simplifier (before)
+  /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
+  /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant 9876543210
+  /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Arg>>]
+  /// CHECK-DAG:      <<And:j\d+>>      And [<<Long>>,<<Mask>>]
+  /// CHECK-DAG:                        Return [<<And>>]
+
+  /// CHECK-START: long Main.$noinline$intAndLargeLongConstant(int) instruction_simplifier (after)
+  /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
+  /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant 9876543210
+  /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Arg>>]
+  /// CHECK-DAG:      <<And:j\d+>>      And [<<Long>>,<<Mask>>]
+  /// CHECK-DAG:                        Return [<<And>>]
+
+  public static long $noinline$intAndLargeLongConstant(int value) {
+    return value & 9876543210L;  // Shall not be simplified (constant is not 32-bit).
+  }
+
+  /// CHECK-START: long Main.$noinline$intShr28And15L(int) instruction_simplifier (before)
+  /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
+  /// CHECK-DAG:      <<Shift:i\d+>>    IntConstant 28
+  /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant 15
+  /// CHECK-DAG:      <<Shifted:i\d+>>  Shr [<<Arg>>,<<Shift>>]
+  /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Shifted>>]
+  /// CHECK-DAG:      <<And:j\d+>>      And [<<Long>>,<<Mask>>]
+  /// CHECK-DAG:                        Return [<<And>>]
+
+  /// CHECK-START: long Main.$noinline$intShr28And15L(int) instruction_simplifier (after)
+  /// CHECK-DAG:      <<Arg:i\d+>>      ParameterValue
+  /// CHECK-DAG:      <<Shift:i\d+>>    IntConstant 28
+  /// CHECK-DAG:      <<Shifted:i\d+>>  UShr [<<Arg>>,<<Shift>>]
+  /// CHECK-DAG:      <<Long:j\d+>>     TypeConversion [<<Shifted>>]
+  /// CHECK-DAG:                        Return [<<Long>>]
+
+  public static long $noinline$intShr28And15L(int value) {
+    return (value >> 28) & 15L;
+  }
+
   /// CHECK-START: byte Main.$noinline$longAnd0xffToByte(long) instruction_simplifier (before)
   /// CHECK-DAG:      <<Arg:j\d+>>      ParameterValue
   /// CHECK-DAG:      <<Mask:j\d+>>     LongConstant 255
@@ -1798,7 +1773,6 @@
   /// CHECK-NOT:                        And
 
   public static byte $noinline$longAnd0xffToByte(long value) {
-    if (doThrow) { throw new Error(); }
     return (byte) (value & 0xff);
   }
 
@@ -1818,7 +1792,6 @@
   /// CHECK-NOT:                        And
 
   public static char $noinline$intAnd0x1ffffToChar(int value) {
-    if (doThrow) { throw new Error(); }
     // Keeping all significant bits and one more.
     return (char) (value & 0x1ffff);
   }
@@ -1838,7 +1811,6 @@
   /// CHECK-DAG:                        Return [<<Short>>]
 
   public static short $noinline$intAnd0x17fffToShort(int value) {
-    if (doThrow) { throw new Error(); }
     // No simplification: clearing a significant bit.
     return (short) (value & 0x17fff);
   }
@@ -1857,7 +1829,6 @@
   /// CHECK-DAG:                        Return [<<Double>>]
 
   public static double $noinline$shortAnd0xffffToShortToDouble(short value) {
-    if (doThrow) { throw new Error(); }
     short same = (short) (value & 0xffff);
     return (double) same;
   }
@@ -1873,7 +1844,6 @@
   /// CHECK-DAG:      <<GE:z\d+>>       GreaterThanOrEqual [<<Arg>>,<<Const42>>]
 
   public static int $noinline$intReverseCondition(int i) {
-    if (doThrow) { throw new Error(); }
     return (42 > i) ? 13 : 54;
   }
 
@@ -1888,12 +1858,10 @@
   /// CHECK-DAG:      <<EQ:z\d+>>       Equal [<<Result>>,<<Const42>>]
 
   public static int $noinline$intReverseConditionNaN(int i) {
-    if (doThrow) { throw new Error(); }
     return (42 != Math.sqrt(i)) ? 13 : 54;
   }
 
   public static int $noinline$runSmaliTest(String name, boolean input) {
-    if (doThrow) { throw new Error(); }
     try {
       Class<?> c = Class.forName("SmaliTests");
       Method m = c.getMethod(name, boolean.class);
@@ -1904,7 +1872,6 @@
   }
 
   public static boolean $noinline$runSmaliTestBoolean(String name, boolean input) {
-    if (doThrow) { throw new Error(); }
     try {
       Class<?> c = Class.forName("SmaliTests");
       Method m = c.getMethod(name, boolean.class);
@@ -1915,7 +1882,6 @@
   }
 
   public static int $noinline$runSmaliTestInt(String name, int arg) {
-    if (doThrow) { throw new Error(); }
     try {
       Class<?> c = Class.forName("SmaliTests");
       Method m = c.getMethod(name, int.class);
@@ -1926,7 +1892,6 @@
   }
 
   public static long $noinline$runSmaliTestLong(String name, long arg) {
-    if (doThrow) { throw new Error(); }
     try {
       Class<?> c = Class.forName("SmaliTests");
       Method m = c.getMethod(name, long.class);
@@ -1951,7 +1916,6 @@
   /// CHECK-DAG:                        Return [<<Shl>>]
 
   public static int $noinline$intUnnecessaryShiftMasking(int value, int shift) {
-    if (doThrow) { throw new Error(); }
     return value << (shift & 31);
   }
 
@@ -1970,7 +1934,6 @@
   /// CHECK-DAG:                        Return [<<Shr>>]
 
   public static long $noinline$longUnnecessaryShiftMasking(long value, int shift) {
-    if (doThrow) { throw new Error(); }
     return value >> (shift & 63);
   }
 
@@ -1989,7 +1952,6 @@
   /// CHECK-DAG:                        Return [<<UShr>>]
 
   public static int $noinline$intUnnecessaryWiderShiftMasking(int value, int shift) {
-    if (doThrow) { throw new Error(); }
     return value >>> (shift & 0xff);
   }
 
@@ -2010,7 +1972,6 @@
   /// CHECK-DAG:                        Return [<<Shl>>]
 
   public static long $noinline$longSmallerShiftMasking(long value, int shift) {
-    if (doThrow) { throw new Error(); }
     return value << (shift & 3);
   }
 
@@ -2033,7 +1994,6 @@
   /// CHECK-DAG:                        Return [<<Add>>]
 
   public static int $noinline$otherUseOfUnnecessaryShiftMasking(int value, int shift) {
-    if (doThrow) { throw new Error(); }
     int temp = shift & 31;
     return (value >> temp) + temp;
   }
@@ -2066,7 +2026,6 @@
   /// CHECK-DAG:                        Shr [<<Value>>,<<Shift>>]
 
   public static int $noinline$intUnnecessaryShiftModifications(int value, int shift) {
-    if (doThrow) { throw new Error(); }
     int c128 = 128;
     return (value << (shift | 32)) +
            (value >> (shift ^ 64)) +
@@ -2108,7 +2067,6 @@
   /// CHECK-DAG:                        Shl [<<Value>>,<<Sub>>]
 
   public static int $noinline$intNecessaryShiftModifications(int value, int shift) {
-    if (doThrow) { throw new Error(); }
     int c129 = 129;
     return (value << (shift | 33)) +
            (value >> (shift ^ 65)) +
@@ -2130,7 +2088,6 @@
   /// CHECK-DAG:                        Return [<<Y>>]
 
   public static int $noinline$intAddSubSimplifyArg1(int x, int y) {
-    if (doThrow) { throw new Error(); }
     int sum = x + y;
     return sum - x;
   }
@@ -2149,7 +2106,6 @@
   /// CHECK-DAG:                        Return [<<X>>]
 
   public static int $noinline$intAddSubSimplifyArg2(int x, int y) {
-    if (doThrow) { throw new Error(); }
     int sum = x + y;
     return sum - y;
   }
@@ -2168,7 +2124,6 @@
   /// CHECK-DAG:                        Return [<<X>>]
 
   public static int $noinline$intSubAddSimplifyLeft(int x, int y) {
-    if (doThrow) { throw new Error(); }
     int sub = x - y;
     return sub + y;
   }
@@ -2187,7 +2142,6 @@
   /// CHECK-DAG:                        Return [<<X>>]
 
   public static int $noinline$intSubAddSimplifyRight(int x, int y) {
-    if (doThrow) { throw new Error(); }
     int sub = x - y;
     return y + sub;
   }
@@ -2207,7 +2161,6 @@
   /// CHECK-DAG:                        Return [<<Res>>]
 
   public static float $noinline$floatAddSubSimplifyArg1(float x, float y) {
-    if (doThrow) { throw new Error(); }
     float sum = x + y;
     return sum - x;
   }
@@ -2227,7 +2180,6 @@
   /// CHECK-DAG:                        Return [<<Res>>]
 
   public static float $noinline$floatAddSubSimplifyArg2(float x, float y) {
-    if (doThrow) { throw new Error(); }
     float sum = x + y;
     return sum - y;
   }
@@ -2247,7 +2199,6 @@
   /// CHECK-DAG:                        Return [<<Res>>]
 
   public static float $noinline$floatSubAddSimplifyLeft(float x, float y) {
-    if (doThrow) { throw new Error(); }
     float sub = x - y;
     return sub + y;
   }
@@ -2267,7 +2218,6 @@
   /// CHECK-DAG:                        Return [<<Res>>]
 
   public static float $noinline$floatSubAddSimplifyRight(float x, float y) {
-    if (doThrow) { throw new Error(); }
     float sub = x - y;
     return y + sub;
   }
@@ -2309,9 +2259,9 @@
     assertIntEquals(1, $noinline$NegSub1(arg, arg + 1));
     assertIntEquals(1, $noinline$NegSub2(arg, arg + 1));
     assertLongEquals(arg, $noinline$NotNot1(arg));
-    assertLongEquals(arg, $noinline$runSmaliTestLong("NotNot1", arg));
+    assertLongEquals(arg, $noinline$runSmaliTestLong("$noinline$NotNot1", arg));
     assertIntEquals(-1, $noinline$NotNot2(arg));
-    assertIntEquals(-1, $noinline$runSmaliTestInt("NotNot2", arg));
+    assertIntEquals(-1, $noinline$runSmaliTestInt("$noinline$NotNot2", arg));
     assertIntEquals(-(arg + arg + 1), $noinline$SubNeg1(arg, arg + 1));
     assertIntEquals(-(arg + arg + 1), $noinline$SubNeg2(arg, arg + 1));
     assertLongEquals(-(2 * arg + 1), $noinline$SubNeg3(arg, arg + 1));
@@ -2320,9 +2270,9 @@
     assertBooleanEquals(false, $noinline$NotEqualBoolVsIntConst(false));
     assertBooleanEquals(false, $noinline$NotEqualBoolVsIntConst(false));
     assertBooleanEquals(true, $noinline$NotNotBool(true));
-    assertBooleanEquals(true, $noinline$runSmaliTestBoolean("NotNotBool", true));
+    assertBooleanEquals(true, $noinline$runSmaliTestBoolean("$noinline$NotNotBool", true));
     assertBooleanEquals(false, $noinline$NotNotBool(false));
-    assertBooleanEquals(false, $noinline$runSmaliTestBoolean("NotNotBool", false));
+    assertBooleanEquals(false, $noinline$runSmaliTestBoolean("$noinline$NotNotBool", false));
     assertFloatEquals(50.0f, $noinline$Div2(100.0f));
     assertDoubleEquals(75.0, $noinline$Div2(150.0));
     assertFloatEquals(-400.0f, $noinline$DivMP25(100.0f));
@@ -2401,6 +2351,12 @@
     assertStringEquals("c=1023, b=-1", $noinline$shortToCharToBytePrint((short) 1023));
     assertStringEquals("c=65535, b=-1", $noinline$shortToCharToBytePrint((short) -1));
 
+    assertLongEquals(0x55411410L, $noinline$intAndSmallLongConstant(0x55555555));
+    assertLongEquals(0xffffffffaa028aa2L, $noinline$intAndSmallLongConstant(0xaaaaaaaa));
+    assertLongEquals(0x44101440L, $noinline$intAndLargeLongConstant(0x55555555));
+    assertLongEquals(0x208a002aaL, $noinline$intAndLargeLongConstant(0xaaaaaaaa));
+    assertLongEquals(7L, $noinline$intShr28And15L(0x76543210));
+
     assertIntEquals(0x21, $noinline$longAnd0xffToByte(0x1234432112344321L));
     assertIntEquals(0, $noinline$longAnd0xffToByte(Long.MIN_VALUE));
     assertIntEquals(-1, $noinline$longAnd0xffToByte(Long.MAX_VALUE));