Merge "Revert "Revert "ARM: VIXL32: Add an initial code generator that passes codegen_tests."""
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 4ca0600..b787888 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -1577,6 +1577,18 @@
     return;
   }
 
+  if ((input_cst != nullptr) && input_cst->IsOne()
+      && input_other->GetType() == Primitive::kPrimBoolean) {
+    // Replace code looking like
+    //    XOR dst, src, 1
+    // with
+    //    BOOLEAN_NOT dst, src
+    HBooleanNot* boolean_not = new (GetGraph()->GetArena()) HBooleanNot(input_other);
+    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, boolean_not);
+    RecordSimplification();
+    return;
+  }
+
   if ((input_cst != nullptr) && AreAllBitsSet(input_cst)) {
     // Replace code looking like
     //    XOR dst, src, 0xFFF...FF
diff --git a/test/005-annotations/build b/test/005-annotations/build
index 216843d..8b9f550 100644
--- a/test/005-annotations/build
+++ b/test/005-annotations/build
@@ -30,7 +30,8 @@
 
 if [ ${USE_JACK} = "true" ]; then
   jar cf classes.jill.jar -C classes .
-  ${JACK} --import classes.jill.jar --output-dex .
+  # Jack needs to emit annotations with CLASS retention.
+  ${JACK} -D jack.dex.annotation.class-retention=true --import classes.jill.jar --output-dex .
 else
   if [ ${NEED_DEX} = "true" ]; then
     ${DX} -JXmx256m --debug --dex --output=classes.dex classes
diff --git a/test/458-checker-instruct-simplification/src/Main.java b/test/458-checker-instruct-simplification/src/Main.java
index 5b14735..e71a0e1 100644
--- a/test/458-checker-instruct-simplification/src/Main.java
+++ b/test/458-checker-instruct-simplification/src/Main.java
@@ -1178,16 +1178,28 @@
    * remove the second.
    */
 
+  /// 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-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-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier$after_bce (before)
   /// CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
-  /// CHECK-DAG:     <<Const0:i\d+>>    IntConstant 0
-  /// CHECK-DAG:     <<Const1:i\d+>>    IntConstant 1
-  /// CHECK-DAG:     <<NotArg:i\d+>>    Select [<<Const1>>,<<Const0>>,<<Arg>>]
-  /// CHECK-DAG:     <<NotNotArg:i\d+>> Select [<<Const1>>,<<Const0>>,<<NotArg>>]
+  /// CHECK-DAG:     <<NotArg:z\d+>>    BooleanNot [<<Arg>>]
+  /// CHECK-DAG:     <<NotNotArg:z\d+>> BooleanNot [<<NotArg>>]
   /// CHECK-DAG:                        Return [<<NotNotArg>>]
 
   /// CHECK-START: boolean Main.$noinline$NotNotBool(boolean) instruction_simplifier$after_bce (after)
   /// CHECK-DAG:     <<Arg:z\d+>>       ParameterValue
+  /// CHECK-DAG:     <<NotArg:z\d+>>    BooleanNot [<<Arg>>]
   /// CHECK-DAG:                        Return [<<Arg>>]
 
   public static boolean NegateValue(boolean arg) {
diff --git a/test/463-checker-boolean-simplifier/smali/BooleanNotDx.smali b/test/463-checker-boolean-simplifier/smali/BooleanNotDx.smali
new file mode 100644
index 0000000..765d0eb
--- /dev/null
+++ b/test/463-checker-boolean-simplifier/smali/BooleanNotDx.smali
@@ -0,0 +1,65 @@
+# Copyright (C) 2016 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.
+
+.class public LBooleanNotSmali;
+.super Ljava/lang/Object;
+
+#
+# Elementary test negating a boolean. Verifies that blocks are merged and
+# empty branches removed.
+#
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (before)
+## CHECK-DAG:     <<Param:z\d+>>    ParameterValue
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:                       If [<<Param>>]
+## CHECK-DAG:     <<Phi:i\d+>>      Phi [<<Const0>>,<<Const1>>]
+## CHECK-DAG:                       Return [<<Phi>>]
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (before)
+## CHECK:                           Goto
+## CHECK:                           Goto
+## CHECK:                           Goto
+## CHECK-NOT:                       Goto
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (after)
+## CHECK-DAG:     <<Param:z\d+>>    ParameterValue
+## CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
+## CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
+## CHECK-DAG:     <<NotParam:i\d+>> Select [<<Const1>>,<<Const0>>,<<Param>>]
+## CHECK-DAG:                       Return [<<NotParam>>]
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (after)
+## CHECK-NOT:                       If
+## CHECK-NOT:                       Phi
+
+## CHECK-START: boolean BooleanNotSmali.BooleanNot(boolean) select_generator (after)
+## CHECK:                           Goto
+## CHECK-NOT:                       Goto
+
+.method public static BooleanNot(Z)Z
+  .registers 2
+
+  if-eqz v1, :true_start
+  const/4 v0, 0x0
+
+:return_start
+  return v0
+
+:true_start
+  const/4 v0, 0x1
+  goto :return_start
+
+.end method
diff --git a/test/463-checker-boolean-simplifier/src/Main.java b/test/463-checker-boolean-simplifier/src/Main.java
index f0fe1b1..9368488 100644
--- a/test/463-checker-boolean-simplifier/src/Main.java
+++ b/test/463-checker-boolean-simplifier/src/Main.java
@@ -32,42 +32,14 @@
     }
   }
 
