xref: /aosp_15_r20/art/test/859-checker-var-handles-intrinsics/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1 /*
2  * Copyright (C) 2024 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 import java.lang.invoke.MethodHandles;
17 import java.lang.invoke.VarHandle;
18 
19 public class Main {
main(String[] args)20     public static void main(String[] args) {
21         // Since the tests will share a value, we have the condition that the value starts
22         // and ends as 0 before and after each test.
23 
24         // Int tests
25         $noinline$testGetAndAdd_Int();
26         $noinline$testGetAndSet_Int();
27         $noinline$testGetAndBitwiseAnd_Int();
28         $noinline$testGetAndBitwiseOr_Int();
29         $noinline$testGetAndBitwiseXor_Int();
30 
31         // Long tests
32         $noinline$testGetAndAdd_Long();
33         $noinline$testGetAndSet_Long();
34         $noinline$testGetAndBitwiseAnd_Long();
35         $noinline$testGetAndBitwiseOr_Long();
36         $noinline$testGetAndBitwiseXor_Long();
37 
38         // Float tests
39         $noinline$testGetAndAdd_Float();
40         $noinline$testGetAndSet_Float();
41 
42         // Double tests
43         $noinline$testGetAndAdd_Double();
44         $noinline$testGetAndSet_Double();
45     }
46 
$noinline$testGetAndAdd_Int()47     private static void $noinline$testGetAndAdd_Int() {
48         Main m = new Main();
49         // 0 + 100 = 100
50         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
51         m.$noinline$getAndAdd_Int(100);
52         $noinline$assertIntEquals(100, (int) INT_VALUE.get(m));
53 
54         // 100 - 100 = 0
55         m.$noinline$getAndAdd_Int(-100);
56         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
57     }
58 
$noinline$testGetAndSet_Int()59     private static void $noinline$testGetAndSet_Int() {
60         Main m = new Main();
61         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
62         m.$noinline$getAndSet_Int(100);
63         $noinline$assertIntEquals(100, (int) INT_VALUE.get(m));
64 
65         m.$noinline$getAndSet_Int(-100);
66         $noinline$assertIntEquals(-100, (int) INT_VALUE.get(m));
67 
68         m.$noinline$getAndSet_Int(0);
69         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
70     }
71 
$noinline$testGetAndBitwiseAnd_Int()72     private static void $noinline$testGetAndBitwiseAnd_Int() {
73         Main m = new Main();
74         // 0 AND X = 0
75         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
76         m.$noinline$getAndBitwiseAnd_Int(100);
77         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
78 
79         // 10101010 AND
80         // 11001100 =
81         // 10001000
82         m.$noinline$getAndSet_Int(0b10101010);
83         m.$noinline$getAndBitwiseAnd_Int(0b11001100);
84         $noinline$assertIntEquals(0b10001000, (int) INT_VALUE.get(m));
85 
86         // 10001000 AND
87         // 11111111 =
88         // 10001000
89         m.$noinline$getAndBitwiseAnd_Int(0b11111111);
90         $noinline$assertIntEquals(0b10001000, (int) INT_VALUE.get(m));
91 
92         // 10001000 AND
93         // 01110111 =
94         // 0
95         m.$noinline$getAndBitwiseAnd_Int(0b01110111);
96         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
97     }
98 
$noinline$testGetAndBitwiseOr_Int()99     private static void $noinline$testGetAndBitwiseOr_Int() {
100         Main m = new Main();
101 
102         // 0 OR X = X
103         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
104         m.$noinline$getAndBitwiseOr_Int(0b10101010);
105         $noinline$assertIntEquals(0b10101010, (int) INT_VALUE.get(m));
106 
107         // 10101010 OR
108         // 01010101 =
109         // 11111111
110         m.$noinline$getAndBitwiseOr_Int(0b01010101);
111         $noinline$assertIntEquals(0b11111111, (int) INT_VALUE.get(m));
112 
113         // 11111111 OR
114         // 0 =
115         // 11111111
116         m.$noinline$getAndBitwiseOr_Int(0);
117         $noinline$assertIntEquals(0b11111111, (int) INT_VALUE.get(m));
118 
119         // Set to 0 due to precondition. See comment in main.
120         m.$noinline$getAndSet_Int(0);
121         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
122     }
123 
$noinline$testGetAndBitwiseXor_Int()124     private static void $noinline$testGetAndBitwiseXor_Int() {
125         Main m = new Main();
126 
127         // 0 XOR X = X
128         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
129         m.$noinline$getAndBitwiseXor_Int(0b10101010);
130         $noinline$assertIntEquals(0b10101010, (int) INT_VALUE.get(m));
131 
132         // 10101010 XOR
133         // 01010101 =
134         // 11111111
135         m.$noinline$getAndBitwiseXor_Int(0b01010101);
136         $noinline$assertIntEquals(0b11111111, (int) INT_VALUE.get(m));
137 
138         // 11111111 XOR
139         // 01010101 =
140         // 10101010
141         m.$noinline$getAndBitwiseXor_Int(0b01010101);
142         $noinline$assertIntEquals(0b10101010, (int) INT_VALUE.get(m));
143 
144         // X XOR X = 0
145         m.$noinline$getAndBitwiseXor_Int(0b10101010);
146         $noinline$assertIntEquals(0, (int) INT_VALUE.get(m));
147     }
148 
$noinline$testGetAndAdd_Long()149     private static void $noinline$testGetAndAdd_Long() {
150         Main m = new Main();
151         // 0 + 100 = 100
152         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
153         m.$noinline$getAndAdd_Long(100);
154         $noinline$assertLongEquals(100L, (long) LONG_VALUE.get(m));
155 
156         // 100 - 100 = 0
157         m.$noinline$getAndAdd_Long(-100);
158         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
159     }
160 
$noinline$testGetAndSet_Long()161     private static void $noinline$testGetAndSet_Long() {
162         Main m = new Main();
163         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
164         m.$noinline$getAndSet_Long(100);
165         $noinline$assertLongEquals(100L, (long) LONG_VALUE.get(m));
166 
167         m.$noinline$getAndSet_Long(-100);
168         $noinline$assertLongEquals(-100L, (long) LONG_VALUE.get(m));
169 
170         m.$noinline$getAndSet_Long(0);
171         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
172     }
173 
$noinline$testGetAndBitwiseAnd_Long()174     private static void $noinline$testGetAndBitwiseAnd_Long() {
175         Main m = new Main();
176         // 0 AND X = 0
177         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
178         m.$noinline$getAndBitwiseAnd_Long(100);
179         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
180 
181         // 10101010 AND
182         // 11001100 =
183         // 10001000
184         m.$noinline$getAndSet_Long(0b10101010);
185         m.$noinline$getAndBitwiseAnd_Long(0b11001100);
186         $noinline$assertLongEquals(0b10001000L, (long) LONG_VALUE.get(m));
187 
188         // 10001000 AND
189         // 11111111 =
190         // 10001000
191         m.$noinline$getAndBitwiseAnd_Long(0b11111111);
192         $noinline$assertLongEquals(0b10001000L, (long) LONG_VALUE.get(m));
193 
194         // 10001000 AND
195         // 01110111 =
196         // 0
197         m.$noinline$getAndBitwiseAnd_Long(0b01110111);
198         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
199     }
200 
$noinline$testGetAndBitwiseOr_Long()201     private static void $noinline$testGetAndBitwiseOr_Long() {
202         Main m = new Main();
203 
204         // 0 OR X = X
205         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
206         m.$noinline$getAndBitwiseOr_Long(0b10101010);
207         $noinline$assertLongEquals(0b10101010L, (long) LONG_VALUE.get(m));
208 
209         // 10101010 OR
210         // 01010101 =
211         // 11111111
212         m.$noinline$getAndBitwiseOr_Long(0b01010101);
213         $noinline$assertLongEquals(0b11111111L, (long) LONG_VALUE.get(m));
214 
215         // 11111111 OR
216         // 0 =
217         // 11111111
218         m.$noinline$getAndBitwiseOr_Long(0);
219         $noinline$assertLongEquals(0b11111111L, (long) LONG_VALUE.get(m));
220 
221         // Set to 0 due to precondition. See comment in main.
222         m.$noinline$getAndSet_Long(0);
223         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
224     }
225 
$noinline$testGetAndBitwiseXor_Long()226     private static void $noinline$testGetAndBitwiseXor_Long() {
227         Main m = new Main();
228 
229         // 0 XOR X = X
230         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
231         m.$noinline$getAndBitwiseXor_Long(0b10101010);
232         $noinline$assertLongEquals(0b10101010L, (long) LONG_VALUE.get(m));
233 
234         // 10101010 XOR
235         // 01010101 =
236         // 11111111
237         m.$noinline$getAndBitwiseXor_Long(0b01010101);
238         $noinline$assertLongEquals(0b11111111L, (long) LONG_VALUE.get(m));
239 
240         // 11111111 XOR
241         // 01010101 =
242         // 10101010
243         m.$noinline$getAndBitwiseXor_Long(0b01010101);
244         $noinline$assertLongEquals(0b10101010L, (long) LONG_VALUE.get(m));
245 
246         // X XOR X = 0
247         m.$noinline$getAndBitwiseXor_Long(0b10101010);
248         $noinline$assertLongEquals(0L, (long) LONG_VALUE.get(m));
249     }
250 
$noinline$testGetAndAdd_Float()251     private static void $noinline$testGetAndAdd_Float() {
252         Main m = new Main();
253         // 0 + 100 = 100
254         $noinline$assertFloatEquals(0.0f, (float) FLOAT_VALUE.get(m));
255         m.$noinline$getAndAdd_Float(100.0f);
256         $noinline$assertFloatEquals(100.0f, (float) FLOAT_VALUE.get(m));
257 
258         // 100 - 100 = 0
259         m.$noinline$getAndAdd_Float(-100.0f);
260         $noinline$assertFloatEquals(0.0f, (float) FLOAT_VALUE.get(m));
261     }
262 
$noinline$testGetAndSet_Float()263     private static void $noinline$testGetAndSet_Float() {
264         Main m = new Main();
265         $noinline$assertFloatEquals(0.0f, (float) FLOAT_VALUE.get(m));
266         m.$noinline$getAndSet_Float(100.0f);
267         $noinline$assertFloatEquals(100.0f, (float) FLOAT_VALUE.get(m));
268 
269         m.$noinline$getAndSet_Float(-100.0f);
270         $noinline$assertFloatEquals(-100.0f, (float) FLOAT_VALUE.get(m));
271 
272         m.$noinline$getAndSet_Float(0.0f);
273         $noinline$assertFloatEquals(0.0f, (float) FLOAT_VALUE.get(m));
274     }
275 
$noinline$testGetAndAdd_Double()276     private static void $noinline$testGetAndAdd_Double() {
277         Main m = new Main();
278         // 0 + 100 = 100
279         $noinline$assertDoubleEquals(0.0d, (double) DOUBLE_VALUE.get(m));
280         m.$noinline$getAndAdd_Double(100.0d);
281         $noinline$assertDoubleEquals(100.0d, (double) DOUBLE_VALUE.get(m));
282 
283         // 100 - 100 = 0
284         m.$noinline$getAndAdd_Double(-100.0d);
285         $noinline$assertDoubleEquals(0.0d, (double) DOUBLE_VALUE.get(m));
286     }
287 
$noinline$testGetAndSet_Double()288     private static void $noinline$testGetAndSet_Double() {
289         Main m = new Main();
290         $noinline$assertDoubleEquals(0.0d, (double) DOUBLE_VALUE.get(m));
291         m.$noinline$getAndSet_Double(100.0d);
292         $noinline$assertDoubleEquals(100.0d, (double) DOUBLE_VALUE.get(m));
293 
294         m.$noinline$getAndSet_Double(-100.0d);
295         $noinline$assertDoubleEquals(-100.0d, (double) DOUBLE_VALUE.get(m));
296 
297         m.$noinline$getAndSet_Double(0.0d);
298         $noinline$assertDoubleEquals(0.0d, (double) DOUBLE_VALUE.get(m));
299     }
300 
301     // VarHandles
302     private volatile int int_value = 0;
303     private static final VarHandle INT_VALUE;
304     static {
305         try {
306             MethodHandles.Lookup l = MethodHandles.lookup();
307             INT_VALUE = l.findVarHandle(Main.class, "int_value", int.class);
308         } catch (ReflectiveOperationException e) {
309             throw new ExceptionInInitializerError(e);
310         }
311     }
312 
313     private volatile long long_value = 0L;
314     private static final VarHandle LONG_VALUE;
315     static {
316         try {
317             MethodHandles.Lookup l = MethodHandles.lookup();
318             LONG_VALUE = l.findVarHandle(Main.class, "long_value", long.class);
319         } catch (ReflectiveOperationException e) {
320             throw new ExceptionInInitializerError(e);
321         }
322     }
323 
324     private volatile float float_value = 0.0f;
325     private static final VarHandle FLOAT_VALUE;
326     static {
327         try {
328             MethodHandles.Lookup l = MethodHandles.lookup();
329             FLOAT_VALUE = l.findVarHandle(Main.class, "float_value", float.class);
330         } catch (ReflectiveOperationException e) {
331             throw new ExceptionInInitializerError(e);
332         }
333     }
334 
335     private volatile double double_value = 0.0d;
336     private static final VarHandle DOUBLE_VALUE;
337     static {
338         try {
339             MethodHandles.Lookup l = MethodHandles.lookup();
340             DOUBLE_VALUE = l.findVarHandle(Main.class, "double_value", double.class);
341         } catch (ReflectiveOperationException e) {
342             throw new ExceptionInInitializerError(e);
343         }
344     }
345 
346     // Check that we successfully intrinsify intrinsics (e.g. getAndAdd) by checking that there's no
347     // call to the runtime.
348 
349     /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndAdd_Int(int) disassembly (after)
350     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
351     /// CHECK-NOT: call
352     /// CHECK:     ReturnVoid
353 
354     /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Int(int) disassembly (after)
355     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
356     /// CHECK-NOT: blx
357     /// CHECK:     ReturnVoid
358 
359     /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Int(int) disassembly (after)
360     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
361     /// CHECK-NOT: blr
362     /// CHECK:     ReturnVoid
363 
364     /// CHECK-START-RISCV64: void Main.$noinline$getAndAdd_Int(int) disassembly (after)
365     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
366     /// CHECK-NOT: jalr
367     /// CHECK:     ReturnVoid
$noinline$getAndAdd_Int(int value)368     private void $noinline$getAndAdd_Int(int value) {
369         INT_VALUE.getAndAdd(this, value);
370     }
371 
372     /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndSet_Int(int) disassembly (after)
373     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
374     /// CHECK-NOT: call
375     /// CHECK:     ReturnVoid
376 
377     /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Int(int) disassembly (after)
378     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
379     /// CHECK-NOT: blx
380     /// CHECK:     ReturnVoid
381 
382     /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Int(int) disassembly (after)
383     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
384     /// CHECK-NOT: blr
385     /// CHECK:     ReturnVoid
386 
387     /// CHECK-START-RISCV64: void Main.$noinline$getAndSet_Int(int) disassembly (after)
388     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
389     /// CHECK-NOT: jalr
390     /// CHECK:     ReturnVoid
$noinline$getAndSet_Int(int value)391     private void $noinline$getAndSet_Int(int value) {
392         INT_VALUE.getAndSet(this, value);
393     }
394 
395     /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndBitwiseAnd_Int(int) disassembly (after)
396     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
397     /// CHECK-NOT: call
398     /// CHECK:     ReturnVoid
399 
400     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseAnd_Int(int) disassembly (after)
401     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
402     /// CHECK-NOT: blx
403     /// CHECK:     ReturnVoid
404 
405     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseAnd_Int(int) disassembly (after)
406     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
407     /// CHECK-NOT: blr
408     /// CHECK:     ReturnVoid
409 
410     /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseAnd_Int(int) disassembly (after)
411     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
412     /// CHECK-NOT: jalr
413     /// CHECK:     ReturnVoid
$noinline$getAndBitwiseAnd_Int(int value)414     private void $noinline$getAndBitwiseAnd_Int(int value) {
415         INT_VALUE.getAndBitwiseAnd(this, value);
416     }
417 
418     /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndBitwiseOr_Int(int) disassembly (after)
419     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
420     /// CHECK-NOT: call
421     /// CHECK:     ReturnVoid
422 
423     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseOr_Int(int) disassembly (after)
424     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
425     /// CHECK-NOT: blx
426     /// CHECK:     ReturnVoid
427 
428     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseOr_Int(int) disassembly (after)
429     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
430     /// CHECK-NOT: blr
431     /// CHECK:     ReturnVoid
432 
433     /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseOr_Int(int) disassembly (after)
434     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
435     /// CHECK-NOT: jalr
436     /// CHECK:     ReturnVoid
$noinline$getAndBitwiseOr_Int(int value)437     private void $noinline$getAndBitwiseOr_Int(int value) {
438         INT_VALUE.getAndBitwiseOr(this, value);
439     }
440 
441     /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndBitwiseXor_Int(int) disassembly (after)
442     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
443     /// CHECK-NOT: call
444     /// CHECK:     ReturnVoid
445 
446     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseXor_Int(int) disassembly (after)
447     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
448     /// CHECK-NOT: blx
449     /// CHECK:     ReturnVoid
450 
451     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseXor_Int(int) disassembly (after)
452     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
453     /// CHECK-NOT: blr
454     /// CHECK:     ReturnVoid
455 
456     /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseXor_Int(int) disassembly (after)
457     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
458     /// CHECK-NOT: jalr
459     /// CHECK:     ReturnVoid
$noinline$getAndBitwiseXor_Int(int value)460     private void $noinline$getAndBitwiseXor_Int(int value) {
461         INT_VALUE.getAndBitwiseXor(this, value);
462     }
463 
$noinline$assertIntEquals(int expected, int result)464     private static void $noinline$assertIntEquals(int expected, int result) {
465         if (expected != result) {
466             throw new Error("Expected: " + expected + ", found: " + result);
467         }
468     }
469 
470     // Note that the Long ones do a call for X86.
471     // TODO(solanes): Add this support.
472 
473     /// CHECK-START-X86: void Main.$noinline$getAndAdd_Long(long) disassembly (after)
474     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
475     /// CHECK:     call
476     /// CHECK:     ReturnVoid
477 
478     /// CHECK-START-X86_64: void Main.$noinline$getAndAdd_Long(long) disassembly (after)
479     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
480     /// CHECK-NOT: call
481     /// CHECK:     ReturnVoid
482 
483     /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Long(long) disassembly (after)
484     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
485     /// CHECK-NOT: blx
486     /// CHECK:     ReturnVoid
487 
488     /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Long(long) disassembly (after)
489     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
490     /// CHECK-NOT: blr
491     /// CHECK:     ReturnVoid
492 
493     /// CHECK-START-RISCV64: void Main.$noinline$getAndAdd_Long(long) disassembly (after)
494     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
495     /// CHECK-NOT: jalr
496     /// CHECK:     ReturnVoid
$noinline$getAndAdd_Long(long value)497     private void $noinline$getAndAdd_Long(long value) {
498         LONG_VALUE.getAndAdd(this, value);
499     }
500 
501     /// CHECK-START-X86: void Main.$noinline$getAndSet_Long(long) disassembly (after)
502     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
503     /// CHECK:     call
504     /// CHECK:     ReturnVoid
505 
506     /// CHECK-START-X86_64: void Main.$noinline$getAndSet_Long(long) disassembly (after)
507     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
508     /// CHECK-NOT: call
509     /// CHECK:     ReturnVoid
510 
511     /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Long(long) disassembly (after)
512     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
513     /// CHECK-NOT: blx
514     /// CHECK:     ReturnVoid
515 
516     /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Long(long) disassembly (after)
517     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
518     /// CHECK-NOT: blr
519     /// CHECK:     ReturnVoid
520 
521     /// CHECK-START-RISCV64: void Main.$noinline$getAndSet_Long(long) disassembly (after)
522     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
523     /// CHECK-NOT: jalr
524     /// CHECK:     ReturnVoid
$noinline$getAndSet_Long(long value)525     private void $noinline$getAndSet_Long(long value) {
526         LONG_VALUE.getAndSet(this, value);
527     }
528 
529     /// CHECK-START-X86: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after)
530     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
531     /// CHECK:     call
532     /// CHECK:     ReturnVoid
533 
534     /// CHECK-START-X86_64: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after)
535     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
536     /// CHECK-NOT: call
537     /// CHECK:     ReturnVoid
538 
539     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after)
540     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
541     /// CHECK-NOT: blx
542     /// CHECK:     ReturnVoid
543 
544     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after)
545     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
546     /// CHECK-NOT: blr
547     /// CHECK:     ReturnVoid
548 
549     /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseAnd_Long(long) disassembly (after)
550     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseAnd
551     /// CHECK-NOT: jalr
552     /// CHECK:     ReturnVoid
$noinline$getAndBitwiseAnd_Long(long value)553     private void $noinline$getAndBitwiseAnd_Long(long value) {
554         LONG_VALUE.getAndBitwiseAnd(this, value);
555     }
556 
557     /// CHECK-START-X86: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after)
558     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
559     /// CHECK:     call
560     /// CHECK:     ReturnVoid
561 
562     /// CHECK-START-X86_64: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after)
563     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
564     /// CHECK-NOT: call
565     /// CHECK:     ReturnVoid
566 
567     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after)
568     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
569     /// CHECK-NOT: blx
570     /// CHECK:     ReturnVoid
571 
572     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after)
573     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
574     /// CHECK-NOT: blr
575     /// CHECK:     ReturnVoid
576 
577     /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseOr_Long(long) disassembly (after)
578     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseOr
579     /// CHECK-NOT: jalr
580     /// CHECK:     ReturnVoid
$noinline$getAndBitwiseOr_Long(long value)581     private void $noinline$getAndBitwiseOr_Long(long value) {
582         LONG_VALUE.getAndBitwiseOr(this, value);
583     }
584 
585     /// CHECK-START-X86: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after)
586     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
587     /// CHECK:     call
588     /// CHECK:     ReturnVoid
589 
590     /// CHECK-START-X86_64: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after)
591     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
592     /// CHECK-NOT: call
593     /// CHECK:     ReturnVoid
594 
595     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after)
596     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
597     /// CHECK-NOT: blx
598     /// CHECK:     ReturnVoid
599 
600     /// CHECK-START-ARM64: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after)
601     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
602     /// CHECK-NOT: blr
603     /// CHECK:     ReturnVoid
604 
605     /// CHECK-START-RISCV64: void Main.$noinline$getAndBitwiseXor_Long(long) disassembly (after)
606     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndBitwiseXor
607     /// CHECK-NOT: jalr
608     /// CHECK:     ReturnVoid
$noinline$getAndBitwiseXor_Long(long value)609     private void $noinline$getAndBitwiseXor_Long(long value) {
610         LONG_VALUE.getAndBitwiseXor(this, value);
611     }
612 
$noinline$assertLongEquals(long expected, long result)613     private static void $noinline$assertLongEquals(long expected, long result) {
614         if (expected != result) {
615             throw new Error("Expected: " + expected + ", found: " + result);
616         }
617     }
618 
619     /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndAdd_Float(float) disassembly (after)
620     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
621     /// CHECK-NOT: call
622     /// CHECK:     ReturnVoid
623 
624     /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Float(float) disassembly (after)
625     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
626     /// CHECK-NOT: blx
627     /// CHECK:     ReturnVoid
628 
629     /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Float(float) disassembly (after)
630     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
631     /// CHECK-NOT: blr
632     /// CHECK:     ReturnVoid
633 
634     /// CHECK-START-RISCV64: void Main.$noinline$getAndAdd_Float(float) disassembly (after)
635     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
636     /// CHECK-NOT: jalr
637     /// CHECK:     ReturnVoid
$noinline$getAndAdd_Float(float value)638     private void $noinline$getAndAdd_Float(float value) {
639         FLOAT_VALUE.getAndAdd(this, value);
640     }
641 
642     /// CHECK-START-{X86,X86_64}: void Main.$noinline$getAndSet_Float(float) disassembly (after)
643     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
644     /// CHECK-NOT: call
645     /// CHECK:     ReturnVoid
646 
647     /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Float(float) disassembly (after)
648     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
649     /// CHECK-NOT: blx
650     /// CHECK:     ReturnVoid
651 
652     /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Float(float) disassembly (after)
653     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
654     /// CHECK-NOT: blr
655     /// CHECK:     ReturnVoid
656 
657     /// CHECK-START-RISCV64: void Main.$noinline$getAndSet_Float(float) disassembly (after)
658     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
659     /// CHECK-NOT: jalr
660     /// CHECK:     ReturnVoid
$noinline$getAndSet_Float(float value)661     private void $noinline$getAndSet_Float(float value) {
662         FLOAT_VALUE.getAndSet(this, value);
663     }
664 
$noinline$assertFloatEquals(float expected, float result)665     private static void $noinline$assertFloatEquals(float expected, float result) {
666         if (expected != result) {
667             throw new Error("Expected: " + expected + ", found: " + result);
668         }
669     }
670 
671     // Note that the Double ones do a call for X86.
672     // TODO(solanes): Add this support.
673 
674     /// CHECK-START-X86: void Main.$noinline$getAndAdd_Double(double) disassembly (after)
675     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
676     /// CHECK:     call
677     /// CHECK:     ReturnVoid
678 
679     /// CHECK-START-X86_64: void Main.$noinline$getAndAdd_Double(double) disassembly (after)
680     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
681     /// CHECK-NOT: call
682     /// CHECK:     ReturnVoid
683 
684     /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Double(double) disassembly (after)
685     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
686     /// CHECK-NOT: blx
687     /// CHECK:     ReturnVoid
688 
689     /// CHECK-START-ARM64: void Main.$noinline$getAndAdd_Double(double) disassembly (after)
690     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
691     /// CHECK-NOT: blr
692     /// CHECK:     ReturnVoid
693 
694     /// CHECK-START-RISCV64: void Main.$noinline$getAndAdd_Double(double) disassembly (after)
695     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndAdd
696     /// CHECK-NOT: jalr
697     /// CHECK:     ReturnVoid
$noinline$getAndAdd_Double(double value)698     private void $noinline$getAndAdd_Double(double value) {
699         DOUBLE_VALUE.getAndAdd(this, value);
700     }
701 
702     /// CHECK-START-X86: void Main.$noinline$getAndSet_Double(double) disassembly (after)
703     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
704     /// CHECK:     call
705     /// CHECK:     ReturnVoid
706 
707     /// CHECK-START-X86_64: void Main.$noinline$getAndSet_Double(double) disassembly (after)
708     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
709     /// CHECK-NOT: call
710     /// CHECK:     ReturnVoid
711 
712     /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Double(double) disassembly (after)
713     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
714     /// CHECK-NOT: blx
715     /// CHECK:     ReturnVoid
716 
717     /// CHECK-START-ARM64: void Main.$noinline$getAndSet_Double(double) disassembly (after)
718     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
719     /// CHECK-NOT: blr
720     /// CHECK:     ReturnVoid
721 
722     /// CHECK-START-RISCV64: void Main.$noinline$getAndSet_Double(double) disassembly (after)
723     /// CHECK:     InvokePolymorphic intrinsic:VarHandleGetAndSet
724     /// CHECK-NOT: jalr
725     /// CHECK:     ReturnVoid
$noinline$getAndSet_Double(double value)726     private void $noinline$getAndSet_Double(double value) {
727         DOUBLE_VALUE.getAndSet(this, value);
728     }
729 
$noinline$assertDoubleEquals(double expected, double result)730     private static void $noinline$assertDoubleEquals(double expected, double result) {
731         if (expected != result) {
732             throw new Error("Expected: " + expected + ", found: " + result);
733         }
734     }
735 }
736