xref: /aosp_15_r20/art/test/640-checker-integer-valueof/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2017 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   /// CHECK-START: java.lang.Integer Main.foo(int) disassembly (after)
20   /// CHECK: <<Integer:l\d+>>     InvokeStaticOrDirect method_name:java.lang.Integer.valueOf intrinsic:IntegerValueOf
21   /// CHECK:                      pAllocObjectInitialized
22   /// CHECK:                      Return [<<Integer>>]
foo(int a)23   public static Integer foo(int a) {
24     return Integer.valueOf(a);
25   }
26 
27   /// CHECK-START: java.lang.Integer Main.foo2() disassembly (after)
28   /// CHECK: <<Integer:l\d+>>     InvokeStaticOrDirect method_name:java.lang.Integer.valueOf intrinsic:IntegerValueOf
29   /// CHECK-NOT:                  pAllocObjectInitialized
30   /// CHECK:                      Return [<<Integer>>]
foo2()31   public static Integer foo2() {
32     return Integer.valueOf(-42);
33   }
34 
35   /// CHECK-START: java.lang.Integer Main.foo3() disassembly (after)
36   /// CHECK: <<Integer:l\d+>>     InvokeStaticOrDirect method_name:java.lang.Integer.valueOf intrinsic:IntegerValueOf
37   /// CHECK-NOT:                  pAllocObjectInitialized
38   /// CHECK:                      Return [<<Integer>>]
foo3()39   public static Integer foo3() {
40     return Integer.valueOf(42);
41   }
42 
43   /// CHECK-START: java.lang.Integer Main.foo4() disassembly (after)
44   /// CHECK: <<Integer:l\d+>>     InvokeStaticOrDirect method_name:java.lang.Integer.valueOf intrinsic:IntegerValueOf
45   /// CHECK:                      pAllocObjectInitialized
46   /// CHECK:                      Return [<<Integer>>]
foo4()47   public static Integer foo4() {
48     return Integer.valueOf(55555);
49   }
50 
51   /// CHECK-START: byte Main.$noinline$boxUnboxByte(byte) builder (after)
52   /// CHECK: <<Input:b\d+>>       ParameterValue
53   /// CHECK: <<Boxed:l\d+>>       InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
54   /// CHECK-NOT:                  NullCheck [<<Boxed>>]
55   /// CHECK: <<Unboxed:b\d+>>     InvokeVirtual [<<Boxed>>] method_name:java.lang.Byte.byteValue
56   /// CHECK:                      Return [<<Unboxed>>]
57 
58   /// CHECK-START: byte Main.$noinline$boxUnboxByte(byte) inliner (after)
59   /// CHECK: <<Input:b\d+>>       ParameterValue
60   /// CHECK: <<Boxed:l\d+>>       InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
61   /// CHECK: <<Unboxed:b\d+>>     InstanceFieldGet [<<Boxed>>] field_name:java.lang.Byte.value
62   /// CHECK:                      Return [<<Unboxed>>]
63 
64   /// CHECK-START: byte Main.$noinline$boxUnboxByte(byte) instruction_simplifier$after_inlining (after)
65   /// CHECK: <<Input:b\d+>>       ParameterValue
66   /// CHECK:                      Return [<<Input>>]
67 
68   /// CHECK-START: byte Main.$noinline$boxUnboxByte(byte) dead_code_elimination$after_inlining (after)
69   /// CHECK-NOT:                  InvokeStaticOrDirect
70   /// CHECK-NOT:                  InstanceFieldGet
71 
$noinline$boxUnboxByte(byte value)72   public static byte $noinline$boxUnboxByte(byte value) {
73     return Byte.valueOf(value).byteValue();
74   }
75 
76   /// CHECK-START: short Main.$noinline$boxUnboxShort(short) builder (after)
77   /// CHECK: <<Input:s\d+>>       ParameterValue
78   /// CHECK: <<Boxed:l\d+>>       InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Short.valueOf intrinsic:ShortValueOf
79   /// CHECK-NOT:                  NullCheck [<<Boxed>>]
80   /// CHECK: <<Unboxed:s\d+>>     InvokeVirtual [<<Boxed>>] method_name:java.lang.Short.shortValue
81   /// CHECK:                      Return [<<Unboxed>>]
82 
83   /// CHECK-START: short Main.$noinline$boxUnboxShort(short) inliner (after)
84   /// CHECK: <<Input:s\d+>>       ParameterValue
85   /// CHECK: <<Boxed:l\d+>>       InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Short.valueOf intrinsic:ShortValueOf
86   /// CHECK: <<Unboxed:s\d+>>     InstanceFieldGet [<<Boxed>>] field_name:java.lang.Short.value
87   /// CHECK:                      Return [<<Unboxed>>]
88 
89   /// CHECK-START: short Main.$noinline$boxUnboxShort(short) instruction_simplifier$after_inlining (after)
90   /// CHECK: <<Input:s\d+>>       ParameterValue
91   /// CHECK:                      Return [<<Input>>]
92 
93   /// CHECK-START: short Main.$noinline$boxUnboxShort(short) dead_code_elimination$after_inlining (after)
94   /// CHECK-NOT:                  InvokeStaticOrDirect
95   /// CHECK-NOT:                  InstanceFieldGet
96 
$noinline$boxUnboxShort(short value)97   public static short $noinline$boxUnboxShort(short value) {
98     return Short.valueOf(value).shortValue();
99   }
100 
101   /// CHECK-START: char Main.$noinline$boxUnboxCharacter(char) builder (after)
102   /// CHECK: <<Input:c\d+>>       ParameterValue
103   /// CHECK: <<Boxed:l\d+>>       InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Character.valueOf intrinsic:CharacterValueOf
104   /// CHECK-NOT:                  NullCheck [<<Boxed>>]
105   /// CHECK: <<Unboxed:c\d+>>     InvokeVirtual [<<Boxed>>] method_name:java.lang.Character.charValue
106   /// CHECK:                      Return [<<Unboxed>>]
107 
108   /// CHECK-START: char Main.$noinline$boxUnboxCharacter(char) inliner (after)
109   /// CHECK: <<Input:c\d+>>       ParameterValue
110   /// CHECK: <<Boxed:l\d+>>       InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Character.valueOf intrinsic:CharacterValueOf
111   /// CHECK: <<Unboxed:c\d+>>     InstanceFieldGet [<<Boxed>>] field_name:java.lang.Character.value
112   /// CHECK:                      Return [<<Unboxed>>]
113 
114   /// CHECK-START: char Main.$noinline$boxUnboxCharacter(char) instruction_simplifier$after_inlining (after)
115   /// CHECK: <<Input:c\d+>>       ParameterValue
116   /// CHECK:                      Return [<<Input>>]
117 
118   /// CHECK-START: char Main.$noinline$boxUnboxCharacter(char) dead_code_elimination$after_inlining (after)
119   /// CHECK-NOT:                  InvokeStaticOrDirect
120   /// CHECK-NOT:                  InstanceFieldGet
121 
$noinline$boxUnboxCharacter(char value)122   public static char $noinline$boxUnboxCharacter(char value) {
123     return Character.valueOf(value).charValue();
124   }
125 
126   /// CHECK-START: int Main.$noinline$boxUnboxInteger(int) builder (after)
127   /// CHECK: <<Input:i\d+>>       ParameterValue
128   /// CHECK: <<Boxed:l\d+>>       InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Integer.valueOf intrinsic:IntegerValueOf
129   /// CHECK-NOT:                  NullCheck [<<Boxed>>]
130   /// CHECK: <<Unboxed:i\d+>>     InvokeVirtual [<<Boxed>>] method_name:java.lang.Integer.intValue
131   /// CHECK:                      Return [<<Unboxed>>]
132 
133   /// CHECK-START: int Main.$noinline$boxUnboxInteger(int) inliner (after)
134   /// CHECK: <<Input:i\d+>>       ParameterValue
135   /// CHECK: <<Boxed:l\d+>>       InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Integer.valueOf intrinsic:IntegerValueOf
136   /// CHECK: <<Unboxed:i\d+>>     InstanceFieldGet [<<Boxed>>] field_name:java.lang.Integer.value
137   /// CHECK:                      Return [<<Unboxed>>]
138 
139   /// CHECK-START: int Main.$noinline$boxUnboxInteger(int) instruction_simplifier$after_inlining (after)
140   /// CHECK: <<Input:i\d+>>       ParameterValue
141   /// CHECK:                      Return [<<Input>>]
142 
143   /// CHECK-START: int Main.$noinline$boxUnboxInteger(int) dead_code_elimination$after_inlining (after)
144   /// CHECK-NOT:                  InvokeStaticOrDirect
145   /// CHECK-NOT:                  InstanceFieldGet
146 
$noinline$boxUnboxInteger(int value)147   public static int $noinline$boxUnboxInteger(int value) {
148     return Integer.valueOf(value).intValue();
149   }
150 
151   /// CHECK-START: int Main.$noinline$boxUnboxByteAsUint8(byte) builder (after)
152   /// CHECK-DAG: <<Input:b\d+>>   ParameterValue
153   /// CHECK-DAG: <<Boxed:l\d+>>   InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
154   /// CHECK-DAG: <<Phi:l\d+>>     Phi
155   /// CHECK-DAG: <<NC:l\d+>>      NullCheck [<<Phi>>]
156   /// CHECK-DAG: <<Unboxed:b\d+>> InvokeVirtual [<<NC>>] method_name:java.lang.Byte.byteValue
157   /// CHECK-DAG: <<And:i\d+>>     And
158   /// CHECK-DAG:                  Return [<<And>>]
159 
160   /// CHECK-START: int Main.$noinline$boxUnboxByteAsUint8(byte) instruction_simplifier (after)
161   /// CHECK-DAG: <<Input:b\d+>>   ParameterValue
162   /// CHECK-DAG: <<Boxed:l\d+>>   InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
163   /// CHECK-DAG: <<Phi:l\d+>>     Phi
164   /// CHECK-DAG: <<NC:l\d+>>      NullCheck [<<Phi>>]
165   /// CHECK-DAG: <<Unboxed:b\d+>> InvokeVirtual [<<NC>>] method_name:java.lang.Byte.byteValue
166   /// CHECK-DAG: <<Conv:a\d+>>    TypeConversion [<<Unboxed>>]
167   /// CHECK-DAG:                  Return [<<Conv>>]
168 
169   /// CHECK-START: int Main.$noinline$boxUnboxByteAsUint8(byte) inliner (after)
170   /// CHECK-DAG: <<Input:b\d+>>   ParameterValue
171   /// CHECK-DAG: <<Boxed:l\d+>>   InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
172   /// CHECK-DAG: <<Phi:l\d+>>     Phi
173   /// CHECK-DAG: <<NC:l\d+>>      NullCheck [<<Phi>>]
174   /// CHECK-DAG: <<Unboxed:b\d+>> InstanceFieldGet [<<NC>>] field_name:java.lang.Byte.value
175   /// CHECK-DAG: <<Conv:a\d+>>    TypeConversion [<<Unboxed>>]
176   /// CHECK-DAG:                  Return [<<Conv>>]
177 
178   /// CHECK-START: int Main.$noinline$boxUnboxByteAsUint8(byte) instruction_simplifier$after_inlining (after)
179   /// CHECK-DAG: <<Input:b\d+>>   ParameterValue
180   /// CHECK-DAG: <<Boxed:l\d+>>   InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
181   /// CHECK-DAG: <<Phi:l\d+>>     Phi
182   /// CHECK-DAG: <<NC:l\d+>>      NullCheck [<<Phi>>]
183   /// CHECK-DAG: <<Conv:a\d+>>    InstanceFieldGet [<<NC>>] field_name:java.lang.Byte.value
184   /// CHECK-DAG:                  Return [<<Conv>>]
185 
186   /// CHECK-START: int Main.$noinline$boxUnboxByteAsUint8(byte) dead_code_elimination$after_inlining (after)
187   /// CHECK-DAG: <<Input:b\d+>>   ParameterValue
188   /// CHECK-DAG: <<Boxed:l\d+>>   InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
189   /// CHECK-DAG: <<NC:l\d+>>      NullCheck [<<Boxed>>]
190   /// CHECK-DAG: <<Conv:a\d+>>    InstanceFieldGet [<<NC>>] field_name:java.lang.Byte.value
191   /// CHECK-DAG:                  Return [<<Conv>>]
192 
193   /// CHECK-START: int Main.$noinline$boxUnboxByteAsUint8(byte) instruction_simplifier$after_gvn (after)
194   /// CHECK-DAG: <<Input:b\d+>>   ParameterValue
195   /// CHECK-DAG: <<Boxed:l\d+>>   InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
196   /// CHECK-DAG: <<Conv:a\d+>>    InstanceFieldGet [<<Boxed>>] field_name:java.lang.Byte.value
197   /// CHECK-DAG:                  Return [<<Conv>>]
198 
199   /// CHECK-START: int Main.$noinline$boxUnboxByteAsUint8(byte) disassembly (after)
200   /// CHECK-DAG: <<Input:b\d+>>   ParameterValue
201   /// CHECK-DAG: <<Boxed:l\d+>>   InvokeStaticOrDirect [<<Input>>{{(,[ij]\d+)?}}] method_name:java.lang.Byte.valueOf intrinsic:ByteValueOf
202   /// CHECK-DAG: <<Conv:a\d+>>    InstanceFieldGet [<<Boxed>>] field_name:java.lang.Byte.value
203   /// CHECK-DAG:                  Return [<<Conv>>]
204 
$noinline$boxUnboxByteAsUint8(byte value)205   public static int $noinline$boxUnboxByteAsUint8(byte value) {
206     Byte boxed = Byte.valueOf(value);
207 
208     // Hide the unboxing from the initial instruction simplifier pass or the one after inlining,
209     // so that after inlining we can merge the `TypeConversion` into `InstanceFieldGet` with
210     // a modified type. The Phi shall be eliminated by `dead_code_elimination$after_inlining`.
211     // The null check that shall be eliminated by `instruction_simplifier$after_gvn (after)`
212     Byte merged = $inline$returnTrue() ? boxed : null;
213 
214     // Due to the type mismatch, we shall not simplify the unboxing. The boxing and unboxing
215     // shall be kept during subsequent simplifier passes all the way to the disassembly.
216     return merged.byteValue() & 0xff;
217   }
218 
$inline$returnTrue()219   public static boolean $inline$returnTrue() {
220     return true;
221   }
222 
main(String[] args)223   public static void main(String[] args) {
224     assertEqual("42", foo(intField));
225     assertEqual(foo(intField), foo(intField2));
226     assertEqual("-42", foo2());
227     assertEqual("42", foo3());
228     assertEqual("55555", foo4());
229     assertEqual("55555", foo(intField3));
230     assertEqual("-129", foo(intFieldMinus129));
231     assertEqual("-128", foo(intFieldMinus128));
232     assertEqual(foo(intFieldMinus128), foo(intFieldMinus128));
233     assertEqual("-127", foo(intFieldMinus127));
234     assertEqual(foo(intFieldMinus127), foo(intFieldMinus127));
235     assertEqual("126", foo(intField126));
236     assertEqual(foo(intField126), foo(intField126));
237     assertEqual("127", foo(intField127));
238     assertEqual(foo(intField127), foo(intField127));
239     assertEqual("128", foo(intField128));
240 
241     assertEqual(42, (int) $noinline$boxUnboxByte((byte) 42));
242     assertEqual(-42, (int) $noinline$boxUnboxByte((byte) -42));
243     assertEqual(42, (int) $noinline$boxUnboxShort((short) 42));
244     assertEqual(-42, (int) $noinline$boxUnboxShort((short) -42));
245     assertEqual((int) (char) 42, (int) $noinline$boxUnboxCharacter((char) 42));
246     assertEqual((int) (char) -42, (int) $noinline$boxUnboxCharacter((char) -42));
247     assertEqual(42, $noinline$boxUnboxInteger(42));
248     assertEqual(-42, $noinline$boxUnboxInteger(-42));
249 
250     assertEqual(42, $noinline$boxUnboxByteAsUint8((byte) 42));
251     assertEqual(-42 & 0xff, $noinline$boxUnboxByteAsUint8((byte) -42));
252   }
253 
assertEqual(String a, Integer b)254   static void assertEqual(String a, Integer b) {
255     if (!a.equals(b.toString())) {
256       throw new Error("Expected " + a + ", got " + b);
257     }
258   }
259 
assertEqual(Integer a, Integer b)260   static void assertEqual(Integer a, Integer b) {
261     if (a != b) {
262       throw new Error("Expected " + a + ", got " + b);
263     }
264   }
265 
assertEqual(int a, int b)266   static void assertEqual(int a, int b) {
267     if (a != b) {
268       throw new Error("Expected " + a + ", got " + b);
269     }
270   }
271 
272   static int intField = 42;
273   static int intField2 = 42;
274   static int intField3 = 55555;
275 
276   // Edge cases.
277   static int intFieldMinus129 = -129;
278   static int intFieldMinus128 = -128;
279   static int intFieldMinus127 = -127;
280   static int intField126 = 126;
281   static int intField127 = 127;
282   static int intField128 = 128;
283 }
284