1ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames/*
2fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * Copyright (C) 2016 The Android Open Source Project
3fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain *
4fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * Licensed under the Apache License, Version 2.0 (the "License");
5fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * you may not use this file except in compliance with the License.
6fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * You may obtain a copy of the License at
7fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain *
8fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain *      http://www.apache.org/licenses/LICENSE-2.0
9fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain *
10fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * Unless required by applicable law or agreed to in writing, software
11fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * distributed under the License is distributed on an "AS IS" BASIS,
12fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * See the License for the specific language governing permissions and
14fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain * limitations under the License.
15fb7fc7b1e11523b6e4f444f0f54de0b49cd0c4e1Roland Levillain */
16ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
17f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkinimport java.lang.reflect.Method;
18f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin
19ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Ramespublic class Main {
20ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
21ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  // A dummy value to defeat inlining of these routines.
22ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  static boolean doThrow = false;
23ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
24ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  public static void assertIntEquals(int expected, int result) {
25ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    if (expected != result) {
26ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames      throw new Error("Expected: " + expected + ", found: " + result);
27ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    }
28ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  }
29ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
30ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  public static void assertLongEquals(long expected, long result) {
31ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    if (expected != result) {
32ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames      throw new Error("Expected: " + expected + ", found: " + result);
33ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    }
34ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  }
35ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
36f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  public static void assertEquals(boolean expected, boolean result) {
37f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    if (expected != result) {
38f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin      throw new Error("Expected: " + expected + ", found: " + result);
39f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    }
40f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  }
41f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin
42f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  public static <T> T $noinline$runSmaliTest(String name, Class<T> klass, T input1, T input2) {
43f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    if (doThrow) { throw new Error(); }
44f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin
45f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    Class<T> inputKlass = (Class<T>)input1.getClass();
46f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    try {
47f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin      Class<?> c = Class.forName("SmaliTests");
48f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin      Method m = c.getMethod(name, klass, klass);
49f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin      return inputKlass.cast(m.invoke(null, input1, input2));
50f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    } catch (Exception ex) {
51f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin      throw new Error(ex);
52f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    }
53f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  }
54f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin
55ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  /**
56ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   * Test transformation of Not/Not/And into Or/Not.
57ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   */
58ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
59f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  // Note: before the instruction_simplifier pass, Xor's are used instead of
60f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  // Not's (the simplification happens during the same pass).
61a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (before)
62f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:i\d+>>          ParameterValue
63f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:i\d+>>          ParameterValue
64f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<CstM1:i\d+>>       IntConstant -1
65f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
66f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
67f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And:i\d+>>         And [<<Not1>>,<<Not2>>]
68f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<And>>]
69ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
70a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
71f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:i\d+>>          ParameterValue
72f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:i\d+>>          ParameterValue
73f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Or:i\d+>>          Or [<<P1>>,<<P2>>]
74f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not:i\d+>>         Not [<<Or>>]
75f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Not>>]
76ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
77a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
78f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Not
79f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            Not
809f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
819f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$andToOr(int, int) instruction_simplifier (after)
82f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            And
83ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
84ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  public static int $opt$noinline$andToOr(int a, int b) {
85ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    if (doThrow) throw new Error();
86ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    return ~a & ~b;
87ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  }
88ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
89ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  /**
909f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * Test transformation of Not/Not/And into Or/Not for boolean negations.
919f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * Note that the graph before this instruction simplification pass does not
929f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * contain `HBooleanNot` instructions. This is because this transformation
939f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * follows the optimization of `HSelect` to `HBooleanNot` occurring in the
949f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * same pass.
959f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   */
969f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
97f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_inlining (before)
98f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:z\d+>>          ParameterValue
99f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:z\d+>>          ParameterValue
100f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Const0:i\d+>>      IntConstant 0
101f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
102f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
103f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
104f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And:i\d+>>         And [<<Select2>>,<<Select1>>]
105f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<And>>]
106f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin
107f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_inlining (after)
108f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
109f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
110f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Or:i\d+>>          Or [<<Cond2>>,<<Cond1>>]
111f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<BooleanNot:z\d+>>  BooleanNot [<<Or>>]
112f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<BooleanNot>>]
1139f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1145319d3cca5a9b8e9e3f59421818272b966575172Wojciech Staszkiewicz  /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (after)
115f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            BooleanNot
116f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            BooleanNot
1179f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1185319d3cca5a9b8e9e3f59421818272b966575172Wojciech Staszkiewicz  /// CHECK-START: boolean Main.$opt$noinline$booleanAndToOr(boolean, boolean) instruction_simplifier$after_bce (after)
119f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            And
1209f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1219f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  public static boolean $opt$noinline$booleanAndToOr(boolean a, boolean b) {
1229f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames    if (doThrow) throw new Error();
1239f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames    return !a & !b;
1249f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  }
1259f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1269f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  /**
127ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   * Test transformation of Not/Not/Or into And/Not.
128ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   */
129ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
130f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  // See note above.
131f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  // The second Xor has its arguments reversed for no obvious reason.
132a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (before)
133f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:j\d+>>          ParameterValue
134f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:j\d+>>          ParameterValue
135f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<CstM1:j\d+>>       LongConstant -1
136f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not1:j\d+>>        Xor [<<P1>>,<<CstM1>>]
137f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not2:j\d+>>        Xor [<<CstM1>>,<<P2>>]
138f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Or:j\d+>>          Or [<<Not1>>,<<Not2>>]
139f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Or>>]
140ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
141a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
142f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:j\d+>>          ParameterValue
143f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:j\d+>>          ParameterValue
144f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And:j\d+>>         And [<<P1>>,<<P2>>]
145f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not:j\d+>>         Not [<<And>>]
146f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Not>>]
147ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
148a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
149f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Not
150f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            Not
1519f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1529f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  /// CHECK-START: long Main.$opt$noinline$orToAnd(long, long) instruction_simplifier (after)
153f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            Or
154ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
155ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  public static long $opt$noinline$orToAnd(long a, long b) {
156ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    if (doThrow) throw new Error();
157ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    return ~a | ~b;
158ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  }
159ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
160ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  /**
1619f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * Test transformation of Not/Not/Or into Or/And for boolean negations.
1629f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * Note that the graph before this instruction simplification pass does not
1639f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * contain `HBooleanNot` instructions. This is because this transformation
1649f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * follows the optimization of `HSelect` to `HBooleanNot` occurring in the
1659f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * same pass.
1669f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   */
1679f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
168f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_inlining (before)
169f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:z\d+>>          ParameterValue
170f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:z\d+>>          ParameterValue
171f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Const0:i\d+>>      IntConstant 0
172f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
173f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
174f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
175f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Or:i\d+>>          Or [<<Select2>>,<<Select1>>]
176f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Or>>]
177f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin
178f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_inlining (after)
179f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
180f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
181f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And:i\d+>>         And [<<Cond2>>,<<Cond1>>]
182f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<BooleanNot:z\d+>>  BooleanNot [<<And>>]
183f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<BooleanNot>>]
1849f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1855319d3cca5a9b8e9e3f59421818272b966575172Wojciech Staszkiewicz  /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (after)
186f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            BooleanNot
187f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            BooleanNot
1889f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1895319d3cca5a9b8e9e3f59421818272b966575172Wojciech Staszkiewicz  /// CHECK-START: boolean Main.$opt$noinline$booleanOrToAnd(boolean, boolean) instruction_simplifier$after_bce (after)
190f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            Or
1919f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1929f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  public static boolean $opt$noinline$booleanOrToAnd(boolean a, boolean b) {
1939f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames    if (doThrow) throw new Error();
1949f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames    return !a | !b;
1959f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  }
1969f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
1979f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  /**
198ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   * Test that the transformation copes with inputs being separated from the
199ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   * bitwise operations.
200ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   * This is a regression test. The initial logic was inserting the new bitwise
201ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   * operation incorrectly.
202ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   */
203ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
204a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (before)
205f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:i\d+>>          ParameterValue
206f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:i\d+>>          ParameterValue
207f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Cst1:i\d+>>        IntConstant 1
208f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<CstM1:i\d+>>       IntConstant -1
209f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<AddP1:i\d+>>       Add [<<P1>>,<<Cst1>>]
210f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not1:i\d+>>        Xor [<<AddP1>>,<<CstM1>>]
211f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<AddP2:i\d+>>       Add [<<P2>>,<<Cst1>>]
212f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not2:i\d+>>        Xor [<<AddP2>>,<<CstM1>>]
213f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Or:i\d+>>          Or [<<Not1>>,<<Not2>>]
214f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Or>>]
215ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
216a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
217f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:i\d+>>          ParameterValue
218f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:i\d+>>          ParameterValue
219f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Cst1:i\d+>>        IntConstant 1
220f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<AddP1:i\d+>>       Add [<<P1>>,<<Cst1>>]
221f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<AddP2:i\d+>>       Add [<<P2>>,<<Cst1>>]
222f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And:i\d+>>         And [<<AddP1>>,<<AddP2>>]
223f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not:i\d+>>         Not [<<And>>]
224f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Not>>]
225ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
226a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
227f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Not
228f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            Not
2299f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
2309f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$regressInputsAway(int, int) instruction_simplifier (after)
231f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            Or
232ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
233ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  public static int $opt$noinline$regressInputsAway(int a, int b) {
234ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    if (doThrow) throw new Error();
235ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    int a1 = a + 1;
236ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    int not_a1 = ~a1;
237ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    int b1 = b + 1;
238ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    int not_b1 = ~b1;
239ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    return not_a1 | not_b1;
240ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  }
241ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
242ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  /**
243ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   * Test transformation of Not/Not/Xor into Xor.
244ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   */
245ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
246ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  // See first note above.
247a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (before)
248f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:i\d+>>          ParameterValue
249f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:i\d+>>          ParameterValue
250f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<CstM1:i\d+>>       IntConstant -1
251f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
252f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
253f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Xor:i\d+>>         Xor [<<Not1>>,<<Not2>>]
254f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Xor>>]
255ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
256a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after)
257f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:i\d+>>          ParameterValue
258f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:i\d+>>          ParameterValue
259f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Xor:i\d+>>         Xor [<<P1>>,<<P2>>]
260f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Xor>>]
261ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
262a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$notXorToXor(int, int) instruction_simplifier (after)
263f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            Not
264ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
265ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  public static int $opt$noinline$notXorToXor(int a, int b) {
266ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    if (doThrow) throw new Error();
267ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    return ~a ^ ~b;
268ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  }
269ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
270ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  /**
2719f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * Test transformation of Not/Not/Xor into Xor for boolean negations.
2729f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * Note that the graph before this instruction simplification pass does not
2739f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * contain `HBooleanNot` instructions. This is because this transformation
2749f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * follows the optimization of `HSelect` to `HBooleanNot` occurring in the
2759f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   * same pass.
2769f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames   */
2779f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
278f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_inlining (before)
279f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:z\d+>>          ParameterValue
280f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:z\d+>>          ParameterValue
281f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Const0:i\d+>>      IntConstant 0
282f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Const1:i\d+>>      IntConstant 1
283f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Select1:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P1>>]
284f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Select2:i\d+>>     Select [<<Const1>>,<<Const0>>,<<P2>>]
285f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Xor:i\d+>>         Xor [<<Select2>>,<<Select1>>]
286f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Xor>>]
287f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin
288f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_inlining (after)
289f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Cond1:z\d+>>       ParameterValue
290f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Cond2:z\d+>>       ParameterValue
291f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Xor:i\d+>>         Xor [<<Cond2>>,<<Cond1>>]
292f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Xor>>]
2939f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
2945319d3cca5a9b8e9e3f59421818272b966575172Wojciech Staszkiewicz  /// CHECK-START: boolean Main.$opt$noinline$booleanNotXorToXor(boolean, boolean) instruction_simplifier$after_bce (after)
295f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            BooleanNot
2969f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
2979f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  public static boolean $opt$noinline$booleanNotXorToXor(boolean a, boolean b) {
2989f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames    if (doThrow) throw new Error();
2999f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames    return !a ^ !b;
3009f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  }
3019f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames
3029f98025ba5541641cfa9abb7b9cf30332d91fad1Alexandre Rames  /**
303ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   * Check that no transformation is done when one Not has multiple uses.
304ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames   */
305ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
306a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (before)
307f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:i\d+>>          ParameterValue
308f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:i\d+>>          ParameterValue
309f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<CstM1:i\d+>>       IntConstant -1
310f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<One:i\d+>>         IntConstant 1
311f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not2:i\d+>>        Xor [<<P2>>,<<CstM1>>]
312f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And2:i\d+>>        And [<<Not2>>,<<One>>]
313f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not1:i\d+>>        Xor [<<P1>>,<<CstM1>>]
314f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And1:i\d+>>        And [<<Not1>>,<<Not2>>]
315f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
316f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Add>>]
317ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
318a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after)
319f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P1:i\d+>>          ParameterValue
320f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<P2:i\d+>>          ParameterValue
321f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<One:i\d+>>         IntConstant 1
322f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not2:i\d+>>        Not [<<P2>>]
323f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And2:i\d+>>        And [<<Not2>>,<<One>>]
324f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Not1:i\d+>>        Not [<<P1>>]
325f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<And1:i\d+>>        And [<<Not1>>,<<Not2>>]
326f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:       <<Add:i\d+>>         Add [<<And2>>,<<And1>>]
327f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-DAG:                            Return [<<Add>>]
328ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
329a211a028e51c18e202ed326e4114cf5bb008a268Alexandre Rames  /// CHECK-START: int Main.$opt$noinline$notMultipleUses(int, int) instruction_simplifier (after)
330f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin  /// CHECK-NOT:                            Or
331ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
332ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  public static int $opt$noinline$notMultipleUses(int a, int b) {
333ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    if (doThrow) throw new Error();
334ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    int tmp = ~b;
335ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    return (tmp & 0x1) + (~a & tmp);
336ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  }
337ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames
338ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  public static void main(String[] args) {
339ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    assertIntEquals(~0xff, $opt$noinline$andToOr(0xf, 0xff));
340f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertIntEquals(~0xff, $noinline$runSmaliTest("$opt$noinline$andToOr", int.class, 0xf, 0xff));
341f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertEquals(true, $opt$noinline$booleanAndToOr(false, false));
342f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertEquals(true, $noinline$runSmaliTest("$opt$noinline$booleanAndToOr", boolean.class, false, false));
343ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    assertLongEquals(~0xf, $opt$noinline$orToAnd(0xf, 0xff));
344f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertLongEquals(~0xf, $noinline$runSmaliTest("$opt$noinline$orToAnd", long.class, 0xfL, 0xffL));
345f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertEquals(false, $opt$noinline$booleanOrToAnd(true, true));
346f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertEquals(false, $noinline$runSmaliTest("$opt$noinline$booleanOrToAnd", boolean.class, true, true));
347f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertIntEquals(-1, $opt$noinline$regressInputsAway(0xf, 0xff));
348f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertIntEquals(-1, $noinline$runSmaliTest("$opt$noinline$regressInputsAway", int.class, 0xf, 0xff));
349ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    assertIntEquals(0xf0, $opt$noinline$notXorToXor(0xf, 0xff));
350f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertIntEquals(0xf0, $noinline$runSmaliTest("$opt$noinline$notXorToXor", int.class, 0xf, 0xff));
351f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertEquals(true, $opt$noinline$booleanNotXorToXor(true, false));
352f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertEquals(true, $noinline$runSmaliTest("$opt$noinline$booleanNotXorToXor", boolean.class, true, false));
353ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames    assertIntEquals(~0xff, $opt$noinline$notMultipleUses(0xf, 0xff));
354f8c81921ba6d0e0443c92368d1536dcbe3e4ce7dIgor Murashkin    assertIntEquals(~0xff, $noinline$runSmaliTest("$opt$noinline$notMultipleUses", int.class, 0xf, 0xff));
355ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames  }
356ca0e3a0c9f1fd5902dc40043b061d2f9b79ec098Alexandre Rames}
357