test: Modify 458-checker-instruct-simplification for javac/dx

Previously 3 of the methods were failing checker with javac/dx.
Move their old bytecode to a smali file to retain testing of those
optimizations.

Rewrite the checker tests in Main.java to use the javac/dx-generated
bytecode.

Test: art/test/run-test --64 --host --optimizing --build-with-javac-dx 458-checker-instruct-simplification
Bug: 62950048
Bug: 36902714
Change-Id: Ib14ba0c95bc24378a8e9e3155081a17daa3d4d77
diff --git a/test/458-checker-instruct-simplification/build b/test/458-checker-instruct-simplification/build
new file mode 100755
index 0000000..49292c9
--- /dev/null
+++ b/test/458-checker-instruct-simplification/build
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# Copyright 2017 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.
+
+# This checker test is incompatible with jack bytecode output,
+# so force it to use javac/dx.
+export USE_JACK=false
+# Also disable desugar because it is missing in jack platform builds.
+export DESUGAR=false
+
+./default-build "$@"
diff --git a/test/458-checker-instruct-simplification/smali/SmaliTests.smali b/test/458-checker-instruct-simplification/smali/SmaliTests.smali
index 6845961..a8d7d94 100644
--- a/test/458-checker-instruct-simplification/smali/SmaliTests.smali
+++ b/test/458-checker-instruct-simplification/smali/SmaliTests.smali
@@ -327,3 +327,144 @@
 
     return v0
 .end method
+
+# Test simplification of the `~~var` pattern.
+# The transformation tested is implemented in `InstructionSimplifierVisitor::VisitNot`.
+
+## CHECK-START: long SmaliTests.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-DAG:     <<Arg:j\d+>>      ParameterValue
+## CHECK-DAG:                       Return [<<Arg>>]
+
+## CHECK-START: long SmaliTests.NotNot1(long) instruction_simplifier (after)
+## CHECK-NOT:                       Not
+
+.method public static 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-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-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:                           Not
+## CHECK-NOT:                       Not
+
+.method public static 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
+    add-int/2addr v1, v0
+
+    return v1
+.end method
+
+# Test simplification of double Boolean negation. Note that sometimes
+# 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-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-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-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-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-DAG:     <<Arg:z\d+>>       ParameterValue
+## CHECK-DAG:                        Return [<<Arg>>]
+
+.method public static NegateValue(Z)Z
+    .registers 2
+    .param p0, "arg"    # Z
+
+    .prologue
+
+    # return !arg
+    xor-int/lit8 v0, p0, 0x1
+    return v0
+.end method
+
+
+.method public static 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
+    xor-int/lit8 v0, v0, 0x1
+
+    return v0
+.end method
diff --git a/test/458-checker-instruct-simplification/src/Main.java b/test/458-checker-instruct-simplification/src/Main.java
index 529ea5b..5c36ce9 100644
--- a/test/458-checker-instruct-simplification/src/Main.java
+++ b/test/458-checker-instruct-simplification/src/Main.java
@@ -982,17 +982,18 @@
    */
 
   /// CHECK-START: long Main.$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-DAG:     <<Arg:j\d+>>       ParameterValue
+  /// CHECK-DAG:     <<ConstNeg1:j\d+>> LongConstant -1
+  /// CHECK-DAG:     <<Not1:j\d+>>      Xor [<<Arg>>,<<ConstNeg1>>]
+  /// CHECK-DAG:     <<Not2:j\d+>>      Xor [<<Not1>>,<<ConstNeg1>>]
+  /// CHECK-DAG:                        Return [<<Not2>>]
 
   /// CHECK-START: long Main.$noinline$NotNot1(long) instruction_simplifier (after)
   /// CHECK-DAG:     <<Arg:j\d+>>      ParameterValue
   /// CHECK-DAG:                       Return [<<Arg>>]
 
   /// CHECK-START: long Main.$noinline$NotNot1(long) instruction_simplifier (after)
-  /// CHECK-NOT:                       Not
+  /// CHECK-NOT:                       Xor
 
   public static long $noinline$NotNot1(long arg) {
     if (doThrow) { throw new Error(); }
@@ -1000,11 +1001,12 @@
   }
 
   /// CHECK-START: int Main.$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-DAG:     <<Arg:i\d+>>       ParameterValue
+  /// CHECK-DAG:     <<ConstNeg1:i\d+>> IntConstant -1
+  /// CHECK-DAG:     <<Not1:i\d+>>      Xor [<<Arg>>,<<ConstNeg1>>]
+  /// CHECK-DAG:     <<Not2:i\d+>>      Xor [<<Not1>>,<<ConstNeg1>>]
+  /// CHECK-DAG:     <<Add:i\d+>>       Add [<<Not2>>,<<Not1>>]
+  /// CHECK-DAG:                        Return [<<Add>>]
 
   /// CHECK-START: int Main.$noinline$NotNot2(int) instruction_simplifier (after)
   /// CHECK-DAG:     <<Arg:i\d+>>      ParameterValue
@@ -1016,6 +1018,9 @@
   /// CHECK:                           Not
   /// CHECK-NOT:                       Not
 