-  /*
-   * Elementary test negating a boolean. Verifies that blocks are merged and
-   * empty branches removed.
-   */
-
-  /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (before)
-  /// CHECK-DAG:     <<Param:z\d+>>    ParameterValue
-  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
-  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
-  /// CHECK-DAG:                       If [<<Param>>]
-  /// CHECK-DAG:     <<Phi:i\d+>>      Phi [<<Const0>>,<<Const1>>]
-  /// CHECK-DAG:                       Return [<<Phi>>]
-
-  /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (before)
-  /// CHECK:                           Goto
-  /// CHECK:                           Goto
-  /// CHECK:                           Goto
-  /// CHECK-NOT:                       Goto
-
-  /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (after)
-  /// CHECK-DAG:     <<Param:z\d+>>    ParameterValue
-  /// CHECK-DAG:     <<Const0:i\d+>>   IntConstant 0
-  /// CHECK-DAG:     <<Const1:i\d+>>   IntConstant 1
-  /// CHECK-DAG:     <<NotParam:i\d+>> Select [<<Const1>>,<<Const0>>,<<Param>>]
-  /// CHECK-DAG:                       Return [<<NotParam>>]
-
-  /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (after)
-  /// CHECK-NOT:                       If
-  /// CHECK-NOT:                       Phi
-
-  /// CHECK-START: boolean Main.BooleanNot(boolean) select_generator (after)
-  /// CHECK:                           Goto
-  /// CHECK-NOT:                       Goto
-
-  public static boolean BooleanNot(boolean x) {
-    return !x;
+  // Invoke a method written in smali that implements the boolean ! operator. This method
+  // uses the if/else pattern generated by dx (while Jack generates a different pattern).
+  // Since this method is in a smali-generated class, we invoke it through reflection.
+  public static boolean SmaliBooleanNot(boolean x) throws Exception {
+      Class<?> c = Class.forName("BooleanNotSmali");
+      java.lang.reflect.Method method = c.getMethod("BooleanNot", boolean.class);
+      Object retValue = method.invoke(null, new Object[] { Boolean.valueOf(x) });
+      return ((Boolean) retValue).booleanValue();
   }
 
   /*
@@ -357,9 +329,9 @@
     return x ? 42 : (write_field = 43);
   }
 
-  public static void main(String[] args) {
-    assertBoolEquals(false, BooleanNot(true));
-    assertBoolEquals(true, BooleanNot(false));
+  public static void main(String[] args) throws Exception {
+    assertBoolEquals(false, SmaliBooleanNot(true));
+    assertBoolEquals(true, SmaliBooleanNot(false));
     assertBoolEquals(true, GreaterThan(10, 5));
     assertBoolEquals(false, GreaterThan(10, 10));
     assertBoolEquals(false, GreaterThan(5, 10));
diff --git a/test/565-checker-doublenegbitwise/src/Main.java b/test/565-checker-doublenegbitwise/src/Main.java
index 811c280..5ccc648 100644
--- a/test/565-checker-doublenegbitwise/src/Main.java
+++ b/test/565-checker-doublenegbitwise/src/Main.java
@@ -70,20 +70,19 @@
    * same pass.
    */
 
-  /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (before)
+  /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier (before)
   /// CHECK:       <<P1:z\d+>>          ParameterValue
   /// CHECK:       <<P2:z\d+>>          ParameterValue
-  /// CHECK-DAG:   <<Const0:i\d+>>      IntConstant 0
   /// CHECK-DAG:   <<Const1:i\d+>>      IntConstant 1
-  /// CHECK:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
-  /// CHECK:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
-  /// CHECK:       <<And:i\d+>>         And [<<Select2>>,<<Select1>>]
+  /// CHECK-DAG:   <<NotP1:i\d+>>       Xor [<<P1>>,<<Const1>>]
+  /// CHECK-DAG:   <<NotP2:i\d+>>       Xor [<<P2>>,<<Const1>>]
+  /// CHECK:       <<And:i\d+>>         And [<<NotP1>>,<<NotP2>>]
   /// CHECK:                            Return [<<And>>]
 
-  /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (after)
+  /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier (after)
   /// CHECK:       <<Cond1:z\d+>>       ParameterValue
   /// CHECK:       <<Cond2:z\d+>>       ParameterValue
-  /// CHECK:       <<Or:i\d+>>          Or [<<Cond2>>,<<Cond1>>]
+  /// CHECK:       <<Or:i\d+>>          Or [<<Cond1>>,<<Cond2>>]
   /// CHECK:       <<BooleanNot:z\d+>>  BooleanNot [<<Or>>]
   /// CHECK:                            Return [<<BooleanNot>>]
 
@@ -138,20 +137,19 @@
    * same pass.
    */
 
-  /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (before)
+  /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier (before)
   /// CHECK:       <<P1:z\d+>>          ParameterValue
   /// CHECK:       <<P2:z\d+>>          ParameterValue
-  /// CHECK-DAG:   <<Const0:i\d+>>      IntConstant 0
   /// CHECK-DAG:   <<Const1:i\d+>>      IntConstant 1
-  /// CHECK:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
-  /// CHECK:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
-  /// CHECK:       <<Or:i\d+>>          Or [<<Select2>>,<<Select1>>]
+  /// CHECK:       <<NotP1:i\d+>>       Xor [<<P1>>,<<Const1>>]
+  /// CHECK:       <<NotP2:i\d+>>       Xor [<<P2>>,<<Const1>>]
+  /// CHECK:       <<Or:i\d+>>          Or [<<NotP1>>,<<NotP2>>]
   /// CHECK:                            Return [<<Or>>]
 
-  /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (after)
+  /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier (after)
   /// CHECK:       <<Cond1:z\d+>>       ParameterValue
   /// CHECK:       <<Cond2:z\d+>>       ParameterValue
-  /// CHECK:       <<And:i\d+>>         And [<<Cond2>>,<<Cond1>>]
+  /// CHECK:       <<And:i\d+>>         And [<<Cond1>>,<<Cond2>>]
   /// CHECK:       <<BooleanNot:z\d+>>  BooleanNot [<<And>>]
   /// CHECK:                            Return [<<BooleanNot>>]
 
@@ -246,20 +244,19 @@
    * same pass.
    */
 
-  /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (before)
+  /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier (before)
   /// CHECK:       <<P1:z\d+>>          ParameterValue
   /// CHECK:       <<P2:z\d+>>          ParameterValue
-  /// CHECK-DAG:   <<Const0:i\d+>>      IntConstant 0
   /// CHECK-DAG:   <<Const1:i\d+>>      IntConstant 1
-  /// CHECK:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
-  /// CHECK:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
-  /// CHECK:       <<Xor:i\d+>>         Xor [<<Select2>>,<<Select1>>]
+  /// CHECK:       <<NotP1:i\d+>>       Xor [<<P1>>,<<Const1>>]
+  /// CHECK:       <<NotP2:i\d+>>       Xor [<<P2>>,<<Const1>>]
+  /// CHECK:       <<Xor:i\d+>>         Xor [<<NotP1>>,<<NotP2>>]
   /// CHECK:                            Return [<<Xor>>]
 
-  /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (after)
+  /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier (after)
   /// CHECK:       <<Cond1:z\d+>>       ParameterValue
   /// CHECK:       <<Cond2:z\d+>>       ParameterValue
-  /// CHECK:       <<Xor:i\d+>>         Xor [<<Cond2>>,<<Cond1>>]
+  /// CHECK:       <<Xor:i\d+>>         Xor [<<Cond1>>,<<Cond2>>]
   /// CHECK:                            Return [<<Xor>>]
 
   /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (after)