• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 public class Main {
18 
19   // A dummy value to defeat inlining of these routines.
20   static boolean doThrow = false;
21 
assertIntEquals(int expected, int result)22   public static void assertIntEquals(int expected, int result) {
23     if (expected != result) {
24       throw new Error("Expected: " + expected + ", found: " + result);
25     }
26   }
27 
assertLongEquals(long expected, long result)28   public static void assertLongEquals(long expected, long result) {
29     if (expected != result) {
30       throw new Error("Expected: " + expected + ", found: " + result);
31     }
32   }
33 
34   /**
35    * Test merging of `NOT+AND` into `BIC`.
36    */
37 
38   /// CHECK-START-ARM64: int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm64 (before)
39   /// CHECK:       <<Base:i\d+>>        ParameterValue
40   /// CHECK:       <<Mask:i\d+>>        ParameterValue
41   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
42   /// CHECK:       <<Op:i\d+>>          And [<<Base>>,<<Not>>]
43   /// CHECK:                            Return [<<Op>>]
44 
45   /// CHECK-START-ARM64: int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm64 (after)
46   /// CHECK:       <<Base:i\d+>>        ParameterValue
47   /// CHECK:       <<Mask:i\d+>>        ParameterValue
48   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:And
49   /// CHECK:                            Return [<<NegOp>>]
50 
51   /// CHECK-START-ARM64: int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm64 (after)
52   /// CHECK-NOT:                        Not
53   /// CHECK-NOT:                        And
54 
55   /// CHECK-START-ARM64: int Main.$opt$noinline$notAnd(int, int) disassembly (after)
56   /// CHECK:                            bic w{{\d+}}, w{{\d+}}, w{{\d+}}
57 
58 
59   /// CHECK-START-ARM:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm (before)
60   /// CHECK:       <<Base:i\d+>>        ParameterValue
61   /// CHECK:       <<Mask:i\d+>>        ParameterValue
62   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
63   /// CHECK:       <<Op:i\d+>>          And [<<Base>>,<<Not>>]
64   /// CHECK:                            Return [<<Op>>]
65 
66   /// CHECK-START-ARM:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm (after)
67   /// CHECK:       <<Base:i\d+>>        ParameterValue
68   /// CHECK:       <<Mask:i\d+>>        ParameterValue
69   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:And
70   /// CHECK:                            Return [<<NegOp>>]
71 
72   /// CHECK-START-ARM:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm (after)
73   /// CHECK-NOT:                        Not
74   /// CHECK-NOT:                        And
75 
76   /// CHECK-START-ARM:   int Main.$opt$noinline$notAnd(int, int) disassembly (after)
77   /// CHECK:                            bic r{{\d+}}, r{{\d+}}, r{{\d+}}
78 
$opt$noinline$notAnd(int base, int mask)79   public static int $opt$noinline$notAnd(int base, int mask) {
80     if (doThrow) throw new Error();
81     return base & ~mask;
82   }
83 
84   /**
85    * Test merging of `NOT+ORR` into `ORN`.
86    */
87 
88   /// CHECK-START-ARM64: long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm64 (before)
89   /// CHECK:       <<Base:j\d+>>        ParameterValue
90   /// CHECK:       <<Mask:j\d+>>        ParameterValue
91   /// CHECK:       <<Not:j\d+>>         Not [<<Mask>>]
92   /// CHECK:       <<Op:j\d+>>          Or [<<Base>>,<<Not>>]
93   /// CHECK:                            Return [<<Op>>]
94 
95   /// CHECK-START-ARM64: long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm64 (after)
96   /// CHECK:       <<Base:j\d+>>        ParameterValue
97   /// CHECK:       <<Mask:j\d+>>        ParameterValue
98   /// CHECK:       <<NegOp:j\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:Or
99   /// CHECK:                            Return [<<NegOp>>]
100 
101   /// CHECK-START-ARM64: long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm64 (after)
102   /// CHECK-NOT:                        Not
103   /// CHECK-NOT:                        Or
104 
105   /// CHECK-START-ARM64: long Main.$opt$noinline$notOr(long, long) disassembly (after)
106   /// CHECK:                            orn x{{\d+}}, x{{\d+}}, x{{\d+}}
107 
108 
109   /// CHECK-START-ARM:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm (before)
110   /// CHECK:       <<Base:j\d+>>        ParameterValue
111   /// CHECK:       <<Mask:j\d+>>        ParameterValue
112   /// CHECK:       <<Not:j\d+>>         Not [<<Mask>>]
113   /// CHECK:       <<Op:j\d+>>          Or [<<Base>>,<<Not>>]
114   /// CHECK:                            Return [<<Op>>]
115 
116   /// CHECK-START-ARM:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm (after)
117   /// CHECK:       <<Base:j\d+>>        ParameterValue
118   /// CHECK:       <<Mask:j\d+>>        ParameterValue
119   /// CHECK:       <<NegOp:j\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:Or
120   /// CHECK:                            Return [<<NegOp>>]
121 
122   /// CHECK-START-ARM:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm (after)
123   /// CHECK-NOT:                        Not
124   /// CHECK-NOT:                        Or
125 
126   /// CHECK-START-ARM:   long Main.$opt$noinline$notOr(long, long) disassembly (after)
127   /// CHECK:                            orn r{{\d+}}, r{{\d+}}, r{{\d+}}
128 
$opt$noinline$notOr(long base, long mask)129   public static long $opt$noinline$notOr(long base, long mask) {
130     if (doThrow) throw new Error();
131     return base | ~mask;
132   }
133 
134   /**
135    * Test merging of `NOT+EOR` into `EON`.
136    */
137 
138   /// CHECK-START-ARM64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm64 (before)
139   /// CHECK:       <<Base:i\d+>>        ParameterValue
140   /// CHECK:       <<Mask:i\d+>>        ParameterValue
141   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
142   /// CHECK:       <<Op:i\d+>>          Xor [<<Base>>,<<Not>>]
143   /// CHECK:                            Return [<<Op>>]
144 
145   /// CHECK-START-ARM64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm64 (after)
146   /// CHECK:       <<Base:i\d+>>        ParameterValue
147   /// CHECK:       <<Mask:i\d+>>        ParameterValue
148   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:Xor
149   /// CHECK:                            Return [<<NegOp>>]
150 
151   /// CHECK-START-ARM64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm64 (after)
152   /// CHECK-NOT:                        Not
153   /// CHECK-NOT:                        Xor
154 
155   /// CHECK-START-ARM64: int Main.$opt$noinline$notXor(int, int) disassembly (after)
156   /// CHECK:                            eon w{{\d+}}, w{{\d+}}, w{{\d+}}
157 
158 
159   /// CHECK-START-ARM:   int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm (before)
160   /// CHECK:       <<Base:i\d+>>        ParameterValue
161   /// CHECK:       <<Mask:i\d+>>        ParameterValue
162   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
163   /// CHECK:       <<Op:i\d+>>          Xor [<<Base>>,<<Not>>]
164   /// CHECK:                            Return [<<Op>>]
165 
166   /// CHECK-START-ARM:   int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm (after)
167   /// CHECK:       <<Base:i\d+>>        ParameterValue
168   /// CHECK:       <<Mask:i\d+>>        ParameterValue
169   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
170   /// CHECK:       <<Op:i\d+>>          Xor [<<Base>>,<<Not>>]
171   /// CHECK:                            Return [<<Op>>]
172 
173   /// CHECK-START-ARM:   int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm (after)
174   /// CHECK-NOT:                        BitwiseNegatedRight
175 
$opt$noinline$notXor(int base, int mask)176   public static int $opt$noinline$notXor(int base, int mask) {
177     if (doThrow) throw new Error();
178     return base ^ ~mask;
179   }
180 
181   /**
182    * Check that transformation is done when the argument is a constant.
183    */
184 
185   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_arm64 (before)
186   /// CHECK:       <<Base:i\d+>>        ParameterValue
187   /// CHECK:       <<Constant:i\d+>>    IntConstant
188   /// CHECK:       <<Not:i\d+>>         Not [<<Base>>]
189   /// CHECK:       <<Op:i\d+>>          And [<<Not>>,<<Constant>>]
190   /// CHECK:                            Return [<<Op>>]
191 
192   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_arm64 (after)
193   /// CHECK:       <<Base:i\d+>>        ParameterValue
194   /// CHECK:       <<Constant:i\d+>>    IntConstant
195   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Constant>>,<<Base>>] kind:And
196   /// CHECK:                            Return [<<NegOp>>]
197 
198 
199   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_arm (before)
200   /// CHECK:       <<Base:i\d+>>        ParameterValue
201   /// CHECK:       <<Constant:i\d+>>    IntConstant
202   /// CHECK:       <<Not:i\d+>>         Not [<<Base>>]
203   /// CHECK:       <<Op:i\d+>>          And [<<Not>>,<<Constant>>]
204   /// CHECK:                            Return [<<Op>>]
205 
206   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_arm (after)
207   /// CHECK:       <<Base:i\d+>>        ParameterValue
208   /// CHECK:       <<Constant:i\d+>>    IntConstant
209   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Constant>>,<<Base>>] kind:And
210   /// CHECK:                            Return [<<NegOp>>]
211 
$opt$noinline$notAndConstant(int mask)212   public static int $opt$noinline$notAndConstant(int mask) {
213     if (doThrow) throw new Error();
214     return 0xf & ~mask;
215   }
216 
217   /**
218    * Check that no transformation is done when Not has multiple uses.
219    */
220 
221   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm64 (before)
222   /// CHECK:       <<Base:i\d+>>        ParameterValue
223   /// CHECK:       <<Mask:i\d+>>        ParameterValue
224   /// CHECK:       <<One:i\d+>>         IntConstant
225   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
226   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
227   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
228   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
229   /// CHECK:                            Return [<<Add>>]
230 
231   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm64 (after)
232   /// CHECK:       <<Base:i\d+>>        ParameterValue
233   /// CHECK:       <<Mask:i\d+>>        ParameterValue
234   /// CHECK:       <<One:i\d+>>         IntConstant
235   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
236   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
237   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
238   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
239   /// CHECK:                            Return [<<Add>>]
240 
241   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm64 (after)
242   /// CHECK-NOT:                        BitwiseNegatedRight
243 
244 
245   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm (before)
246   /// CHECK:       <<Base:i\d+>>        ParameterValue
247   /// CHECK:       <<Mask:i\d+>>        ParameterValue
248   /// CHECK:       <<One:i\d+>>         IntConstant
249   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
250   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
251   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
252   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
253   /// CHECK:                            Return [<<Add>>]
254 
255   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm (after)
256   /// CHECK:       <<Base:i\d+>>        ParameterValue
257   /// CHECK:       <<Mask:i\d+>>        ParameterValue
258   /// CHECK:       <<One:i\d+>>         IntConstant
259   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
260   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
261   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
262   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
263   /// CHECK:                            Return [<<Add>>]
264 
265   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm (after)
266   /// CHECK-NOT:                        BitwiseNegatedRight
267 
$opt$noinline$notAndMultipleUses(int base, int mask)268   public static int $opt$noinline$notAndMultipleUses(int base, int mask) {
269     if (doThrow) throw new Error();
270     int tmp = ~mask;
271     return (tmp & 0x1) + (base & tmp);
272   }
273 
274   /**
275    * Check that no transformation is done when both inputs are Not's.
276    */
277 
278   // We don't check the instructions before the pass, since if De Morgan's laws
279   // have been applied then Not/Not/Or is replaced by And/Not.
280 
281   /// CHECK-START-ARM64: int Main.$opt$noinline$deMorganOr(int, int) instruction_simplifier_arm64 (after)
282   /// CHECK-NOT:                        BitwiseNegatedRight
283 
284   /// CHECK-START-ARM:   int Main.$opt$noinline$deMorganOr(int, int) instruction_simplifier_arm (after)
285   /// CHECK-NOT:                        BitwiseNegatedRight
286 
$opt$noinline$deMorganOr(int a, int b)287   public static int $opt$noinline$deMorganOr(int a, int b) {
288     if (doThrow) throw new Error();
289     return ~a | ~b;
290   }
291 
main(String[] args)292   public static void main(String[] args) {
293     assertIntEquals(0xe,   $opt$noinline$notAnd(0xf, 0x1));
294     assertLongEquals(~0x0, $opt$noinline$notOr(0xf, 0x1));
295     assertIntEquals(~0xe,  $opt$noinline$notXor(0xf, 0x1));
296     assertIntEquals(0xe,  $opt$noinline$notAndConstant(0x1));
297     assertIntEquals(0xe,   $opt$noinline$notAndMultipleUses(0xf, 0x1));
298     assertIntEquals(~0x1,  $opt$noinline$deMorganOr(0x3, 0x1));
299   }
300 }
301