+  /// CHECK-START: int Main.$noinline$NotNot2(int) instruction_simplifier (after)
+  /// CHECK-NOT:                       Xor
+
   public static int $noinline$NotNot2(int arg) {
     if (doThrow) { throw new Error(); }
     int temp = ~arg;
@@ -1180,30 +1185,46 @@
 
   /// CHECK-START: boolean Main.$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-DAG:     <<Const1:i\d+>>    IntConstant 0
+  /// CHECK-DAG:     <<Result:z\d+>>    InvokeStaticOrDirect method_name:Main.NegateValue
+  /// CHECK-DAG:     <<NotResult:z\d+>> NotEqual [<<Result>>,<<Const1>>]
+  /// CHECK-DAG:                        If [<<NotResult>>]
+
+  /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier (after)
+  /// CHECK-NOT:                        NotEqual
 
   /// CHECK-START: boolean Main.$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-DAG:     <<Result:z\d+>>    InvokeStaticOrDirect method_name:Main.NegateValue
+  /// CHECK-DAG:     <<Const0:i\d+>>    IntConstant 0
+  /// CHECK-DAG:     <<Const1:i\d+>>    IntConstant 1
+  /// CHECK-DAG:     <<Phi:i\d+>>       Phi [<<Const1>>,<<Const0>>]
+  /// CHECK-DAG:                        Return [<<Phi>>]
 
   /// CHECK-START: boolean Main.$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-NOT:                        BooleanNot [<<Arg>>]
+  /// CHECK-NOT:                        Phi
+
+  /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier$after_inlining (before)
+  /// CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
+  /// CHECK-DAG:     <<Const0:i\d+>>    IntConstant 0
+  /// CHECK-DAG:     <<Const1:i\d+>>    IntConstant 1
+  /// CHECK-DAG:     <<Sel:i\d+>>       Select [<<Const1>>,<<Const0>>,<<Arg>>]
+  /// CHECK-DAG:     <<Sel2:i\d+>>      Select [<<Const1>>,<<Const0>>,<<Sel>>]
+  /// CHECK-DAG:                        Return [<<Sel2>>]
 
   /// CHECK-START: boolean Main.$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:                            BooleanNot [<<Arg>>]
+  /// CHECK-NEXT:                       Goto
+
+  /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier$after_inlining (after)
+  /// CHECK-NOT:                        Select
 
   /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) dead_code_elimination$final (after)
   /// CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
+  /// CHECK-NOT:                        BooleanNot [<<Arg>>]
   /// CHECK-DAG:                        Return [<<Arg>>]
 
   public static boolean NegateValue(boolean arg) {
@@ -1882,7 +1903,18 @@
     }
   }
 
-  public static int $noinline$runSmaliTestConst(String name, int arg) {
+  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);
+      return (Boolean) m.invoke(null, input);
+    } catch (Exception ex) {
+      throw new Error(ex);
+    }
+  }
+
+  public static int $noinline$runSmaliTestInt(String name, int arg) {
     if (doThrow) { throw new Error(); }
     try {
       Class<?> c = Class.forName("SmaliTests");
@@ -1893,6 +1925,17 @@
     }
   }
 
+  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);
+      return (Long) m.invoke(null, arg);
+    } catch (Exception ex) {
+      throw new Error(ex);
+    }
+  }
+
   /// CHECK-START: int Main.$noinline$intUnnecessaryShiftMasking(int, int) instruction_simplifier (before)
   /// CHECK:          <<Value:i\d+>>    ParameterValue
   /// CHECK:          <<Shift:i\d+>>    ParameterValue
@@ -2188,7 +2231,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));
     assertIntEquals(-1, $noinline$NotNot2(arg));
+    assertIntEquals(-1, $noinline$runSmaliTestInt("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));
@@ -2197,7 +2242,9 @@
     assertBooleanEquals(false, $noinline$NotEqualBoolVsIntConst(false));
     assertBooleanEquals(false, $noinline$NotEqualBoolVsIntConst(false));
     assertBooleanEquals(true, $noinline$NotNotBool(true));
+    assertBooleanEquals(true, $noinline$runSmaliTestBoolean("NotNotBool", true));
     assertBooleanEquals(false, $noinline$NotNotBool(false));
+    assertBooleanEquals(false, $noinline$runSmaliTestBoolean("NotNotBool", false));
     assertFloatEquals(50.0f, $noinline$Div2(100.0f));
     assertDoubleEquals(75.0, $noinline$Div2(150.0));
     assertFloatEquals(-400.0f, $noinline$DivMP25(100.0f));
@@ -2309,11 +2356,11 @@
       }
     }
 
-    assertIntEquals(0, $noinline$runSmaliTestConst("AddSubConst", 1));
-    assertIntEquals(3, $noinline$runSmaliTestConst("SubAddConst", 2));
-    assertIntEquals(-16, $noinline$runSmaliTestConst("SubSubConst1", 3));
-    assertIntEquals(-5, $noinline$runSmaliTestConst("SubSubConst2", 4));
-    assertIntEquals(26, $noinline$runSmaliTestConst("SubSubConst3", 5));
+    assertIntEquals(0, $noinline$runSmaliTestInt("AddSubConst", 1));
+    assertIntEquals(3, $noinline$runSmaliTestInt("SubAddConst", 2));
+    assertIntEquals(-16, $noinline$runSmaliTestInt("SubSubConst1", 3));
+    assertIntEquals(-5, $noinline$runSmaliTestInt("SubSubConst2", 4));
+    assertIntEquals(26, $noinline$runSmaliTestInt("SubSubConst3", 5));
     assertIntEquals(0x5e6f7808, $noinline$intUnnecessaryShiftMasking(0xabcdef01, 3));
     assertIntEquals(0x5e6f7808, $noinline$intUnnecessaryShiftMasking(0xabcdef01, 3 + 32));
     assertLongEquals(0xffffffffffffeaf3L, $noinline$longUnnecessaryShiftMasking(0xabcdef0123456789L, 50));
diff --git a/test/knownfailures.json b/test/knownfailures.json
index db993b7..a21c97c 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -602,7 +602,6 @@
     },
     {
         "tests": [
-            "458-checker-instruct-simplification",
             "536-checker-intrinsic-optimization",
             "565-checker-doublenegbitwise",
             "567-checker-compare",