xref: /aosp_15_r20/art/test/564-checker-negbitwise/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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 
assertIntEquals(int expected, int result)19   public static void assertIntEquals(int expected, int result) {
20     if (expected != result) {
21       throw new Error("Expected: " + expected + ", found: " + result);
22     }
23   }
24 
assertLongEquals(long expected, long result)25   public static void assertLongEquals(long expected, long result) {
26     if (expected != result) {
27       throw new Error("Expected: " + expected + ", found: " + result);
28     }
29   }
30 
31   /**
32    * Test merging of `NOT+AND` into `BIC`.
33    */
34 
35   /// CHECK-START-ARM64: int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm64 (before)
36   /// CHECK:       <<Base:i\d+>>        ParameterValue
37   /// CHECK:       <<Mask:i\d+>>        ParameterValue
38   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
39   /// CHECK:       <<Op:i\d+>>          And [<<Base>>,<<Not>>]
40   /// CHECK:                            Return [<<Op>>]
41 
42   /// CHECK-START-ARM64: int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm64 (after)
43   /// CHECK:       <<Base:i\d+>>        ParameterValue
44   /// CHECK:       <<Mask:i\d+>>        ParameterValue
45   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:And
46   /// CHECK:                            Return [<<NegOp>>]
47 
48   /// CHECK-START-ARM64: int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm64 (after)
49   /// CHECK-NOT:                        Not
50   /// CHECK-NOT:                        And
51 
52   /// CHECK-START-ARM64: int Main.$opt$noinline$notAnd(int, int) disassembly (after)
53   /// CHECK:                            bic w{{\d+}}, w{{\d+}}, w{{\d+}}
54 
55 
56   /// CHECK-START-ARM:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm (before)
57   /// CHECK:       <<Base:i\d+>>        ParameterValue
58   /// CHECK:       <<Mask:i\d+>>        ParameterValue
59   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
60   /// CHECK:       <<Op:i\d+>>          And [<<Base>>,<<Not>>]
61   /// CHECK:                            Return [<<Op>>]
62 
63   /// CHECK-START-ARM:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm (after)
64   /// CHECK:       <<Base:i\d+>>        ParameterValue
65   /// CHECK:       <<Mask:i\d+>>        ParameterValue
66   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:And
67   /// CHECK:                            Return [<<NegOp>>]
68 
69   /// CHECK-START-ARM:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_arm (after)
70   /// CHECK-NOT:                        Not
71   /// CHECK-NOT:                        And
72 
73   /// CHECK-START-ARM:   int Main.$opt$noinline$notAnd(int, int) disassembly (after)
74   /// CHECK:                            bic r{{\d+}}, r{{\d+}}, r{{\d+}}
75 
76 
77   /// CHECK-START-RISCV64:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_riscv64 (before)
78   /// CHECK:       <<Base:i\d+>>        ParameterValue
79   /// CHECK:       <<Mask:i\d+>>        ParameterValue
80   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
81   /// CHECK:       <<Op:i\d+>>          And [<<Base>>,<<Not>>]
82   /// CHECK:                            Return [<<Op>>]
83 
84   /// CHECK-START-RISCV64:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_riscv64 (after)
85   /// CHECK:       <<Base:i\d+>>        ParameterValue
86   /// CHECK:       <<Mask:i\d+>>        ParameterValue
87   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:And
88   /// CHECK:                            Return [<<NegOp>>]
89 
90   /// CHECK-START-RISCV64:   int Main.$opt$noinline$notAnd(int, int) instruction_simplifier_riscv64 (after)
91   /// CHECK-NOT:                        Not
92   /// CHECK-NOT:                        And
93 
94   /// CHECK-START-RISCV64:   int Main.$opt$noinline$notAnd(int, int) disassembly (after)
95   /// CHECK:                            andn a{{\d+}}, a{{\d+}}, a{{\d+}}
96 
$opt$noinline$notAnd(int base, int mask)97   public static int $opt$noinline$notAnd(int base, int mask) {
98     return base & ~mask;
99   }
100 
101   /**
102    * Test merging of `NOT+ORR` into `ORN`.
103    */
104 
105   /// CHECK-START-ARM64: long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm64 (before)
106   /// CHECK:       <<Base:j\d+>>        ParameterValue
107   /// CHECK:       <<Mask:j\d+>>        ParameterValue
108   /// CHECK:       <<Not:j\d+>>         Not [<<Mask>>]
109   /// CHECK:       <<Op:j\d+>>          Or [<<Base>>,<<Not>>]
110   /// CHECK:                            Return [<<Op>>]
111 
112   /// CHECK-START-ARM64: long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm64 (after)
113   /// CHECK:       <<Base:j\d+>>        ParameterValue
114   /// CHECK:       <<Mask:j\d+>>        ParameterValue
115   /// CHECK:       <<NegOp:j\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:Or
116   /// CHECK:                            Return [<<NegOp>>]
117 
118   /// CHECK-START-ARM64: long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm64 (after)
119   /// CHECK-NOT:                        Not
120   /// CHECK-NOT:                        Or
121 
122   /// CHECK-START-ARM64: long Main.$opt$noinline$notOr(long, long) disassembly (after)
123   /// CHECK:                            orn x{{\d+}}, x{{\d+}}, x{{\d+}}
124 
125 
126   /// CHECK-START-ARM:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm (before)
127   /// CHECK:       <<Base:j\d+>>        ParameterValue
128   /// CHECK:       <<Mask:j\d+>>        ParameterValue
129   /// CHECK:       <<Not:j\d+>>         Not [<<Mask>>]
130   /// CHECK:       <<Op:j\d+>>          Or [<<Base>>,<<Not>>]
131   /// CHECK:                            Return [<<Op>>]
132 
133   /// CHECK-START-ARM:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm (after)
134   /// CHECK:       <<Base:j\d+>>        ParameterValue
135   /// CHECK:       <<Mask:j\d+>>        ParameterValue
136   /// CHECK:       <<NegOp:j\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:Or
137   /// CHECK:                            Return [<<NegOp>>]
138 
139   /// CHECK-START-ARM:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_arm (after)
140   /// CHECK-NOT:                        Not
141   /// CHECK-NOT:                        Or
142 
143   /// CHECK-START-ARM:   long Main.$opt$noinline$notOr(long, long) disassembly (after)
144   /// CHECK:                            orn r{{\d+}}, r{{\d+}}, r{{\d+}}
145 
146 
147   /// CHECK-START-RISCV64:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_riscv64 (before)
148   /// CHECK:       <<Base:j\d+>>        ParameterValue
149   /// CHECK:       <<Mask:j\d+>>        ParameterValue
150   /// CHECK:       <<Not:j\d+>>         Not [<<Mask>>]
151   /// CHECK:       <<Op:j\d+>>          Or [<<Base>>,<<Not>>]
152   /// CHECK:                            Return [<<Op>>]
153 
154   /// CHECK-START-RISCV64:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_riscv64 (after)
155   /// CHECK:       <<Base:j\d+>>        ParameterValue
156   /// CHECK:       <<Mask:j\d+>>        ParameterValue
157   /// CHECK:       <<NegOp:j\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:Or
158   /// CHECK:                            Return [<<NegOp>>]
159 
160   /// CHECK-START-RISCV64:   long Main.$opt$noinline$notOr(long, long) instruction_simplifier_riscv64 (after)
161   /// CHECK-NOT:                        Not
162   /// CHECK-NOT:                        Or
163 
164   /// CHECK-START-RISCV64:   long Main.$opt$noinline$notOr(long, long) disassembly (after)
165   /// CHECK:                            orn a{{\d+}}, a{{\d+}}, a{{\d+}}
166 
$opt$noinline$notOr(long base, long mask)167   public static long $opt$noinline$notOr(long base, long mask) {
168     return base | ~mask;
169   }
170 
171   /**
172    * Test merging of `NOT+EOR` into `EON`.
173    */
174 
175   /// CHECK-START-ARM64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm64 (before)
176   /// CHECK:       <<Base:i\d+>>        ParameterValue
177   /// CHECK:       <<Mask:i\d+>>        ParameterValue
178   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
179   /// CHECK:       <<Op:i\d+>>          Xor [<<Base>>,<<Not>>]
180   /// CHECK:                            Return [<<Op>>]
181 
182   /// CHECK-START-ARM64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm64 (after)
183   /// CHECK:       <<Base:i\d+>>        ParameterValue
184   /// CHECK:       <<Mask:i\d+>>        ParameterValue
185   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:Xor
186   /// CHECK:                            Return [<<NegOp>>]
187 
188   /// CHECK-START-ARM64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm64 (after)
189   /// CHECK-NOT:                        Not
190   /// CHECK-NOT:                        Xor
191 
192   /// CHECK-START-ARM64: int Main.$opt$noinline$notXor(int, int) disassembly (after)
193   /// CHECK:                            eon w{{\d+}}, w{{\d+}}, w{{\d+}}
194 
195 
196   /// CHECK-START-ARM:   int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm (before)
197   /// CHECK:       <<Base:i\d+>>        ParameterValue
198   /// CHECK:       <<Mask:i\d+>>        ParameterValue
199   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
200   /// CHECK:       <<Op:i\d+>>          Xor [<<Base>>,<<Not>>]
201   /// CHECK:                            Return [<<Op>>]
202 
203   /// CHECK-START-ARM:   int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm (after)
204   /// CHECK:       <<Base:i\d+>>        ParameterValue
205   /// CHECK:       <<Mask:i\d+>>        ParameterValue
206   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
207   /// CHECK:       <<Op:i\d+>>          Xor [<<Base>>,<<Not>>]
208   /// CHECK:                            Return [<<Op>>]
209 
210   /// CHECK-START-ARM:   int Main.$opt$noinline$notXor(int, int) instruction_simplifier_arm (after)
211   /// CHECK-NOT:                        BitwiseNegatedRight
212 
213 
214   /// CHECK-START-RISCV64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_riscv64 (before)
215   /// CHECK:       <<Base:i\d+>>        ParameterValue
216   /// CHECK:       <<Mask:i\d+>>        ParameterValue
217   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
218   /// CHECK:       <<Op:i\d+>>          Xor [<<Base>>,<<Not>>]
219   /// CHECK:                            Return [<<Op>>]
220 
221   /// CHECK-START-RISCV64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_riscv64 (after)
222   /// CHECK:       <<Base:i\d+>>        ParameterValue
223   /// CHECK:       <<Mask:i\d+>>        ParameterValue
224   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Base>>,<<Mask>>] kind:Xor
225   /// CHECK:                            Return [<<NegOp>>]
226 
227   /// CHECK-START-RISCV64: int Main.$opt$noinline$notXor(int, int) instruction_simplifier_riscv64 (after)
228   /// CHECK-NOT:                        Not
229   /// CHECK-NOT:                        Xor
230 
231   /// CHECK-START-RISCV64: int Main.$opt$noinline$notXor(int, int) disassembly (after)
232   /// CHECK:                            xnor a{{\d+}}, a{{\d+}}, a{{\d+}}
233 
$opt$noinline$notXor(int base, int mask)234   public static int $opt$noinline$notXor(int base, int mask) {
235     return base ^ ~mask;
236   }
237 
238   /**
239    * Check that transformation is done when the argument is a constant.
240    */
241 
242   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_arm64 (before)
243   /// CHECK:       <<Base:i\d+>>        ParameterValue
244   /// CHECK:       <<Constant:i\d+>>    IntConstant
245   /// CHECK:       <<Not:i\d+>>         Not [<<Base>>]
246   /// CHECK:       <<Op:i\d+>>          And [<<Not>>,<<Constant>>]
247   /// CHECK:                            Return [<<Op>>]
248 
249   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_arm64 (after)
250   /// CHECK:       <<Base:i\d+>>        ParameterValue
251   /// CHECK:       <<Constant:i\d+>>    IntConstant
252   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Constant>>,<<Base>>] kind:And
253   /// CHECK:                            Return [<<NegOp>>]
254 
255 
256   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_arm (before)
257   /// CHECK:       <<Base:i\d+>>        ParameterValue
258   /// CHECK:       <<Constant:i\d+>>    IntConstant
259   /// CHECK:       <<Not:i\d+>>         Not [<<Base>>]
260   /// CHECK:       <<Op:i\d+>>          And [<<Not>>,<<Constant>>]
261   /// CHECK:                            Return [<<Op>>]
262 
263   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_arm (after)
264   /// CHECK:       <<Base:i\d+>>        ParameterValue
265   /// CHECK:       <<Constant:i\d+>>    IntConstant
266   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Constant>>,<<Base>>] kind:And
267   /// CHECK:                            Return [<<NegOp>>]
268 
269 
270   /// CHECK-START-RISCV64: int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_riscv64 (before)
271   /// CHECK:       <<Base:i\d+>>        ParameterValue
272   /// CHECK:       <<Constant:i\d+>>    IntConstant
273   /// CHECK:       <<Not:i\d+>>         Not [<<Base>>]
274   /// CHECK:       <<Op:i\d+>>          And [<<Not>>,<<Constant>>]
275   /// CHECK:                            Return [<<Op>>]
276 
277   /// CHECK-START-RISCV64: int Main.$opt$noinline$notAndConstant(int) instruction_simplifier_riscv64 (after)
278   /// CHECK:       <<Base:i\d+>>        ParameterValue
279   /// CHECK:       <<Constant:i\d+>>    IntConstant
280   /// CHECK:       <<NegOp:i\d+>>       BitwiseNegatedRight [<<Constant>>,<<Base>>] kind:And
281   /// CHECK:                            Return [<<NegOp>>]
282 
$opt$noinline$notAndConstant(int mask)283   public static int $opt$noinline$notAndConstant(int mask) {
284     return 0xf & ~mask;
285   }
286 
287   /**
288    * Check that no transformation is done when Not has multiple uses.
289    */
290 
291   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm64 (before)
292   /// CHECK:       <<Base:i\d+>>        ParameterValue
293   /// CHECK:       <<Mask:i\d+>>        ParameterValue
294   /// CHECK:       <<One:i\d+>>         IntConstant
295   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
296   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
297   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
298   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
299   /// CHECK:                            Return [<<Add>>]
300 
301   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm64 (after)
302   /// CHECK:       <<Base:i\d+>>        ParameterValue
303   /// CHECK:       <<Mask:i\d+>>        ParameterValue
304   /// CHECK:       <<One:i\d+>>         IntConstant
305   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
306   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
307   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
308   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
309   /// CHECK:                            Return [<<Add>>]
310 
311   /// CHECK-START-ARM64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm64 (after)
312   /// CHECK-NOT:                        BitwiseNegatedRight
313 
314 
315   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm (before)
316   /// CHECK:       <<Base:i\d+>>        ParameterValue
317   /// CHECK:       <<Mask:i\d+>>        ParameterValue
318   /// CHECK:       <<One:i\d+>>         IntConstant
319   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
320   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
321   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
322   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
323   /// CHECK:                            Return [<<Add>>]
324 
325   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm (after)
326   /// CHECK:       <<Base:i\d+>>        ParameterValue
327   /// CHECK:       <<Mask:i\d+>>        ParameterValue
328   /// CHECK:       <<One:i\d+>>         IntConstant
329   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
330   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
331   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
332   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
333   /// CHECK:                            Return [<<Add>>]
334 
335   /// CHECK-START-ARM:   int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_arm (after)
336   /// CHECK-NOT:                        BitwiseNegatedRight
337 
338 
339   /// CHECK-START-RISCV64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_riscv64 (before)
340   /// CHECK:       <<Base:i\d+>>        ParameterValue
341   /// CHECK:       <<Mask:i\d+>>        ParameterValue
342   /// CHECK:       <<One:i\d+>>         IntConstant
343   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
344   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
345   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
346   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
347   /// CHECK:                            Return [<<Add>>]
348 
349   /// CHECK-START-RISCV64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_riscv64 (after)
350   /// CHECK:       <<Base:i\d+>>        ParameterValue
351   /// CHECK:       <<Mask:i\d+>>        ParameterValue
352   /// CHECK:       <<One:i\d+>>         IntConstant
353   /// CHECK:       <<Not:i\d+>>         Not [<<Mask>>]
354   /// CHECK:       <<Op1:i\d+>>         And [<<Not>>,<<One>>]
355   /// CHECK:       <<Op2:i\d+>>         And [<<Base>>,<<Not>>]
356   /// CHECK:       <<Add:i\d+>>         Add [<<Op1>>,<<Op2>>]
357   /// CHECK:                            Return [<<Add>>]
358 
359   /// CHECK-START-RISCV64: int Main.$opt$noinline$notAndMultipleUses(int, int) instruction_simplifier_riscv64 (after)
360   /// CHECK-NOT:                        BitwiseNegatedRight
361 
$opt$noinline$notAndMultipleUses(int base, int mask)362   public static int $opt$noinline$notAndMultipleUses(int base, int mask) {
363     int tmp = ~mask;
364     return (tmp & 0x1) + (base & tmp);
365   }
366 
367   /**
368    * Check that no transformation is done when both inputs are Not's.
369    */
370 
371   // We don't check the instructions before the pass, since if De Morgan's laws
372   // have been applied then Not/Not/Or is replaced by And/Not.
373 
374   /// CHECK-START-ARM64: int Main.$opt$noinline$deMorganOr(int, int) instruction_simplifier_arm64 (after)
375   /// CHECK-NOT:                        BitwiseNegatedRight
376 
377   /// CHECK-START-ARM:   int Main.$opt$noinline$deMorganOr(int, int) instruction_simplifier_arm (after)
378   /// CHECK-NOT:                        BitwiseNegatedRight
379 
380   /// CHECK-START-RISCV64: int Main.$opt$noinline$deMorganOr(int, int) instruction_simplifier_riscv64 (after)
381   /// CHECK-NOT:                        BitwiseNegatedRight
382 
$opt$noinline$deMorganOr(int a, int b)383   public static int $opt$noinline$deMorganOr(int a, int b) {
384     return ~a | ~b;
385   }
386 
387   /**
388    * Check that we transform a And+Sub into a bic
389    */
390 
391   /// CHECK-START-ARM: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_arm (before)
392   /// CHECK: <<HAnd:i\d+>> And [<<Left:i\d+>>,<<Right:i\d+>>]
393   /// CHECK:               Sub [<<Left>>,<<HAnd>>]
394 
395   /// CHECK-START-ARM: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_arm (after)
396   /// CHECK-NOT: And
397 
398   /// CHECK-START-ARM: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_arm (after)
399   /// CHECK-NOT: Sub
400 
401   /// CHECK-START-ARM: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_arm (after)
402   /// CHECK:     BitwiseNegatedRight kind:And
403 
404   /// CHECK-START-ARM64: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_arm64 (before)
405   /// CHECK: <<HAnd:i\d+>> And [<<Left:i\d+>>,<<Right:i\d+>>]
406   /// CHECK:               Sub [<<Left>>,<<HAnd>>]
407 
408   /// CHECK-START-ARM64: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_arm64 (after)
409   /// CHECK-NOT: And
410 
411   /// CHECK-START-ARM64: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_arm64 (after)
412   /// CHECK-NOT: Sub
413 
414   /// CHECK-START-ARM64: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_arm64 (after)
415   /// CHECK:     BitwiseNegatedRight kind:And
416 
417 
418   /// CHECK-START-RISCV64: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_riscv64 (before)
419   /// CHECK:       <<HAnd:i\d+>>        And [<<Left:i\d+>>,<<Right:i\d+>>]
420   /// CHECK:                            Sub [<<Left>>,<<HAnd>>]
421 
422   /// CHECK-START-RISCV64: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_riscv64 (after)
423   /// CHECK-NOT:                        And
424 
425   /// CHECK-START-RISCV64: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_riscv64 (after)
426   /// CHECK-NOT:                        Sub
427 
428   /// CHECK-START-RISCV64: int Main.$noinline$AndSubIntoBic(int, int) instruction_simplifier_riscv64 (after)
429   /// CHECK:                            BitwiseNegatedRight kind:And
430 
$noinline$AndSubIntoBic(int a, int b)431   public static int $noinline$AndSubIntoBic(int a, int b) {
432       return a - (a & b);
433   }
434 
435   /**
436    * Check that we transform a And+Sub into a bic. Alternative version where the and is inverted.
437    */
438 
439   /// CHECK-START-ARM: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_arm (before)
440   /// CHECK: <<HAnd:i\d+>> And [<<Left:i\d+>>,<<Right:i\d+>>]
441   /// CHECK:               Sub [<<Right>>,<<HAnd>>]
442 
443   /// CHECK-START-ARM: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_arm (after)
444   /// CHECK-NOT: And
445 
446   /// CHECK-START-ARM: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_arm (after)
447   /// CHECK-NOT: Sub
448 
449   /// CHECK-START-ARM: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_arm (after)
450   /// CHECK:     BitwiseNegatedRight kind:And
451 
452   /// CHECK-START-ARM64: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_arm64 (before)
453   /// CHECK: <<HAnd:i\d+>> And [<<Left:i\d+>>,<<Right:i\d+>>]
454   /// CHECK:               Sub [<<Right>>,<<HAnd>>]
455 
456   /// CHECK-START-ARM64: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_arm64 (after)
457   /// CHECK-NOT: And
458 
459   /// CHECK-START-ARM64: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_arm64 (after)
460   /// CHECK-NOT: Sub
461 
462   /// CHECK-START-ARM64: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_arm64 (after)
463   /// CHECK:     BitwiseNegatedRight kind:And
464 
465 
466   /// CHECK-START-RISCV64: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_riscv64 (before)
467   /// CHECK:       <<HAnd:i\d+>>        And [<<Left:i\d+>>,<<Right:i\d+>>]
468   /// CHECK:                            Sub [<<Right>>,<<HAnd>>]
469 
470   /// CHECK-START-RISCV64: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_riscv64 (after)
471   /// CHECK-NOT:                        And
472 
473   /// CHECK-START-RISCV64: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_riscv64 (after)
474   /// CHECK-NOT:                        Sub
475 
476   /// CHECK-START-RISCV64: int Main.$noinline$AndSubIntoBic_v2(int, int) instruction_simplifier_riscv64 (after)
477   /// CHECK:                            BitwiseNegatedRight kind:And
478 
$noinline$AndSubIntoBic_v2(int a, int b)479   public static int $noinline$AndSubIntoBic_v2(int a, int b) {
480       return b - (a & b);
481   }
482 
main(String[] args)483   public static void main(String[] args) {
484     assertIntEquals(0xe,   $opt$noinline$notAnd(0xf, 0x1));
485     assertLongEquals(~0x0, $opt$noinline$notOr(0xf, 0x1));
486     assertIntEquals(~0xe,  $opt$noinline$notXor(0xf, 0x1));
487     assertIntEquals(0xe,  $opt$noinline$notAndConstant(0x1));
488     assertIntEquals(0xe,   $opt$noinline$notAndMultipleUses(0xf, 0x1));
489     assertIntEquals(~0x1,  $opt$noinline$deMorganOr(0x3, 0x1));
490     assertIntEquals(0x2, $noinline$AndSubIntoBic(0x3, 0x1));
491     assertIntEquals(0x2, $noinline$AndSubIntoBic_v2(0x1, 0x3));
492   }
493 }
494