1 /*
   2  * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package compiler.valhalla.inlinetypes;
  25 
  26 import compiler.lib.ir_framework.*;
  27 import jdk.test.lib.Asserts;
  28 import jdk.experimental.bytecode.TypeTag;
  29 import test.java.lang.invoke.lib.OldInstructionHelper;
  30 
  31 import java.util.Objects;
  32 
  33 import java.lang.invoke.MethodHandle;
  34 import java.lang.invoke.MethodHandles;
  35 import java.lang.invoke.MethodType;
  36 import java.lang.reflect.Method;
  37 
  38 import jdk.internal.value.ValueClass;
  39 import jdk.internal.vm.annotation.ImplicitlyConstructible;
  40 import jdk.internal.vm.annotation.LooselyConsistentValue;
  41 import jdk.internal.vm.annotation.NullRestricted;
  42 
  43 import static compiler.valhalla.inlinetypes.InlineTypeIRNode.*;
  44 import static compiler.valhalla.inlinetypes.InlineTypes.*;
  45 
  46 /*
  47  * @test
  48  * @key randomness
  49  * @summary Test correct handling of nullable value classes.
  50  * @library /test/lib /test/jdk/lib/testlibrary/bytecode /test/jdk/java/lang/invoke/common /
  51  * @requires (os.simpleArch == "x64" | os.simpleArch == "aarch64")
  52  * @enablePreview
  53  * @modules java.base/jdk.internal.value
  54  *          java.base/jdk.internal.vm.annotation
  55  * @build jdk.experimental.bytecode.BasicClassBuilder test.java.lang.invoke.lib.OldInstructionHelper
  56  * @run main/othervm/timeout=300 compiler.valhalla.inlinetypes.TestNullableInlineTypes
  57  */
  58 
  59 @ForceCompileClassInitializer
  60 public class TestNullableInlineTypes {
  61 
  62     public static void main(String[] args) {
  63 
  64         Scenario[] scenarios = InlineTypes.DEFAULT_SCENARIOS;
  65         scenarios[3].addFlags("-XX:-MonomorphicArrayCheck", "-XX:FlatArrayElementMaxSize=-1");
  66         scenarios[4].addFlags("-XX:-MonomorphicArrayCheck");
  67 
  68         InlineTypes.getFramework()
  69                    .addScenarios(scenarios)
  70                    .addHelperClasses(MyValue1.class,
  71                                      MyValue2.class,
  72                                      MyValue2Inline.class,
  73                                      MyValue3.class,
  74                                      MyValue3Inline.class)
  75                    .start();
  76     }
  77 
  78     static {
  79         // Make sure RuntimeException is loaded to prevent uncommon traps in IR verified tests
  80         RuntimeException tmp = new RuntimeException("42");
  81         try {
  82             Class<?> clazz = TestNullableInlineTypes.class;
  83             MethodHandles.Lookup lookup = MethodHandles.lookup();
  84 
  85             MethodType test18_mt = MethodType.methodType(void.class, MyValue1.class);
  86             test18_mh1 = lookup.findStatic(clazz, "test18_target1", test18_mt);
  87             test18_mh2 = lookup.findStatic(clazz, "test18_target2", test18_mt);
  88 
  89             MethodType test19_mt = MethodType.methodType(void.class, MyValue1.class);
  90             test19_mh1 = lookup.findStatic(clazz, "test19_target1", test19_mt);
  91             test19_mh2 = lookup.findStatic(clazz, "test19_target2", test19_mt);
  92         } catch (NoSuchMethodException | IllegalAccessException e) {
  93             e.printStackTrace();
  94             throw new RuntimeException("Method handle lookup failed");
  95         }
  96     }
  97 
  98     @NullRestricted
  99     private static final MyValue1 testValue1 = MyValue1.createWithFieldsInline(rI, rL);
 100 
 101     private static final MyValue1[] testValue1Array = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 3);
 102     static {
 103         for (int i = 0; i < 3; ++i) {
 104             testValue1Array[i] = testValue1;
 105         }
 106     }
 107 
 108     MyValue1 nullField;
 109     @NullRestricted
 110     MyValue1 valueField1 = testValue1;
 111 
 112     @Test
 113     @IR(failOn = {ALLOC})
 114     public long test1(MyValue1 vt) {
 115         long result = 0;
 116         try {
 117             result = vt.hash();
 118             throw new RuntimeException("NullPointerException expected");
 119         } catch (NullPointerException e) {
 120             // Expected
 121         }
 122         return result;
 123     }
 124 
 125     @Run(test = "test1")
 126     public void test1_verifier() {
 127         long result = test1(null);
 128         Asserts.assertEquals(result, 0L);
 129     }
 130 
 131     @Test
 132     @IR(failOn = {ALLOC})
 133     public long test2(MyValue1 vt) {
 134         long result = 0;
 135         try {
 136             result = vt.hashInterpreted();
 137             throw new RuntimeException("NullPointerException expected");
 138         } catch (NullPointerException e) {
 139             // Expected
 140         }
 141         return result;
 142     }
 143 
 144     @Run(test = "test2")
 145     public void test2_verifier() {
 146         long result = test2(null);
 147         Asserts.assertEquals(result, 0L);
 148     }
 149 
 150     @Test
 151     @IR(failOn = {ALLOC})
 152     public long test3() {
 153         long result = 0;
 154         try {
 155             if ((Object)nullField != null) {
 156                 throw new RuntimeException("nullField should be null");
 157             }
 158             result = nullField.hash();
 159             throw new RuntimeException("NullPointerException expected");
 160         } catch (NullPointerException e) {
 161             // Expected
 162         }
 163         return result;
 164     }
 165 
 166     @Run(test = "test3")
 167     public void test3_verifier() {
 168         long result = test3();
 169         Asserts.assertEquals(result, 0L);
 170     }
 171 
 172     @Test
 173     @IR(failOn = {ALLOC})
 174     public void test4() {
 175         try {
 176             valueField1 = nullField;
 177             throw new RuntimeException("NullPointerException expected");
 178         } catch (NullPointerException e) {
 179             // Expected
 180         }
 181     }
 182 
 183     @Run(test = "test4")
 184     public void test4_verifier() {
 185         test4();
 186     }
 187 
 188     @Test
 189     // TODO 8284443 When passing vt to test5_inline and incrementally inlining, we lose the oop
 190     @IR(applyIfOr = {"InlineTypePassFieldsAsArgs", "false", "AlwaysIncrementalInline", "false"},
 191         failOn = {ALLOC})
 192     public MyValue1 test5(MyValue1 vt) {
 193         Object o = vt;
 194         vt = (MyValue1)o;
 195         vt = test5_dontinline(vt);
 196         vt = test5_inline(vt);
 197         return vt;
 198     }
 199 
 200     @Run(test = "test5")
 201     public void test5_verifier() {
 202         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
 203         Asserts.assertEquals(test5(val), val);
 204         Asserts.assertEquals(test5(null), null);
 205     }
 206 
 207     @DontInline
 208     public MyValue1 test5_dontinline(MyValue1 vt) {
 209         return vt;
 210     }
 211 
 212     @ForceInline
 213     public MyValue1 test5_inline(MyValue1 vt) {
 214         return vt;
 215     }
 216 
 217     @Test
 218     public MyValue1 test6(Object obj) {
 219         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
 220         try {
 221             vt = (MyValue1)Objects.requireNonNull(obj);
 222         } catch (NullPointerException e) {
 223             // Expected
 224         }
 225         return vt;
 226     }
 227 
 228     @Run(test = "test6")
 229     public void test6_verifier() {
 230         MyValue1 vt = test6(null);
 231         Asserts.assertEquals(vt.hash(), testValue1.hash());
 232     }
 233 
 234     @ForceInline
 235     public MyValue1 getNullInline() {
 236         return null;
 237     }
 238 
 239     @DontInline
 240     public MyValue1 getNullDontInline() {
 241         return null;
 242     }
 243 
 244     @Test
 245     @IR(failOn = {ALLOC})
 246     public void test7() {
 247         nullField = getNullInline();     // Should not throw
 248         nullField = getNullDontInline(); // Should not throw
 249         try {
 250             valueField1 = getNullInline();
 251             throw new RuntimeException("NullPointerException expected");
 252         } catch (NullPointerException e) {
 253             // Expected
 254         }
 255         try {
 256             valueField1 = getNullDontInline();
 257             throw new RuntimeException("NullPointerException expected");
 258         } catch (NullPointerException e) {
 259             // Expected
 260         }
 261     }
 262 
 263     @Run(test = "test7")
 264     public void test7_verifier() {
 265         test7();
 266     }
 267 
 268     @Test
 269     @IR(failOn = {ALLOC})
 270     public void test8() {
 271         try {
 272             valueField1 = nullField;
 273             throw new RuntimeException("NullPointerException expected");
 274         } catch (NullPointerException e) {
 275             // Expected
 276         }
 277     }
 278 
 279     @Run(test = "test8")
 280     public void test8_verifier() {
 281         test8();
 282     }
 283 
 284     // Merge of two value objects, one being null
 285     @Test
 286     @IR(failOn = {ALLOC})
 287     public void test9(boolean flag) {
 288         MyValue1 v;
 289         if (flag) {
 290             v = valueField1;
 291         } else {
 292             v = nullField;
 293         }
 294         valueField1 = v;
 295     }
 296 
 297     @Run(test = "test9")
 298     public void test9_verifier() {
 299         test9(true);
 300         try {
 301             test9(false);
 302             throw new RuntimeException("NullPointerException expected");
 303         } catch (NullPointerException e) {
 304             // Expected
 305         }
 306     }
 307 
 308     // null constant
 309     @Test
 310     @IR(failOn = {ALLOC})
 311     public void test10(boolean flag) {
 312         MyValue1 val = flag ? valueField1 : null;
 313         valueField1 = val;
 314     }
 315 
 316     @Run(test = "test10")
 317     public void test10_verifier() {
 318         test10(true);
 319         try {
 320             test10(false);
 321             throw new RuntimeException("NullPointerException expected");
 322         } catch (NullPointerException e) {
 323             // Expected
 324         }
 325     }
 326 
 327     // null constant
 328     @Test
 329     @IR(failOn = {ALLOC})
 330     public void test11(boolean flag) {
 331         MyValue1 val = flag ? null : valueField1;
 332         valueField1 = val;
 333     }
 334 
 335     @Run(test = "test11")
 336     public void test11_verifier() {
 337         test11(false);
 338         try {
 339             test11(true);
 340             throw new RuntimeException("NullPointerException expected");
 341         } catch (NullPointerException e) {
 342             // Expected
 343         }
 344     }
 345 
 346     // null return
 347     int test12_cnt;
 348 
 349     @DontInline
 350     public MyValue1 test12_helper() {
 351         test12_cnt++;
 352         return nullField;
 353     }
 354 
 355     @Test
 356     @IR(failOn = {ALLOC})
 357     public void test12() {
 358         valueField1 = test12_helper();
 359     }
 360 
 361     @Run(test = "test12")
 362     public void test12_verifier() {
 363         try {
 364             test12_cnt = 0;
 365             test12();
 366             throw new RuntimeException("NullPointerException expected");
 367         } catch (NullPointerException e) {
 368             // Expected
 369         }
 370         if (test12_cnt != 1) {
 371             throw new RuntimeException("call executed twice");
 372         }
 373     }
 374 
 375     // null return at virtual call
 376     class A {
 377         public MyValue1 test13_helper() {
 378             return nullField;
 379         }
 380     }
 381 
 382     class B extends A {
 383         public MyValue1 test13_helper() {
 384             return nullField;
 385         }
 386     }
 387 
 388     class C extends A {
 389         public MyValue1 test13_helper() {
 390             return nullField;
 391         }
 392     }
 393 
 394     class D extends C {
 395         public MyValue1 test13_helper() {
 396             return nullField;
 397         }
 398     }
 399 
 400     @Test
 401     @IR(failOn = {ALLOC})
 402     public void test13(A a) {
 403         valueField1 = a.test13_helper();
 404     }
 405 
 406     @Run(test = "test13")
 407     public void test13_verifier() {
 408         A a = new A();
 409         A b = new B();
 410         A c = new C();
 411         A d = new D();
 412         try {
 413             test13(a);
 414             throw new RuntimeException("NullPointerException expected");
 415         } catch (NullPointerException e) {
 416             // Expected
 417         }
 418         try {
 419             test13(b);
 420             throw new RuntimeException("NullPointerException expected");
 421         } catch (NullPointerException e) {
 422             // Expected
 423         }
 424         try {
 425             test13(c);
 426             throw new RuntimeException("NullPointerException expected");
 427         } catch (NullPointerException e) {
 428             // Expected
 429         }
 430         try {
 431             test13(d);
 432             throw new RuntimeException("NullPointerException expected");
 433         } catch (NullPointerException e) {
 434             // Expected
 435         }
 436     }
 437 
 438     // Test writing null to a (flat) value class array
 439     @ForceInline
 440     public void test14_inline(Object[] oa, Object o, int index) {
 441         oa[index] = o;
 442     }
 443 
 444     @Test
 445     @IR(failOn = {ALLOC})
 446     public void test14(MyValue1[] va, int index) {
 447         test14_inline(va, nullField, index);
 448     }
 449 
 450     @Run(test = "test14")
 451     public void test14_verifier() {
 452         int index = Math.abs(rI) % 3;
 453         try {
 454             test14(testValue1Array, index);
 455             throw new RuntimeException("No NPE thrown");
 456         } catch (NullPointerException e) {
 457             // Expected
 458         }
 459         Asserts.assertEQ(testValue1Array[index].hash(), testValue1.hash());
 460     }
 461 
 462     @DontInline
 463     MyValue1 getNullField1() {
 464         return nullField;
 465     }
 466 
 467     @DontInline
 468     MyValue1 getNullField2() {
 469         return null;
 470     }
 471 
 472     @Test
 473     @IR(failOn = {ALLOC})
 474     public void test15() {
 475         nullField = getNullField1(); // should not throw
 476         try {
 477             valueField1 = getNullField1();
 478             throw new RuntimeException("NullPointerException expected");
 479         } catch (NullPointerException e) {
 480             // Expected
 481         }
 482         try {
 483             valueField1 = getNullField2();
 484             throw new RuntimeException("NullPointerException expected");
 485         } catch (NullPointerException e) {
 486             // Expected
 487         }
 488     }
 489 
 490     @Run(test = "test15")
 491     public void test15_verifier() {
 492         test15();
 493     }
 494 
 495     @DontInline
 496     public boolean test16_dontinline(MyValue1 vt) {
 497         return vt == null;
 498     }
 499 
 500     // Test c2c call passing null for a value class
 501     @Test
 502     @IR(failOn = {ALLOC})
 503     public boolean test16(Object arg) throws Exception {
 504         Method test16method = getClass().getMethod("test16_dontinline", MyValue1.class);
 505         return (boolean)test16method.invoke(this, arg);
 506     }
 507 
 508     @Run(test = "test16")
 509     @Warmup(10000) // Warmup to make sure 'test17_dontinline' is compiled
 510     public void test16_verifier() throws Exception {
 511         boolean res = test16(null);
 512         Asserts.assertTrue(res);
 513     }
 514 
 515     // Test scalarization of default value class with non-flattenable field
 516     @ImplicitlyConstructible
 517     @LooselyConsistentValue
 518     final value class Test17Value {
 519         public final MyValue1 valueField;
 520 
 521         @ForceInline
 522         public Test17Value(MyValue1 valueField) {
 523             this.valueField = valueField;
 524         }
 525     }
 526 
 527     @Test
 528     // TODO 8284443 When passing testValue1 to the constructor in scalarized form and incrementally inlining, we lose the oop
 529     @IR(applyIfOr = {"InlineTypePassFieldsAsArgs", "false", "AlwaysIncrementalInline", "false"},
 530         failOn = {ALLOC})
 531     public Test17Value test17(boolean b) {
 532         Test17Value vt1 = new Test17Value(null);
 533         Test17Value vt2 = new Test17Value(testValue1);
 534         return b ? vt1 : vt2;
 535     }
 536 
 537     @Run(test = "test17")
 538     public void test17_verifier() {
 539         test17(true);
 540         test17(false);
 541     }
 542 
 543     static final MethodHandle test18_mh1;
 544     static final MethodHandle test18_mh2;
 545 
 546     static MyValue1 nullValue;
 547 
 548     @DontInline
 549     static void test18_target1(MyValue1 vt) {
 550         nullValue = vt;
 551     }
 552 
 553     @ForceInline
 554     static void test18_target2(MyValue1 vt) {
 555         nullValue = vt;
 556     }
 557 
 558     // Test passing null for a value class
 559     @Test
 560     @IR(failOn = {ALLOC})
 561     public void test18() throws Throwable {
 562         test18_mh1.invokeExact(nullValue);
 563         test18_mh2.invokeExact(nullValue);
 564     }
 565 
 566     @Run(test = "test18")
 567     @Warmup(11000) // Make sure lambda forms get compiled
 568     public void test18_verifier() {
 569         try {
 570             test18();
 571         } catch (Throwable t) {
 572             throw new RuntimeException("test18 failed", t);
 573         }
 574     }
 575 
 576     static MethodHandle test19_mh1;
 577     static MethodHandle test19_mh2;
 578 
 579     @DontInline
 580     static void test19_target1(MyValue1 vt) {
 581         nullValue = vt;
 582     }
 583 
 584     @ForceInline
 585     static void test19_target2(MyValue1 vt) {
 586         nullValue = vt;
 587     }
 588 
 589     // Same as test12 but with non-final mh
 590     @Test
 591     @IR(failOn = {ALLOC})
 592     public void test19() throws Throwable {
 593         test19_mh1.invokeExact(nullValue);
 594         test19_mh2.invokeExact(nullValue);
 595     }
 596 
 597     @Run(test = "test19")
 598     @Warmup(11000) // Make sure lambda forms get compiled
 599     public void test19_verifier() {
 600         try {
 601             test19();
 602         } catch (Throwable t) {
 603             throw new RuntimeException("test19 failed", t);
 604         }
 605     }
 606 
 607     // Same as test12/13 but with constant null
 608     @Test
 609     @IR(failOn = {ALLOC})
 610     public void test20(MethodHandle mh) throws Throwable {
 611         mh.invoke(null);
 612     }
 613 
 614     @Run(test = "test20")
 615     @Warmup(11000) // Make sure lambda forms get compiled
 616     public void test20_verifier() {
 617         try {
 618             test20(test18_mh1);
 619             test20(test18_mh2);
 620             test20(test19_mh1);
 621             test20(test19_mh2);
 622         } catch (Throwable t) {
 623             throw new RuntimeException("test20 failed", t);
 624         }
 625     }
 626 
 627     // Test writing null to a flattenable/non-flattenable value class field in a value class
 628     @ImplicitlyConstructible
 629     @LooselyConsistentValue
 630     value class Test21Value {
 631         MyValue1 valueField1;
 632         @NullRestricted
 633         MyValue1 valueField2;
 634 
 635         @ForceInline
 636         public Test21Value(MyValue1 valueField1, MyValue1 valueField2) {
 637             this.valueField1 = valueField1;
 638             this.valueField2 = valueField2;
 639         }
 640 
 641         @ForceInline
 642         public Test21Value test1() {
 643             return new Test21Value(null, this.valueField2); // Should not throw NPE
 644         }
 645 
 646         @ForceInline
 647         public Test21Value test2() {
 648             return new Test21Value(this.valueField1, null); // Should throw NPE
 649         }
 650     }
 651 
 652     @Test
 653     @IR(failOn = {ALLOC})
 654     public Test21Value test21(Test21Value vt) {
 655         vt = vt.test1();
 656         try {
 657             vt = vt.test2();
 658             throw new RuntimeException("NullPointerException expected");
 659         } catch (NullPointerException e) {
 660             // Expected
 661         }
 662         return vt;
 663     }
 664 
 665     @Run(test = "test21")
 666     public void test21_verifier() {
 667         test21(new Test21Value(null, MyValue1.createDefaultInline()));
 668     }
 669 
 670     @DontInline
 671     public MyValue1 test22_helper() {
 672         return nullField;
 673     }
 674 
 675     @Test
 676     @IR(failOn = {ALLOC})
 677     public void test22() {
 678         valueField1 = test22_helper();
 679     }
 680 
 681     @Run(test = "test22")
 682     public void test22_verifier() {
 683         try {
 684             test22();
 685             throw new RuntimeException("NullPointerException expected");
 686         } catch (NullPointerException e) {
 687             // Expected
 688         }
 689     }
 690 
 691     @Test
 692     @IR(applyIfAnd = {"FlatArrayElementMaxSize", "= -1", "InlineTypePassFieldsAsArgs", "true"},
 693         failOn = {ALLOC})
 694     @IR(applyIfAnd = {"FlatArrayElementMaxSize", "= 0", "InlineTypePassFieldsAsArgs", "false"},
 695         failOn = {ALLOC})
 696     public void test23(MyValue1 val) {
 697         MyValue1[] arr = (MyValue1[])ValueClass.newNullRestrictedArray(MyValue1.class, 2);
 698         arr[0] = val;
 699     }
 700 
 701     @Run(test = "test23")
 702     public void test23_verifier() {
 703         MyValue1 val = null;
 704         try {
 705             test23(val);
 706             throw new RuntimeException("NullPointerException expected");
 707         } catch (NullPointerException e) {
 708             // Expected
 709         }
 710     }
 711 
 712     static MyValue1 nullBox;
 713 
 714     @Test
 715     @IR(failOn = {ALLOC})
 716     public MyValue1 test24() {
 717         return Objects.requireNonNull(nullBox);
 718     }
 719 
 720     @Run(test = "test24")
 721     public void test24_verifier() {
 722         try {
 723             test24();
 724             throw new RuntimeException("NullPointerException expected");
 725         } catch (NullPointerException e) {
 726             // Expected
 727         }
 728     }
 729 
 730     @DontInline
 731     public void test25_callee(MyValue1 val) { }
 732 
 733     // Test that when checkcasting from null-ok to null-free and back to null-ok we
 734     // keep track of the information that the value object can never be null.
 735     @Test
 736     @IR(failOn = {ALLOC, STORE})
 737     public int test25(boolean b, MyValue1 vt1, MyValue1 vt2) {
 738         vt1 = (MyValue1)vt1;
 739         Object obj = b ? vt1 : vt2; // We should not allocate here
 740         test25_callee((MyValue1) vt1);
 741         return ((MyValue1)obj).x;
 742     }
 743 
 744     @Run(test = "test25")
 745     public void test25_verifier(RunInfo info) {
 746         int res = test25(true, testValue1, testValue1);
 747         Asserts.assertEquals(res, testValue1.x);
 748         res = test25(false, testValue1, testValue1);
 749         Asserts.assertEquals(res, testValue1.x);
 750         if (!info.isWarmUp()) {
 751             try {
 752                 test25(true, null, testValue1);
 753                 throw new RuntimeException("NullPointerException expected");
 754             } catch (NullPointerException e) {
 755                 // Expected
 756             }
 757         }
 758     }
 759 
 760     // Test that chains of casts are folded and don't trigger an allocation
 761     @Test
 762     @IR(failOn = {ALLOC, STORE})
 763     public MyValue3 test26(MyValue3 vt) {
 764         return ((MyValue3)((Object)((MyValue3)(MyValue3)((MyValue3)((Object)vt)))));
 765     }
 766 
 767     @Run(test = "test26")
 768     public void test26_verifier() {
 769         MyValue3 vt = MyValue3.create();
 770         MyValue3 result = test26(vt);
 771         Asserts.assertEquals(result, vt);
 772     }
 773 
 774     @Test
 775     @IR(failOn = {ALLOC, STORE})
 776     public MyValue3 test27(MyValue3 vt) {
 777         return ((MyValue3)((Object)((MyValue3)(MyValue3)((MyValue3)((Object)vt)))));
 778     }
 779 
 780     @Run(test = "test27")
 781     public void test27_verifier() {
 782         MyValue3 vt = MyValue3.create();
 783         MyValue3 result = (MyValue3) test27(vt);
 784         Asserts.assertEquals(result, vt);
 785     }
 786 
 787     // Some more casting tests
 788     @Test
 789     public MyValue1 test28(MyValue1 vt, MyValue1 vtBox, int i) {
 790         MyValue1 result = null;
 791         if (i == 0) {
 792             result = (MyValue1)vt;
 793             result = null;
 794         } else if (i == 1) {
 795             result = (MyValue1)vt;
 796         } else if (i == 2) {
 797             result = vtBox;
 798         }
 799         return result;
 800     }
 801 
 802     @Run(test = "test28")
 803     public void test28_verifier() {
 804         MyValue1 result = test28(testValue1, null, 0);
 805         Asserts.assertEquals(result, null);
 806         result = test28(testValue1, testValue1, 1);
 807         Asserts.assertEquals(result, testValue1);
 808         result = test28(testValue1, null, 2);
 809         Asserts.assertEquals(result, null);
 810         result = test28(testValue1, testValue1, 2);
 811         Asserts.assertEquals(result, testValue1);
 812     }
 813 
 814     @Test
 815     @IR(failOn = {ALLOC})
 816     public long test29(MyValue1 vt, MyValue1 vtBox) {
 817         long result = 0;
 818         for (int i = 0; i < 100; ++i) {
 819             MyValue1 box;
 820             if (i == 0) {
 821                 box = (MyValue1)vt;
 822                 box = null;
 823             } else if (i < 99) {
 824                 box = (MyValue1)vt;
 825             } else {
 826                 box = vtBox;
 827             }
 828             if (box != null) {
 829                 result += box.hash();
 830             }
 831         }
 832         return result;
 833     }
 834 
 835     @Run(test = "test29")
 836     public void test29_verifier() {
 837         long result = test29(testValue1, null);
 838         Asserts.assertEquals(result, testValue1.hash()*98);
 839         result = test29(testValue1, testValue1);
 840         Asserts.assertEquals(result, testValue1.hash()*99);
 841     }
 842 
 843     // Test null check of value object receiver with incremental inlining
 844     public long test30_callee(MyValue1 vt) {
 845         long result = 0;
 846         try {
 847             result = vt.hashInterpreted();
 848             throw new RuntimeException("NullPointerException expected");
 849         } catch (NullPointerException e) {
 850             // Expected
 851         }
 852         return result;
 853     }
 854 
 855     @Test
 856     @IR(failOn = {ALLOC})
 857     public long test30() {
 858         return test30_callee(nullField);
 859     }
 860 
 861     @Run(test = "test30")
 862     public void test30_verifier() {
 863         long result = test30();
 864         Asserts.assertEquals(result, 0L);
 865     }
 866 
 867     // Test casting null to unloaded value class
 868     value class Test31Value {
 869         private int i = 0;
 870     }
 871 
 872     @Test
 873     @IR(failOn = {ALLOC})
 874     public Object test31(Object o) {
 875         return (Test31Value)o;
 876     }
 877 
 878     @Run(test = "test31")
 879     public void test31_verifier() {
 880         test31(null);
 881     }
 882 
 883     private static final MyValue1 constNullRefField = null;
 884 
 885     @Test
 886     @IR(failOn = {ALLOC})
 887     public MyValue1 test32() {
 888         return constNullRefField;
 889     }
 890 
 891     @Run(test = "test32")
 892     public void test32_verifier() {
 893         MyValue1 result = test32();
 894         Asserts.assertEquals(result, null);
 895     }
 896 
 897     @ImplicitlyConstructible
 898     @LooselyConsistentValue
 899     static value class Test33Value1 {
 900         int x = 0;
 901     }
 902 
 903     @ImplicitlyConstructible
 904     @LooselyConsistentValue
 905     static value class Test33Value2 {
 906         Test33Value1 vt;
 907 
 908         public Test33Value2() {
 909             vt = new Test33Value1();
 910         }
 911     }
 912 
 913     @NullRestricted
 914     public static final Test33Value2 test33Val = new Test33Value2();
 915 
 916     @Test
 917     @IR(failOn = {ALLOC})
 918     public Test33Value2 test33() {
 919         return test33Val;
 920     }
 921 
 922     @Run(test = "test33")
 923     public void test33_verifier() {
 924         Test33Value2 result = test33();
 925         Asserts.assertEquals(result, test33Val);
 926     }
 927 
 928     // Verify that static nullable inline-type fields are not
 929     // treated as never-null by C2 when initialized at compile time.
 930     private static MyValue1 test34Val;
 931 
 932     @Test
 933     public void test34(MyValue1 vt) {
 934         if (test34Val == null) {
 935             test34Val = vt;
 936         }
 937     }
 938 
 939     @Run(test = "test34")
 940     public void test34_verifier(RunInfo info) {
 941         test34(testValue1);
 942         if (!info.isWarmUp()) {
 943             test34Val = null;
 944             test34(testValue1);
 945             Asserts.assertEquals(test34Val, testValue1);
 946         }
 947     }
 948 
 949     // Same as test17 but with non-allocated value object
 950     @Test
 951     public Test17Value test35(boolean b) {
 952         Test17Value vt1 = new Test17Value(null);
 953         if ((Object)vt1.valueField != null) {
 954             throw new RuntimeException("Should be null");
 955         }
 956         MyValue1 vt3 = MyValue1.createWithFieldsInline(rI, rL);
 957         Test17Value vt2 = new Test17Value(vt3);
 958         return b ? vt1 : vt2;
 959     }
 960 
 961     @Run(test = "test35")
 962     public void test35_verifier() {
 963         test35(true);
 964         test35(false);
 965     }
 966 
 967     // Test that when explicitly null checking a value object, we keep
 968     // track of the information that the value object can never be null.
 969     @Test
 970     @IR(failOn = {ALLOC, STORE})
 971     public int test37(boolean b, MyValue1 vt1, MyValue1 vt2) {
 972         if (vt1 == null) {
 973             return 0;
 974         }
 975         // vt1 should be scalarized because it's always non-null
 976         Object obj = b ? vt1 : vt2; // We should not allocate vt2 here
 977         test25_callee(vt1);
 978         return ((MyValue1)obj).x;
 979     }
 980 
 981     @Run(test = "test37")
 982     public void test37_verifier() {
 983         int res = test37(true, testValue1, testValue1);
 984         Asserts.assertEquals(res, testValue1.x);
 985         res = test37(false, testValue1, testValue1);
 986         Asserts.assertEquals(res, testValue1.x);
 987     }
 988 
 989     // Test that when explicitly null checking a value object receiver,
 990     // we keep track of the information that the value object can never be null.
 991     @Test
 992     @IR(failOn = {ALLOC, STORE})
 993     public int test38(boolean b, MyValue1 vt1, MyValue1 vt2) {
 994         vt1.hash(); // Inlined - Explicit null check
 995         // vt1 should be scalarized because it's always non-null
 996         Object obj = b ? vt1 : vt2; // We should not allocate vt2 here
 997         test25_callee(vt1);
 998         return ((MyValue1)obj).x;
 999     }
1000 
1001     @Run(test = "test38")
1002     public void test38_verifier() {
1003         int res = test38(true, testValue1, testValue1);
1004         Asserts.assertEquals(res, testValue1.x);
1005         res = test38(false, testValue1, testValue1);
1006         Asserts.assertEquals(res, testValue1.x);
1007     }
1008 
1009     // Test that when implicitly null checking a value object receiver,
1010     // we keep track of the information that the value object can never be null.
1011     @Test
1012     @IR(failOn = {ALLOC, STORE})
1013     public int test39(boolean b, MyValue1 vt1, MyValue1 vt2) {
1014         vt1.hashInterpreted(); // Not inlined - Implicit null check
1015         // vt1 should be scalarized because it's always non-null
1016         Object obj = b ? vt1 : vt2; // We should not allocate vt2 here
1017         test25_callee(vt1);
1018         return ((MyValue1)obj).x;
1019     }
1020 
1021     @Run(test = "test39")
1022     public void test39_verifier() {
1023         int res = test39(true, testValue1, testValue1);
1024         Asserts.assertEquals(res, testValue1.x);
1025         res = test39(false, testValue1, testValue1);
1026         Asserts.assertEquals(res, testValue1.x);
1027     }
1028 
1029     // Test NPE when casting constant null to a value class
1030     @Test
1031     @IR(failOn = {ALLOC})
1032     public MyValue1 test40() {
1033         Object NULL = null;
1034         MyValue1 val = (MyValue1)NULL;
1035         return Objects.requireNonNull(val);
1036     }
1037 
1038     @Run(test = "test40")
1039     public void test40_verifier() {
1040         try {
1041             test40();
1042             throw new RuntimeException("NullPointerException expected");
1043         } catch (NullPointerException e) {
1044             // Expected
1045         }
1046     }
1047 
1048     MyValue1 refField;
1049     @NullRestricted
1050     MyValue1 flatField;
1051 
1052     // Test scalarization of .ref
1053     @Test
1054     @IR(failOn = {ALLOC_G, STORE, TRAP})
1055     public int test41(boolean b) {
1056         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1057         if (b) {
1058             val = refField;
1059         }
1060         return val.x;
1061     }
1062 
1063     @Run(test = "test41")
1064     public void test41_verifier(RunInfo info) {
1065         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1066         Asserts.assertEquals(test41(true), refField.x);
1067         Asserts.assertEquals(test41(false), testValue1.x);
1068         if (!info.isWarmUp()) {
1069             refField = null;
1070             try {
1071                 Asserts.assertEquals(test41(false), testValue1.x);
1072                 test41(true);
1073                 throw new RuntimeException("NullPointerException expected");
1074             } catch (NullPointerException e) {
1075                 // Expected
1076             }
1077         }
1078     }
1079 
1080     // Same as test41 but with call to hash()
1081     @Test
1082     @IR(failOn = {ALLOC, STORE, TRAP})
1083     public long test42(boolean b) {
1084         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1085         if (b) {
1086             val = refField;
1087         }
1088         return val.hash();
1089     }
1090 
1091     @Run(test = "test42")
1092     public void test42_verifier(RunInfo info) {
1093         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1094         Asserts.assertEquals(test42(true), refField.hash());
1095         Asserts.assertEquals(test42(false), testValue1.hash());
1096         if (!info.isWarmUp()) {
1097             refField = null;
1098             try {
1099                 Asserts.assertEquals(test42(false), testValue1.hash());
1100                 test42(true);
1101                 throw new RuntimeException("NullPointerException expected");
1102             } catch (NullPointerException e) {
1103                 // Expected
1104             }
1105         }
1106     }
1107 
1108     @Test
1109     public MyValue1 test43(boolean b) {
1110         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1111         if (b) {
1112             val = refField;
1113         }
1114         return val;
1115     }
1116 
1117     @Run(test = "test43")
1118     public void test43_verifier(RunInfo info) {
1119         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1120         Asserts.assertEquals(test43(true).hash(), refField.hash());
1121         Asserts.assertEquals(test43(false).hash(), testValue1.hash());
1122         if (!info.isWarmUp()) {
1123             refField = null;
1124             Asserts.assertEquals(test43(true), null);
1125         }
1126     }
1127 
1128     // Test scalarization when .ref is referenced in safepoint debug info
1129     @Test
1130     @IR(failOn = {ALLOC, STORE})
1131     public int test44(boolean b1, boolean b2, Method m) {
1132         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1133         if (b1) {
1134             val = refField;
1135         }
1136         if (b2) {
1137             // Uncommon trap
1138             TestFramework.deoptimize(m);
1139         }
1140         return val.x;
1141     }
1142 
1143     @Run(test = "test44")
1144     public void test44_verifier(RunInfo info) {
1145         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1146         Asserts.assertEquals(test44(true, false, info.getTest()), refField.x);
1147         Asserts.assertEquals(test44(false, false, info.getTest()), testValue1.x);
1148         if (!info.isWarmUp()) {
1149             refField = null;
1150             try {
1151                 Asserts.assertEquals(test44(false, false, info.getTest()), testValue1.x);
1152                 test44(true, false, info.getTest());
1153                 throw new RuntimeException("NullPointerException expected");
1154             } catch (NullPointerException e) {
1155                 // Expected
1156             }
1157             refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1158             Asserts.assertEquals(test44(true, true, info.getTest()), refField.x);
1159             Asserts.assertEquals(test44(false, true, info.getTest()), testValue1.x);
1160         }
1161     }
1162 
1163     @Test
1164     public MyValue1 test45(boolean b1, boolean b2, Method m) {
1165         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1166         if (b1) {
1167             val = refField;
1168         }
1169         if (b2) {
1170             // Uncommon trap
1171             TestFramework.deoptimize(m);
1172         }
1173         return val;
1174     }
1175 
1176     @Run(test = "test45")
1177     public void test45_verifier(RunInfo info) {
1178         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1179         Asserts.assertEquals(test45(true, false, info.getTest()).hash(), refField.hash());
1180         Asserts.assertEquals(test45(false, false, info.getTest()).hash(), testValue1.hash());
1181         if (!info.isWarmUp()) {
1182             refField = null;
1183             Asserts.assertEquals(test45(true, false, info.getTest()), null);
1184             refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1185             Asserts.assertEquals(test45(true, true, info.getTest()).hash(), refField.hash());
1186             Asserts.assertEquals(test45(false, true, info.getTest()).hash(), testValue1.hash());
1187         }
1188     }
1189 
1190     @Test
1191     @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP})
1192     public int test46(boolean b) {
1193         MyValue1 val = null;
1194         if (b) {
1195             val = MyValue1.createWithFieldsInline(rI, rL);
1196         }
1197         return val.x;
1198     }
1199 
1200     @Run(test = "test46")
1201     public void test46_verifier() {
1202         Asserts.assertEquals(test46(true), testValue1.x);
1203         try {
1204             test46(false);
1205             throw new RuntimeException("NullPointerException expected");
1206         } catch (NullPointerException e) {
1207             // Expected
1208         }
1209     }
1210 
1211     @Test
1212     public MyValue1 test47(boolean b) {
1213         MyValue1 val = null;
1214         if (b) {
1215             val = MyValue1.createWithFieldsInline(rI, rL);
1216         }
1217         return val;
1218     }
1219 
1220     @Run(test = "test47")
1221     public void test47_verifier() {
1222         Asserts.assertEquals(test47(true).hash(), testValue1.hash());
1223         Asserts.assertEquals(test47(false), null);
1224     }
1225 
1226     @Test
1227     @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP})
1228     public int test48(boolean b) {
1229         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1230         if (b) {
1231             val = null;
1232         }
1233         return val.x;
1234     }
1235 
1236     @Run(test = "test48")
1237     public void test48_verifier() {
1238         Asserts.assertEquals(test48(false), testValue1.x);
1239         try {
1240             test48(true);
1241             throw new RuntimeException("NullPointerException expected");
1242         } catch (NullPointerException e) {
1243             // Expected
1244         }
1245     }
1246 
1247     @Test
1248     public MyValue1 test49(boolean b) {
1249         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1250         if (b) {
1251             val = null;
1252         }
1253         return val;
1254     }
1255 
1256     @Run(test = "test49")
1257     public void test49_verifier() {
1258         Asserts.assertEquals(test49(false).hash(), testValue1.hash());
1259         Asserts.assertEquals(test49(true), null);
1260     }
1261 
1262     @ForceInline
1263     public Object test50_helper() {
1264         return flatField;
1265     }
1266 
1267     @Test
1268     @IR(failOn = {ALLOC_G, TRAP})
1269     public void test50(boolean b) {
1270         Object o = null;
1271         if (b) {
1272             o = testValue1;
1273         } else {
1274             o = test50_helper();
1275         }
1276         flatField = (MyValue1)o;
1277     }
1278 
1279     @Run(test = "test50")
1280     public void test50_verifier() {
1281         MyValue1 vt = MyValue1.createWithFieldsInline(rI+1, rL+1);
1282         flatField = vt;
1283         test50(false);
1284         Asserts.assertEquals(flatField.hash(), vt.hash());
1285         test50(true);
1286         Asserts.assertEquals(flatField.hash(), testValue1.hash());
1287     }
1288 
1289     @ImplicitlyConstructible
1290     @LooselyConsistentValue
1291     static value class MyValue1Wrapper {
1292         MyValue1 vt;
1293 
1294         @ForceInline
1295         public MyValue1Wrapper(MyValue1 vt) {
1296             this.vt = vt;
1297         }
1298 
1299         @ForceInline
1300         public long hash() {
1301             return (vt != null) ? vt.hash() : 0;
1302         }
1303     }
1304 
1305     @NullRestricted
1306     MyValue1Wrapper wrapperField;
1307 
1308     @Test
1309     @IR(failOn = {ALLOC_G, STORE, TRAP})
1310     public long test51(boolean b) {
1311         MyValue1Wrapper val = new MyValue1Wrapper(null);
1312         if (b) {
1313             val = wrapperField;
1314         }
1315         return val.hash();
1316     }
1317 
1318     @Run(test = "test51")
1319     public void test51_verifier() {
1320         wrapperField = new MyValue1Wrapper(testValue1);
1321         Asserts.assertEquals(test51(true), wrapperField.hash());
1322         Asserts.assertEquals(test51(false), (new MyValue1Wrapper(null)).hash());
1323     }
1324 
1325     @Test
1326     @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP})
1327     public boolean test52(boolean b) {
1328         MyValue1 val = MyValue1.createDefaultInline();
1329         if (b) {
1330             val = null;
1331         }
1332         MyValue1Wrapper w = new MyValue1Wrapper(val);
1333         return w.vt == null;
1334     }
1335 
1336     @Run(test = "test52")
1337     public void test52_verifier() {
1338         Asserts.assertTrue(test52(true));
1339         Asserts.assertFalse(test52(false));
1340     }
1341 
1342     @Test
1343     @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP})
1344     public boolean test53(boolean b) {
1345         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1346         if (b) {
1347             val = null;
1348         }
1349         MyValue1Wrapper w = new MyValue1Wrapper(val);
1350         return w.vt == null;
1351     }
1352 
1353     @Run(test = "test53")
1354     public void test53_verifier() {
1355         Asserts.assertTrue(test53(true));
1356         Asserts.assertFalse(test53(false));
1357     }
1358 
1359     @Test
1360     @IR(failOn = {ALLOC, LOAD, STORE, TRAP})
1361     public long test54(boolean b1, boolean b2) {
1362         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1363         if (b1) {
1364             val = null;
1365         }
1366         MyValue1Wrapper w = new MyValue1Wrapper(null);
1367         if (b2) {
1368             w = new MyValue1Wrapper(val);
1369         }
1370         return w.hash();
1371     }
1372 
1373     @Run(test = "test54")
1374     public void test54_verifier() {
1375         MyValue1Wrapper w = new MyValue1Wrapper(MyValue1.createWithFieldsInline(rI, rL));
1376         Asserts.assertEquals(test54(false, false), (new MyValue1Wrapper(null)).hash());
1377         Asserts.assertEquals(test54(false, true), w.hash());
1378         Asserts.assertEquals(test54(true, false), (new MyValue1Wrapper(null)).hash());
1379         Asserts.assertEquals(test54(true, true), 0L);
1380     }
1381 
1382     @Test
1383     @IR(failOn = {ALLOC_G, STORE, TRAP})
1384     public int test55(boolean b) {
1385         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1386         MyValue1Wrapper w = new MyValue1Wrapper(val);
1387         if (b) {
1388             w = new MyValue1Wrapper(refField);
1389         }
1390         return w.vt.x;
1391     }
1392 
1393     @Run(test = "test55")
1394     public void test55_verifier(RunInfo info) {
1395         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1396         Asserts.assertEquals(test55(true), refField.x);
1397         Asserts.assertEquals(test55(false), testValue1.x);
1398         if (!info.isWarmUp()) {
1399             refField = null;
1400             try {
1401                 Asserts.assertEquals(test55(false), testValue1.x);
1402                 test55(true);
1403                 throw new RuntimeException("NullPointerException expected");
1404             } catch (NullPointerException e) {
1405                 // Expected
1406             }
1407         }
1408     }
1409 
1410     @Test
1411     @IR(failOn = {ALLOC, STORE, TRAP})
1412     public long test56(boolean b) {
1413         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1414         MyValue1Wrapper w = new MyValue1Wrapper(val);
1415         if (b) {
1416             w = new MyValue1Wrapper(refField);
1417         }
1418         return w.vt.hash();
1419     }
1420 
1421     @Run(test = "test56")
1422     public void test56_verifier(RunInfo info) {
1423         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1424         Asserts.assertEquals(test56(true), refField.hash());
1425         Asserts.assertEquals(test56(false), testValue1.hash());
1426         if (!info.isWarmUp()) {
1427             refField = null;
1428             try {
1429                 Asserts.assertEquals(test56(false), testValue1.hash());
1430                 test56(true);
1431                 throw new RuntimeException("NullPointerException expected");
1432             } catch (NullPointerException e) {
1433                 // Expected
1434             }
1435         }
1436     }
1437 
1438     @Test
1439     public MyValue1 test57(boolean b) {
1440         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1441         MyValue1Wrapper w = new MyValue1Wrapper(val);
1442         if (b) {
1443             w = new MyValue1Wrapper(refField);
1444         }
1445         return w.vt;
1446     }
1447 
1448     @Run(test = "test57")
1449     public void test57_verifier(RunInfo info) {
1450         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1451         Asserts.assertEquals(test57(true).hash(), refField.hash());
1452         Asserts.assertEquals(test57(false).hash(), testValue1.hash());
1453         if (!info.isWarmUp()) {
1454             refField = null;
1455             Asserts.assertEquals(test57(true), null);
1456         }
1457     }
1458 
1459     // Test scalarization when .ref is referenced in safepoint debug info
1460     @Test
1461     @IR(failOn = {ALLOC, STORE})
1462     public int test58(boolean b1, boolean b2, Method m) {
1463         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1464         MyValue1Wrapper w = new MyValue1Wrapper(val);
1465         if (b1) {
1466             w = new MyValue1Wrapper(refField);
1467         }
1468         if (b2) {
1469             // Uncommon trap
1470             TestFramework.deoptimize(m);
1471         }
1472         return w.vt.x;
1473     }
1474 
1475     @Run(test = "test58")
1476     public void test58_verifier(RunInfo info) {
1477         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1478         Asserts.assertEquals(test58(true, false, info.getTest()), refField.x);
1479         Asserts.assertEquals(test58(false, false, info.getTest()), testValue1.x);
1480         if (!info.isWarmUp()) {
1481             refField = null;
1482             try {
1483                 Asserts.assertEquals(test58(false, false, info.getTest()), testValue1.x);
1484                 test58(true, false, info.getTest());
1485                 throw new RuntimeException("NullPointerException expected");
1486             } catch (NullPointerException e) {
1487                 // Expected
1488             }
1489             refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1490             Asserts.assertEquals(test58(true, true, info.getTest()), refField.x);
1491             Asserts.assertEquals(test58(false, true, info.getTest()), testValue1.x);
1492         }
1493     }
1494 
1495     @Test
1496     public MyValue1 test59(boolean b1, boolean b2, Method m) {
1497         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1498         MyValue1Wrapper w = new MyValue1Wrapper(val);
1499         if (b1) {
1500             w = new MyValue1Wrapper(refField);
1501         }
1502         if (b2) {
1503             // Uncommon trap
1504             TestFramework.deoptimize(m);
1505         }
1506         return w.vt;
1507     }
1508 
1509     @Run(test = "test59")
1510     public void test59_verifier(RunInfo info) {
1511         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1512         Asserts.assertEquals(test59(true, false, info.getTest()).hash(), refField.hash());
1513         Asserts.assertEquals(test59(false, false, info.getTest()).hash(), testValue1.hash());
1514         if (!info.isWarmUp()) {
1515             refField = null;
1516             Asserts.assertEquals(test59(true, false, info.getTest()), null);
1517             refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1518             Asserts.assertEquals(test59(true, true, info.getTest()).hash(), refField.hash());
1519             Asserts.assertEquals(test59(false, true, info.getTest()).hash(), testValue1.hash());
1520         }
1521     }
1522 
1523     @Test
1524     @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP})
1525     public int test60(boolean b) {
1526         MyValue1Wrapper w = new MyValue1Wrapper(null);
1527         if (b) {
1528             MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1529             w = new MyValue1Wrapper(val);
1530         }
1531         return w.vt.x;
1532     }
1533 
1534     @Run(test = "test60")
1535     public void test60_verifier() {
1536         Asserts.assertEquals(test60(true), testValue1.x);
1537         try {
1538             test60(false);
1539             throw new RuntimeException("NullPointerException expected");
1540         } catch (NullPointerException e) {
1541             // Expected
1542         }
1543     }
1544 
1545     @Test
1546     public MyValue1 test61(boolean b) {
1547         MyValue1Wrapper w = new MyValue1Wrapper(null);
1548         if (b) {
1549             MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1550             w = new MyValue1Wrapper(val);
1551         }
1552         return w.vt;
1553     }
1554 
1555     @Run(test = "test61")
1556     public void test61_verifier() {
1557         Asserts.assertEquals(test61(true).hash(), testValue1.hash());
1558         Asserts.assertEquals(test61(false), null);
1559     }
1560 
1561     @Test
1562     @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP})
1563     public int test62(boolean b) {
1564         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1565         MyValue1Wrapper w = new MyValue1Wrapper(val);
1566         if (b) {
1567             w = new MyValue1Wrapper(null);
1568         }
1569         return w.vt.x;
1570     }
1571 
1572     @Run(test = "test62")
1573     public void test62_verifier() {
1574         Asserts.assertEquals(test62(false), testValue1.x);
1575         try {
1576             test62(true);
1577             throw new RuntimeException("NullPointerException expected");
1578         } catch (NullPointerException e) {
1579             // Expected
1580         }
1581     }
1582 
1583     @Test
1584     public MyValue1 test63(boolean b) {
1585         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1586         MyValue1Wrapper w = new MyValue1Wrapper(val);
1587         if (b) {
1588             w = new MyValue1Wrapper(null);
1589         }
1590         return w.vt;
1591     }
1592 
1593     @Run(test = "test63")
1594     public void test63_verifier() {
1595         Asserts.assertEquals(test63(false).hash(), testValue1.hash());
1596         Asserts.assertEquals(test63(true), null);
1597     }
1598 
1599     @ForceInline
1600     public MyValue1 test64_helper() {
1601         return flatField;
1602     }
1603 
1604     @Test
1605     @IR(failOn = {ALLOC_G, TRAP})
1606     public void test64(boolean b) {
1607         MyValue1Wrapper w = new MyValue1Wrapper(null);
1608         if (b) {
1609             w = new MyValue1Wrapper(testValue1);
1610         } else {
1611             w = new MyValue1Wrapper(test64_helper());
1612         }
1613         flatField = w.vt;
1614     }
1615 
1616     @Run(test = "test64")
1617     public void test64_verifier() {
1618         MyValue1 vt = MyValue1.createWithFieldsInline(rI+1, rL+1);
1619         flatField = vt;
1620         test64(false);
1621         Asserts.assertEquals(flatField.hash(), vt.hash());
1622         test64(true);
1623         Asserts.assertEquals(flatField.hash(), testValue1.hash());
1624     }
1625 
1626     @Test
1627     @IR(failOn = {ALLOC_G, LOAD, STORE, TRAP})
1628     public long test65(boolean b) {
1629         MyValue1 val = MyValue1.createWithFieldsInline(rI, rL);
1630         if (b) {
1631             val = null;
1632         }
1633         if (val != null) {
1634             return val.hashPrimitive();
1635         }
1636         return 42;
1637     }
1638 
1639     @Run(test = "test65")
1640     public void test65_verifier() {
1641         Asserts.assertEquals(test65(true), 42L);
1642         Asserts.assertEquals(test65(false), MyValue1.createWithFieldsInline(rI, rL).hashPrimitive());
1643     }
1644 
1645     @ForceInline
1646     public Object test66_helper(Object arg) {
1647         return arg;
1648     }
1649 
1650     // Test that .ref arg does not block scalarization
1651     @Test
1652     @IR(failOn = {ALLOC, STORE})
1653     public int test66(boolean b1, boolean b2, MyValue1 arg, Method m) {
1654         Object val = MyValue1.createWithFieldsInline(rI, rL);
1655         if (b1) {
1656             val = test66_helper(arg);
1657         }
1658         if (b2) {
1659             // Uncommon trap
1660             TestFramework.deoptimize(m);
1661         }
1662         return ((MyValue1)val).x;
1663     }
1664 
1665     @Run(test = "test66")
1666     public void test66_verifier(RunInfo info) {
1667         MyValue1 arg = MyValue1.createWithFieldsInline(rI+1, rL+1);
1668         Asserts.assertEquals(test66(true, false, arg, info.getTest()), arg.x);
1669         Asserts.assertEquals(test66(false, false, arg, info.getTest()), testValue1.x);
1670         if (!info.isWarmUp()) {
1671             try {
1672                 Asserts.assertEquals(test66(false, false, arg, info.getTest()), testValue1.x);
1673                 test66(true, false, null, info.getTest());
1674                 throw new RuntimeException("NullPointerException expected");
1675             } catch (NullPointerException e) {
1676                 // Expected
1677             }
1678             Asserts.assertEquals(test66(true, true, arg, info.getTest()), arg.x);
1679             Asserts.assertEquals(test66(false, true, arg, info.getTest()), testValue1.x);
1680         }
1681     }
1682 
1683     @DontInline
1684     public MyValue1 test67_helper1() {
1685         return refField;
1686     }
1687 
1688     @ForceInline
1689     public Object test67_helper2() {
1690         return test67_helper1();
1691     }
1692 
1693     // Test that .ref return does not block scalarization
1694     @Test
1695     @IR(failOn = {ALLOC, STORE})
1696     public long test67(boolean b1, boolean b2, Method m) {
1697         Object val = MyValue1.createWithFieldsInline(rI, rL);
1698         if (b1) {
1699             val = test67_helper2();
1700         }
1701         if (b2) {
1702             // Uncommon trap
1703             TestFramework.deoptimize(m);
1704         }
1705         return ((MyValue1)val).hash();
1706     }
1707 
1708     @Run(test = "test67")
1709     public void test67_verifier(RunInfo info) {
1710         refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1711         Asserts.assertEquals(test67(true, false, info.getTest()), refField.hash());
1712         Asserts.assertEquals(test67(false, false, info.getTest()), testValue1.hash());
1713         if (!info.isWarmUp()) {
1714             refField = null;
1715             try {
1716                 Asserts.assertEquals(test67(false, false, info.getTest()), testValue1.hash());
1717                 test67(true, false, info.getTest());
1718                 throw new RuntimeException("NullPointerException expected");
1719             } catch (NullPointerException e) {
1720                 // Expected
1721             }
1722             refField = MyValue1.createWithFieldsInline(rI+1, rL+1);
1723             Asserts.assertEquals(test67(true, true, info.getTest()), refField.hash());
1724             Asserts.assertEquals(test67(false, true, info.getTest()), testValue1.hash());
1725         }
1726     }
1727 
1728     @ForceInline
1729     public Object test68_helper(Object arg) {
1730         MyValue1 tmp = (MyValue1)arg; // Result of cast is unused
1731         return arg;
1732     }
1733 
1734     // Test that scalarization enabled by cast is applied to parsing map
1735     @Test
1736     @IR(failOn = {ALLOC, STORE})
1737     public int test68(boolean b1, boolean b2, Object arg, Method m) {
1738         Object val = MyValue1.createWithFieldsInline(rI, rL);
1739         if (b1) {
1740             val = test68_helper(arg);
1741         }
1742         if (b2) {
1743             // Uncommon trap
1744             TestFramework.deoptimize(m);
1745         }
1746         return ((MyValue1)val).x;
1747     }
1748 
1749     @Run(test = "test68")
1750     public void test68_verifier(RunInfo info) {
1751         MyValue1 arg = MyValue1.createWithFieldsInline(rI+1, rL+1);
1752         Asserts.assertEquals(test68(true, false, arg, info.getTest()), arg.x);
1753         Asserts.assertEquals(test68(false, false, arg, info.getTest()), testValue1.x);
1754         if (!info.isWarmUp()) {
1755             try {
1756                 Asserts.assertEquals(test68(false, false, arg, info.getTest()), testValue1.x);
1757                 test68(true, false, null, info.getTest());
1758                 throw new RuntimeException("NullPointerException expected");
1759             } catch (NullPointerException e) {
1760                 // Expected
1761             }
1762             Asserts.assertEquals(test68(true, true, arg, info.getTest()), arg.x);
1763             Asserts.assertEquals(test68(false, true, arg, info.getTest()), testValue1.x);
1764         }
1765     }
1766 
1767     @ForceInline
1768     public Object test69_helper(Object arg) {
1769         MyValue1 tmp = (MyValue1)arg; // Result of cast is unused
1770         return arg;
1771     }
1772 
1773     // Same as test68 but with ClassCastException
1774     @Test
1775     @IR(failOn = {ALLOC, STORE})
1776     public int test69(boolean b1, boolean b2, Object arg, Method m) {
1777         Object val = MyValue1.createWithFieldsInline(rI, rL);
1778         if (b1) {
1779             val = test69_helper(arg);
1780         }
1781         if (b2) {
1782             // Uncommon trap
1783             TestFramework.deoptimize(m);
1784         }
1785         return ((MyValue1)val).x;
1786     }
1787 
1788     @Run(test = "test69")
1789     @Warmup(10000) // Make sure precise profile information is available
1790     public void test69_verifier(RunInfo info) {
1791         MyValue1 arg = MyValue1.createWithFieldsInline(rI+1, rL+1);
1792         Asserts.assertEquals(test69(true, false, arg, info.getTest()), arg.x);
1793         Asserts.assertEquals(test69(false, false, arg, info.getTest()), testValue1.x);
1794         try {
1795             test69(true, false, 42, info.getTest());
1796             throw new RuntimeException("ClassCastException expected");
1797         } catch (ClassCastException e) {
1798             // Expected
1799         }
1800         if (!info.isWarmUp()) {
1801             try {
1802                 Asserts.assertEquals(test69(false, false, arg, info.getTest()), testValue1.x);
1803                 test69(true, false, null, info.getTest());
1804                 throw new RuntimeException("NullPointerException expected");
1805             } catch (NullPointerException e) {
1806                 // Expected
1807             }
1808             Asserts.assertEquals(test69(true, true, arg, info.getTest()), arg.x);
1809             Asserts.assertEquals(test69(false, true, arg, info.getTest()), testValue1.x);
1810         }
1811     }
1812 
1813     @ForceInline
1814     public Object test70_helper(Object arg) {
1815         MyValue1 tmp = (MyValue1)arg; // Result of cast is unused
1816         return arg;
1817     }
1818 
1819     // Same as test68 but with ClassCastException and frequent NullPointerException
1820     @Test
1821     @IR(failOn = {ALLOC, STORE})
1822     public int test70(boolean b1, boolean b2, Object arg, Method m) {
1823         Object val = MyValue1.createWithFieldsInline(rI, rL);
1824         if (b1) {
1825             val = test70_helper(arg);
1826         }
1827         if (b2) {
1828             // Uncommon trap
1829             TestFramework.deoptimize(m);
1830         }
1831         return ((MyValue1)val).x;
1832     }
1833 
1834     @Run(test = "test70")
1835     @Warmup(10000) // Make sure precise profile information is available
1836     public void test70_verifier(RunInfo info) {
1837         MyValue1 arg = MyValue1.createWithFieldsInline(rI+1, rL+1);
1838         Asserts.assertEquals(test70(true, false, arg, info.getTest()), arg.x);
1839         Asserts.assertEquals(test70(false, false, arg, info.getTest()), testValue1.x);
1840         try {
1841             test70(true, false, 42, info.getTest());
1842             throw new RuntimeException("ClassCastException expected");
1843         } catch (ClassCastException e) {
1844             // Expected
1845         }
1846         try {
1847             Asserts.assertEquals(test70(false, false, arg, info.getTest()), testValue1.x);
1848             test70(true, false, null, info.getTest());
1849             throw new RuntimeException("NullPointerException expected");
1850         } catch (NullPointerException e) {
1851             // Expected
1852         }
1853         if (!info.isWarmUp()) {
1854             Asserts.assertEquals(test70(true, true, arg, info.getTest()), arg.x);
1855             Asserts.assertEquals(test70(false, true, arg, info.getTest()), testValue1.x);
1856         }
1857     }
1858 
1859     @ForceInline
1860     public Object test71_helper(Object arg) {
1861         MyValue1 tmp = (MyValue1)arg; // Result of cast is unused
1862         return arg;
1863     }
1864 
1865     // Same as test68 but with .ref cast
1866     @Test
1867     @IR(failOn = {ALLOC, STORE})
1868     public int test71(boolean b1, boolean b2, Object arg, Method m) {
1869         Object val = MyValue1.createWithFieldsInline(rI, rL);
1870         if (b1) {
1871             val = test71_helper(arg);
1872         }
1873         if (b2) {
1874             // Uncommon trap
1875             TestFramework.deoptimize(m);
1876         }
1877         return ((MyValue1)val).x;
1878     }
1879 
1880     @Run(test = "test71")
1881     public void test71_verifier(RunInfo info) {
1882         MyValue1 arg = MyValue1.createWithFieldsInline(rI+1, rL+1);
1883         Asserts.assertEquals(test71(true, false, arg, info.getTest()), arg.x);
1884         Asserts.assertEquals(test71(false, false, arg, info.getTest()), testValue1.x);
1885         if (!info.isWarmUp()) {
1886             try {
1887                 Asserts.assertEquals(test71(false, false, arg, info.getTest()), testValue1.x);
1888                 test71(true, false, null, info.getTest());
1889                 throw new RuntimeException("NullPointerException expected");
1890             } catch (NullPointerException e) {
1891                 // Expected
1892             }
1893             Asserts.assertEquals(test71(true, true, arg, info.getTest()), arg.x);
1894             Asserts.assertEquals(test71(false, true, arg, info.getTest()), testValue1.x);
1895         }
1896     }
1897 
1898     @ForceInline
1899     public Object test72_helper(Object arg) {
1900         MyValue1 tmp = (MyValue1)arg; // Result of cast is unused
1901         return arg;
1902     }
1903 
1904     // Same as test71 but with ClassCastException and hash() call
1905     @Test
1906     @IR(failOn = {ALLOC, STORE})
1907     public long test72(boolean b1, boolean b2, Object arg, Method m) {
1908         Object val = MyValue1.createWithFieldsInline(rI, rL);
1909         if (b1) {
1910             val = test72_helper(arg);
1911         }
1912         if (b2) {
1913             // Uncommon trap
1914             TestFramework.deoptimize(m);
1915         }
1916         return ((MyValue1)val).hash();
1917     }
1918 
1919     @Run(test = "test72")
1920     @Warmup(10000) // Make sure precise profile information is available
1921     public void test72_verifier(RunInfo info) {
1922         MyValue1 arg = MyValue1.createWithFieldsInline(rI+1, rL+1);
1923         Asserts.assertEquals(test72(true, false, arg, info.getTest()), arg.hash());
1924         Asserts.assertEquals(test72(false, false, arg, info.getTest()), testValue1.hash());
1925         try {
1926             test72(true, false, 42, info.getTest());
1927             throw new RuntimeException("ClassCastException expected");
1928         } catch (ClassCastException e) {
1929             // Expected
1930         }
1931         if (!info.isWarmUp()) {
1932             try {
1933                 Asserts.assertEquals(test72(false, false, arg, info.getTest()), testValue1.hash());
1934                 test72(true, false, null, info.getTest());
1935                 throw new RuntimeException("NullPointerException expected");
1936             } catch (NullPointerException e) {
1937                 // Expected
1938             }
1939             Asserts.assertEquals(test72(true, true, arg, info.getTest()), arg.hash());
1940             Asserts.assertEquals(test72(false, true, arg, info.getTest()), testValue1.hash());
1941         }
1942     }
1943 
1944     @ForceInline
1945     public Object test73_helper(Object arg) {
1946         MyValue1 tmp = (MyValue1)arg; // Result of cast is unused
1947         return arg;
1948     }
1949 
1950     // Same as test71 but with ClassCastException and frequent NullPointerException
1951     @Test
1952     @IR(failOn = {ALLOC, STORE})
1953     public int test73(boolean b1, boolean b2, Object arg, Method m) {
1954         Object val = MyValue1.createWithFieldsInline(rI, rL);
1955         if (b1) {
1956             val = test73_helper(arg);
1957         }
1958         if (b2) {
1959             // Uncommon trap
1960             TestFramework.deoptimize(m);
1961         }
1962         return ((MyValue1)val).x;
1963     }
1964 
1965     @Run(test = "test73")
1966     @Warmup(10000) // Make sure precise profile information is available
1967     public void test73_verifier(RunInfo info) {
1968         MyValue1 arg = MyValue1.createWithFieldsInline(rI+1, rL+1);
1969         Asserts.assertEquals(test73(true, false, arg, info.getTest()), arg.x);
1970         Asserts.assertEquals(test73(false, false, arg, info.getTest()), testValue1.x);
1971         try {
1972             test73(true, false, 42, info.getTest());
1973             throw new RuntimeException("ClassCastException expected");
1974         } catch (ClassCastException e) {
1975             // Expected
1976         }
1977         try {
1978             Asserts.assertEquals(test73(false, false, arg, info.getTest()), testValue1.x);
1979             test73(true, false, null, info.getTest());
1980             throw new RuntimeException("NullPointerException expected");
1981         } catch (NullPointerException e) {
1982             // Expected
1983         }
1984         if (!info.isWarmUp()) {
1985             Asserts.assertEquals(test73(true, true, arg, info.getTest()), arg.x);
1986             Asserts.assertEquals(test73(false, true, arg, info.getTest()), testValue1.x);
1987         }
1988     }
1989 
1990     @ForceInline
1991     public Object test74_helper(Object arg) {
1992         return (MyValue1)arg;
1993     }
1994 
1995     // Same as test73 but result of cast is used and hash() is called
1996     @Test
1997     @IR(failOn = {ALLOC, STORE})
1998     public long test74(boolean b1, boolean b2, Object arg, Method m) {
1999         Object val = MyValue1.createWithFieldsInline(rI, rL);
2000         if (b1) {
2001             val = test74_helper(arg);
2002         }
2003         if (b2) {
2004             // Uncommon trap
2005             TestFramework.deoptimize(m);
2006         }
2007         return ((MyValue1)val).hash();
2008     }
2009 
2010     @Run(test = "test74")
2011     @Warmup(10000) // Make sure precise profile information is available
2012     public void test74_verifier(RunInfo info) {
2013         MyValue1 arg = MyValue1.createWithFieldsInline(rI+1, rL+1);
2014         Asserts.assertEquals(test74(true, false, arg, info.getTest()), arg.hash());
2015         Asserts.assertEquals(test74(false, false, arg, info.getTest()), testValue1.hash());
2016         try {
2017             test74(true, false, 42, info.getTest());
2018             throw new RuntimeException("ClassCastException expected");
2019         } catch (ClassCastException e) {
2020             // Expected
2021         }
2022         try {
2023             Asserts.assertEquals(test74(false, false, arg, info.getTest()), testValue1.hash());
2024             test74(true, false, null, info.getTest());
2025             throw new RuntimeException("NullPointerException expected");
2026         } catch (NullPointerException e) {
2027             // Expected
2028         }
2029         if (!info.isWarmUp()) {
2030             Asserts.assertEquals(test74(true, true, arg, info.getTest()), arg.hash());
2031             Asserts.assertEquals(test74(false, true, arg, info.getTest()), testValue1.hash());
2032         }
2033     }
2034 
2035     // Test new merge path being added for exceptional control flow
2036     @Test
2037     @IR(failOn = {ALLOC})
2038     public MyValue1 test75(MyValue1 vt, Object obj) {
2039         try {
2040             vt = (MyValue1)obj;
2041             throw new RuntimeException("ClassCastException expected");
2042         } catch (ClassCastException e) {
2043             // Expected
2044         }
2045         return vt;
2046     }
2047 
2048     @Run(test = "test75")
2049     public void test75_verifier() {
2050         MyValue1 vt = testValue1;
2051         MyValue1 result = test75(vt, Integer.valueOf(rI));
2052         Asserts.assertEquals(result.hash(), vt.hash());
2053     }
2054 
2055     @ForceInline
2056     public Object test76_helper() {
2057         return constNullRefField;
2058     }
2059 
2060     // Test that constant null field does not block scalarization
2061     @Test
2062     @IR(failOn = {ALLOC, LOAD, STORE})
2063     public long test76(boolean b1, boolean b2, Method m) {
2064         Object val = MyValue1.createWithFieldsInline(rI, rL);
2065         if (b1) {
2066             val = test76_helper();
2067         }
2068         if (b2) {
2069             // Uncommon trap
2070             TestFramework.deoptimize(m);
2071         }
2072         val = Objects.requireNonNull(val);
2073         return ((MyValue1)val).hash();
2074     }
2075 
2076     @Run(test = "test76")
2077     public void test76_verifier(RunInfo info) {
2078         Asserts.assertEquals(test76(false, false, info.getTest()), testValue1.hash());
2079         try {
2080             test76(true, false, info.getTest());
2081             throw new RuntimeException("NullPointerException expected");
2082         } catch (NullPointerException e) {
2083             // Expected
2084         }
2085         if (!info.isWarmUp()) {
2086             Asserts.assertEquals(test76(false, true, info.getTest()), testValue1.hash());
2087             try {
2088                 test76(true, true, info.getTest());
2089                 throw new RuntimeException("NullPointerException expected");
2090             } catch (NullPointerException e) {
2091                 // Expected
2092             }
2093         }
2094     }
2095 
2096     private static final Object constObjectValField = MyValue1.createWithFieldsInline(rI+1, rL+1);
2097 
2098     @ForceInline
2099     public Object test77_helper() {
2100         return constObjectValField;
2101     }
2102 
2103     // Test that constant object field with value class content does not block scalarization
2104     @Test
2105     @IR(failOn = {ALLOC, LOAD, STORE})
2106     public long test77(boolean b1, boolean b2, Method m) {
2107         Object val = MyValue1.createWithFieldsInline(rI, rL);
2108         if (b1) {
2109             val = test77_helper();
2110         }
2111         if (b2) {
2112             // Uncommon trap
2113             TestFramework.deoptimize(m);
2114         }
2115         return ((MyValue1)val).hash();
2116     }
2117 
2118     @Run(test = "test77")
2119     public void test77_verifier(RunInfo info) {
2120         Asserts.assertEquals(test77(true, false, info.getTest()), ((MyValue1)constObjectValField).hash());
2121         Asserts.assertEquals(test77(false, false, info.getTest()), testValue1.hash());
2122         if (!info.isWarmUp()) {
2123           Asserts.assertEquals(test77(true, false, info.getTest()), ((MyValue1)constObjectValField).hash());
2124           Asserts.assertEquals(test77(false, false, info.getTest()), testValue1.hash());
2125         }
2126     }
2127 
2128     @ForceInline
2129     public Object test78_helper() {
2130         return null;
2131     }
2132 
2133     // Test that constant null does not block scalarization
2134     @Test
2135     @IR(failOn = {ALLOC, LOAD, STORE})
2136     public long test78(boolean b1, boolean b2, Method m) {
2137         Object val = MyValue1.createWithFieldsInline(rI, rL);
2138         if (b1) {
2139             val = test78_helper();
2140         }
2141         if (b2) {
2142             // Uncommon trap
2143             TestFramework.deoptimize(m);
2144         }
2145         val = Objects.requireNonNull(val);
2146         return ((MyValue1)val).hash();
2147     }
2148 
2149     @Run(test = "test78")
2150     public void test78_verifier(RunInfo info) {
2151         Asserts.assertEquals(test78(false, false, info.getTest()), testValue1.hash());
2152         try {
2153             test78(true, false, info.getTest());
2154             throw new RuntimeException("NullPointerException expected");
2155         } catch (NullPointerException e) {
2156             // Expected
2157         }
2158         if (!info.isWarmUp()) {
2159             Asserts.assertEquals(test78(false, true, info.getTest()), testValue1.hash());
2160             try {
2161                 test78(true, true, info.getTest());
2162                 throw new RuntimeException("NullPointerException expected");
2163             } catch (NullPointerException e) {
2164                 // Expected
2165             }
2166         }
2167     }
2168 
2169     @ForceInline
2170     public Object test79_helper() {
2171         return null;
2172     }
2173 
2174     // Same as test78 but will trigger different order of PhiNode inputs
2175     @Test
2176     @IR(failOn = {ALLOC, LOAD, STORE})
2177     public long test79(boolean b1, boolean b2, Method m) {
2178         Object val = test79_helper();
2179         if (b1) {
2180             val = MyValue1.createWithFieldsInline(rI, rL);
2181         }
2182         if (b2) {
2183             // Uncommon trap
2184             TestFramework.deoptimize(m);
2185         }
2186         val = Objects.requireNonNull(val);
2187         return ((MyValue1)val).hash();
2188     }
2189 
2190     @Run(test = "test79")
2191     public void test79_verifier(RunInfo info) {
2192         Asserts.assertEquals(test79(true, false, info.getTest()), testValue1.hash());
2193         try {
2194             test79(false, false, info.getTest());
2195             throw new RuntimeException("NullPointerException expected");
2196         } catch (NullPointerException e) {
2197             // Expected
2198         }
2199         if (!info.isWarmUp()) {
2200             Asserts.assertEquals(test79(true, true, info.getTest()), testValue1.hash());
2201             try {
2202                 test79(false, true, info.getTest());
2203                 throw new RuntimeException("NullPointerException expected");
2204             } catch (NullPointerException e) {
2205                 // Expected
2206             }
2207         }
2208     }
2209 
2210     @ForceInline
2211     public Object test80_helper(Object obj, int i) {
2212         if ((i % 2) == 0) {
2213             return MyValue1.createWithFieldsInline(i, i);
2214         }
2215         return obj;
2216     }
2217 
2218     // Test that phi nodes referencing themselves (loops) do not block scalarization
2219     @Test
2220     @IR(failOn = {ALLOC, LOAD, STORE})
2221     public long test80() {
2222         Object val = MyValue1.createWithFieldsInline(rI, rL);
2223         for (int i = 0; i < 100; ++i) {
2224             val = test80_helper(val, i);
2225         }
2226         return ((MyValue1)val).hash();
2227     }
2228 
2229     private long test80Result = 0;
2230 
2231     @Run(test = "test80")
2232     public void test80_verifier() {
2233         if (test80Result == 0) {
2234             test80Result = test80();
2235         }
2236         Asserts.assertEquals(test80(), test80Result);
2237     }
2238 
2239 // TODO 8325106 Fails because they are not compilable with Scenario 3, probably we run out of nodes ...
2240 /*
2241     @ForceInline
2242     public Object test81_helper(Object obj, int i) {
2243         if ((i % 2) == 0) {
2244             return MyValue1.createWithFieldsInline(i, i);
2245         }
2246         return obj;
2247     }
2248 
2249     // Test nested loops
2250     @Test
2251     @IR(failOn = {ALLOC, LOAD, STORE})
2252     public long test81() {
2253         Object val = null;
2254         for (int i = 0; i < 10; ++i) {
2255             for (int j = 0; j < 10; ++j) {
2256                 for (int k = 0; k < 10; ++k) {
2257                     val = test81_helper(val, i + j + k);
2258                 }
2259                 val = test81_helper(val, i + j);
2260             }
2261             val = test81_helper(val, i);
2262         }
2263         return ((MyValue1)val).hash();
2264     }
2265 
2266     private long test81Result = 0;
2267 
2268     @Run(test = "test81")
2269     public void test81_verifier() {
2270         if (test81Result == 0) {
2271             test81Result = test81();
2272         }
2273         Asserts.assertEquals(test81(), test81Result);
2274     }
2275 
2276     @ForceInline
2277     public Object test82_helper(Object obj, int i) {
2278         if ((i % 2) == 0) {
2279             return MyValue1.createWithFieldsInline(i, i);
2280         }
2281         return obj;
2282     }
2283 
2284     // Test loops with casts
2285     @Test
2286     @IR(failOn = {ALLOC, LOAD, STORE})
2287     public long test82() {
2288         Object val = null;
2289         for (int i = 0; i < 10; ++i) {
2290             for (int j = 0; j < 10; ++j) {
2291                 for (int k = 0; k < 10; ++k) {
2292                     val = test82_helper(val, i + j + k);
2293                 }
2294                 if (val != null) {
2295                     val = test82_helper(val, i + j);
2296                 }
2297             }
2298             val = test82_helper(val, i);
2299         }
2300         return ((MyValue1)val).hash();
2301     }
2302 
2303     private long test82Result = 0;
2304 
2305     @Run(test = "test82")
2306     public void test82_verifier() {
2307         if (test82Result == 0) {
2308             test82Result = test81();
2309         }
2310         Asserts.assertEquals(test82(), test82Result);
2311     }
2312 */
2313 
2314     @ForceInline
2315     public Object test83_helper(boolean b) {
2316         if (b) {
2317             return MyValue1.createWithFieldsInline(rI, rL);
2318         }
2319         return null;
2320     }
2321 
2322     // Test that CastPP does not block sclarization in safepoints
2323     @Test
2324     @IR(failOn = {ALLOC, LOAD, STORE})
2325     public long test83(boolean b, Method m) {
2326         Object val = test83_helper(b);
2327         if (val != null) {
2328             // Uncommon trap
2329             TestFramework.deoptimize(m);
2330             return ((MyValue1)val).hash();
2331         }
2332         return 0;
2333     }
2334 
2335     @Run(test = "test83")
2336     public void test83_verifier(RunInfo info) {
2337         Asserts.assertEquals(test83(false, info.getTest()), 0L);
2338         if (!info.isWarmUp()) {
2339             Asserts.assertEquals(test83(true, info.getTest()), testValue1.hash());
2340         }
2341     }
2342 
2343     @ForceInline
2344     public Object test84_helper(Object obj, int i) {
2345         if ((i % 2) == 0) {
2346             return new MyValue1Wrapper(MyValue1.createWithFieldsInline(i, i));
2347         }
2348         return obj;
2349     }
2350 
2351     // Same as test80 but with wrapper
2352     @Test
2353     @IR(failOn = {ALLOC, LOAD, STORE})
2354     public long test84() {
2355         Object val = new MyValue1Wrapper(MyValue1.createWithFieldsInline(rI, rL));
2356         for (int i = 0; i < 100; ++i) {
2357             val = test84_helper(val, i);
2358         }
2359         return ((MyValue1Wrapper)val).vt.hash();
2360     }
2361 
2362     private long test84Result = 0;
2363 
2364     @Run(test = "test84")
2365     public void test84_verifier() {
2366         if (test84Result == 0) {
2367             test84Result = test84();
2368         }
2369         Asserts.assertEquals(test84(), test84Result);
2370     }
2371 
2372     @ForceInline
2373     public Object test85_helper(Object obj, int i) {
2374         if ((i % 2) == 0) {
2375             return new MyValue1Wrapper(MyValue1.createWithFieldsInline(i, i));
2376         }
2377         return obj;
2378     }
2379 
2380 // TODO 8325106 Fails because they are not compilable with Scenario 3, probably we run out of nodes ...
2381 /*
2382     // Same as test81 but with wrapper
2383     @Test
2384     // TODO 8325106 Fails with Scenario 5
2385     // @IR(failOn = {ALLOC, LOAD, STORE})
2386     public long test85() {
2387         Object val = new MyValue1Wrapper(null);
2388         for (int i = 0; i < 10; ++i) {
2389             for (int j = 0; j < 10; ++j) {
2390                 for (int k = 0; k < 10; ++k) {
2391                     val = test85_helper(val, i + j + k);
2392                 }
2393                 val = test85_helper(val, i + j);
2394             }
2395             val = test85_helper(val, i);
2396         }
2397         MyValue1 vt = ((MyValue1Wrapper)val).vt;
2398         vt = Objects.requireNonNull(vt);
2399         return vt.hash();
2400     }
2401 
2402     private long test85Result = 0;
2403 
2404     @Run(test = "test85")
2405     public void test85_verifier() {
2406         if (test85Result == 0) {
2407             test85Result = test85();
2408         }
2409         Asserts.assertEquals(test85(), test85Result);
2410     }
2411 */
2412 
2413     static final class ObjectWrapper {
2414         public Object obj;
2415 
2416         @ForceInline
2417         public ObjectWrapper(Object obj) {
2418             this.obj = obj;
2419         }
2420     }
2421 
2422     // Test scalarization with phi referencing itself
2423     @Test
2424     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2425         failOn = {ALLOC, STORE},
2426         counts = {LOAD, " = 4"}) // 4 loads from the non-flattened MyValue1.v4 fields
2427     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2428         failOn = {ALLOC, STORE})
2429     public long test86(MyValue1 vt) {
2430         ObjectWrapper val = new ObjectWrapper(vt);
2431         for (int i = 0; i < 10; ++i) {
2432             for (int j = 0; j < 10; ++j) {
2433                 val.obj = val.obj;
2434             }
2435         }
2436         return ((MyValue1)val.obj).hash();
2437     }
2438 
2439     @Run(test = "test86")
2440     public void test86_verifier() {
2441         test86(testValue1);
2442         Asserts.assertEquals(test86(testValue1), testValue1.hash());
2443     }
2444 
2445     @ImplicitlyConstructible
2446     @LooselyConsistentValue
2447     public static value class Test87C0 {
2448         int x = 0;
2449     }
2450 
2451     @ImplicitlyConstructible
2452     @LooselyConsistentValue
2453     public static value class Test87C1 {
2454         @NullRestricted
2455         Test87C0 field = new Test87C0();
2456     }
2457 
2458     @ImplicitlyConstructible
2459     @LooselyConsistentValue
2460     public static value class Test87C2 {
2461         @NullRestricted
2462         Test87C1 field = new Test87C1();
2463     }
2464 
2465     // Test merging field loads in return
2466     @Test
2467     public Test87C1 test87(boolean b, Test87C2 v1, Test87C2 v2) {
2468         if (b) {
2469             return v1.field;
2470         } else {
2471             return v2.field;
2472         }
2473     }
2474 
2475     @Run(test = "test87")
2476     public void test87_verifier() {
2477         Test87C2 v = new Test87C2();
2478         Asserts.assertEQ(test87(true, v, v), v.field);
2479         Asserts.assertEQ(test87(false, v, v), v.field);
2480     }
2481 
2482     @ImplicitlyConstructible
2483     @LooselyConsistentValue
2484     static value class Test88Value {
2485         int x = 0;
2486     }
2487 
2488     static class Test88MyClass {
2489         int x = 0;
2490         int y = rI;
2491     }
2492 
2493     @ForceInline
2494     Object test88Helper() {
2495         return new Test88Value();
2496     }
2497 
2498     // Test LoadNode::Identity optimization with always failing checkcast
2499     @Test
2500     public int test88() {
2501         Object obj = test88Helper();
2502         return ((Test88MyClass)obj).y;
2503     }
2504 
2505     @Run(test = "test88")
2506     public void test88_verifier() {
2507         try {
2508             test88();
2509             throw new RuntimeException("No ClassCastException thrown");
2510         } catch (ClassCastException e) {
2511             // Expected
2512         }
2513     }
2514 
2515     // Same as test88 but with Phi
2516     @Test
2517     public int test89(boolean b) {
2518         Test88MyClass obj = b ? (Test88MyClass)test88Helper() : (Test88MyClass)test88Helper();
2519         return obj.y;
2520     }
2521 
2522     @Run(test = "test89")
2523     public void test89_verifier() {
2524         try {
2525             test89(false);
2526             throw new RuntimeException("No ClassCastException thrown");
2527         } catch (ClassCastException e) {
2528             // Expected
2529         }
2530         try {
2531             test89(true);
2532             throw new RuntimeException("No ClassCastException thrown");
2533         } catch (ClassCastException e) {
2534             // Expected
2535         }
2536     }
2537 
2538     @ForceInline
2539     public boolean test90_inline(MyValue1 vt) {
2540         return vt == null;
2541     }
2542 
2543     // Test scalarization with speculative NULL type
2544     @Test
2545     @IR(failOn = {ALLOC})
2546     public boolean test90(Method m) throws Exception {
2547         Object arg = null;
2548         return (boolean)m.invoke(this, arg);
2549     }
2550 
2551     @Run(test = "test90")
2552     @Warmup(10000)
2553     public void test90_verifier() throws Exception {
2554         Method m = getClass().getMethod("test90_inline", MyValue1.class);
2555         Asserts.assertTrue(test90(m));
2556     }
2557 
2558     // Test that scalarization does not introduce redundant/unused checks
2559     @Test
2560     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2561         failOn = {ALLOC, CMPP})
2562     public Object test91(MyValue1 vt) {
2563         return vt;
2564     }
2565 
2566     @Run(test = "test91")
2567     public void test91_verifier() {
2568         Asserts.assertEQ(test91(testValue1), testValue1);
2569     }
2570 
2571     MyValue1 test92Field = testValue1;
2572 
2573     // Same as test91 but with field access
2574     @Test
2575     @IR(failOn = {ALLOC, CMPP})
2576     public Object test92() {
2577         return test92Field;
2578     }
2579 
2580     @Run(test = "test92")
2581     public void test92_verifier() {
2582         Asserts.assertEQ(test92(), testValue1);
2583     }
2584 
2585     private static final MethodHandle refCheckCast = OldInstructionHelper.loadCode(MethodHandles.lookup(),
2586         "refCheckCast",
2587         MethodType.methodType(MyValue2.class, TestNullableInlineTypes.class, MyValue1.class),
2588         CODE -> {
2589             CODE.
2590             aload_1().
2591             checkcast(MyValue2.class).
2592             return_(TypeTag.A);
2593         });
2594 
2595     // Test checkcast that only passes with null
2596     @Test
2597     public Object test93(MyValue1 vt) throws Throwable {
2598         return refCheckCast.invoke(this, vt);
2599     }
2600 
2601     @Run(test = "test93")
2602     @Warmup(10000)
2603     public void test93_verifier() throws Throwable {
2604         Asserts.assertEQ(test93(null), null);
2605     }
2606 
2607     @DontInline
2608     public MyValue1 test94_helper1(MyValue1 vt) {
2609         return vt;
2610     }
2611 
2612     @ForceInline
2613     public MyValue1 test94_helper2(MyValue1 vt) {
2614         return test94_helper1(vt);
2615     }
2616 
2617     @ForceInline
2618     public MyValue1 test94_helper3(Object vt) {
2619         return test94_helper2((MyValue1)vt);
2620     }
2621 
2622     // Test that calling convention optimization prevents buffering of arguments
2623     @Test
2624     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2625         counts = {ALLOC_G, " = 2"}) // 1 MyValue2 allocation + 1 Integer allocation
2626     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2627         counts = {ALLOC_G, " = 3"}) // 1 MyValue1 allocation + 1 MyValue2 allocation + 1 Integer allocation
2628     public MyValue1 test94(MyValue1 vt) {
2629         MyValue1 res = test94_helper1(vt);
2630         vt = MyValue1.createWithFieldsInline(rI, rL);
2631         test94_helper1(vt);
2632         test94_helper2(vt);
2633         test94_helper3(vt);
2634         return res;
2635     }
2636 
2637     @Run(test = "test94")
2638     public void test94_verifier() {
2639         Asserts.assertEQ(test94(testValue1), testValue1);
2640         Asserts.assertEQ(test94(null), null);
2641     }
2642 
2643     @DontInline
2644     public static MyValue1 test95_helper1(MyValue1 vt) {
2645         return vt;
2646     }
2647 
2648     @ForceInline
2649     public static MyValue1 test95_helper2(MyValue1 vt) {
2650         return test95_helper1(vt);
2651     }
2652 
2653     @ForceInline
2654     public static MyValue1 test95_helper3(Object vt) {
2655         return test95_helper2((MyValue1)vt);
2656     }
2657 
2658     // Same as test94 but with static methods to trigger simple adapter logic
2659     @Test
2660     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "true"},
2661         counts = {ALLOC_G, " = 2"}) // 1 MyValue2 allocation + 1 Integer allocation
2662     @IR(applyIf = {"InlineTypePassFieldsAsArgs", "false"},
2663         counts = {ALLOC_G, " = 3"}) // 1 MyValue1 allocation + 1 MyValue2 allocation + 1 Integer allocation
2664     public static MyValue1 test95(MyValue1 vt) {
2665         MyValue1 res = test95_helper1(vt);
2666         vt = MyValue1.createWithFieldsInline(rI, rL);
2667         test95_helper1(vt);
2668         test95_helper2(vt);
2669         test95_helper3(vt);
2670         return res;
2671     }
2672 
2673     @Run(test = "test95")
2674     public void test95_verifier() {
2675         Asserts.assertEQ(test95(testValue1), testValue1);
2676         Asserts.assertEQ(test95(null), null);
2677     }
2678 
2679     @DontInline
2680     public MyValue2 test96_helper1(boolean b) {
2681         return b ? null : MyValue2.createWithFieldsInline(rI, rD);
2682     }
2683 
2684     @ForceInline
2685     public MyValue2 test96_helper2() {
2686         return null;
2687     }
2688 
2689     @ForceInline
2690     public MyValue2 test96_helper3(boolean b) {
2691         return b ? null : MyValue2.createWithFieldsInline(rI, rD);
2692     }
2693 
2694     // Test that calling convention optimization prevents buffering of return values
2695     @Test
2696     @IR(applyIf = {"InlineTypeReturnedAsFields", "true"},
2697         failOn = {ALLOC_G})
2698     @IR(applyIf = {"InlineTypeReturnedAsFields", "false"},
2699         counts = {ALLOC_G, " = 1"})
2700     public MyValue2 test96(int c, boolean b) {
2701         MyValue2 res = null;
2702         if (c == 1) {
2703             res = test96_helper1(b);
2704         } else if (c == 2) {
2705             res = test96_helper2();
2706         } else if (c == 3) {
2707             res = test96_helper3(b);
2708         }
2709         return res;
2710     }
2711 
2712     @Run(test = "test96")
2713     public void test96_verifier() {
2714         Asserts.assertEQ(test96(0, false), null);
2715         Asserts.assertEQ(test96(1, false).hash(), MyValue2.createWithFieldsInline(rI, rD).hash());
2716         Asserts.assertEQ(test96(1, true), null);
2717         Asserts.assertEQ(test96(2, false), null);
2718         Asserts.assertEQ(test96(3, false).hash(), MyValue2.createWithFieldsInline(rI, rD).hash());
2719         Asserts.assertEQ(test96(3, true), null);
2720     }
2721 
2722     @DontInline
2723     public MyValue3 test97_helper1(boolean b) {
2724         return b ? null: MyValue3.create();
2725     }
2726 
2727     @ForceInline
2728     public MyValue3 test97_helper2() {
2729         return null;
2730     }
2731 
2732     @ForceInline
2733     public MyValue3 test97_helper3(boolean b) {
2734         return b ? null: MyValue3.create();
2735     }
2736 
2737     @NullRestricted
2738     MyValue3 test97_res1;
2739     @NullRestricted
2740     MyValue3 test97_res3;
2741 
2742     // Same as test96 but with MyValue3 return
2743     @Test
2744     @IR(applyIf = {"InlineTypeReturnedAsFields", "true"},
2745         counts = {ALLOC_G, " = 1"}) // 1 Object allocation
2746     @IR(applyIf = {"InlineTypeReturnedAsFields", "false"},
2747         counts = {ALLOC_G, " = 2"}) // 1 MyValue3 allocation + 1 Object allocation
2748     public MyValue3 test97(int c, boolean b) {
2749         MyValue3 res = null;
2750         if (c == 1) {
2751             res = test97_helper1(b);
2752             if (res != null) {
2753                 test97_res1 = res;
2754             }
2755         } else if (c == 2) {
2756             res = test97_helper2();
2757         } else if (c == 3) {
2758             res = test97_helper3(b);
2759             if (res != null) {
2760                 test97_res3 = res;
2761             }
2762         }
2763         return res;
2764     }
2765 
2766     @Run(test = "test97")
2767     public void test97_verifier() {
2768         Asserts.assertEQ(test97(0, false), null);
2769         Asserts.assertEQ(test97(1, false), test97_res1);
2770         Asserts.assertEQ(test97(1, true), null);
2771         Asserts.assertEQ(test97(2, false), null);
2772         Asserts.assertEQ(test97(3, false), test97_res3);
2773         Asserts.assertEQ(test97(3, true), null);
2774     }
2775 
2776     @ImplicitlyConstructible
2777     @LooselyConsistentValue
2778     static value class CircularValue1 {
2779         CircularValue1 val;
2780         int x;
2781 
2782         @ForceInline
2783         public CircularValue1(CircularValue1 val) {
2784             this.val = val;
2785             this.x = rI;
2786         }
2787     }
2788 
2789     // Test scalarization of value class with circularity in fields
2790     @Test
2791     public CircularValue1 test98(CircularValue1 val) {
2792         return new CircularValue1(val);
2793     }
2794 
2795     @Run(test = "test98")
2796     public void test98_verifier()  {
2797         CircularValue1 val = new CircularValue1(null);
2798         CircularValue1 res = test98(val);
2799         Asserts.assertEQ(res.x, rI);
2800         Asserts.assertEQ(res.val, val);
2801     }
2802 
2803     @ImplicitlyConstructible
2804     @LooselyConsistentValue
2805     static value class CircularValue2 {
2806         @NullRestricted
2807         CircularValue1 val;
2808 
2809         @ForceInline
2810         public CircularValue2(CircularValue1 val) {
2811             this.val = val;
2812         }
2813     }
2814 
2815     // Same as test98 but with circularity in class of flattened field
2816     @Test
2817     public CircularValue2 test99(CircularValue2 val) {
2818         return new CircularValue2(val.val);
2819     }
2820 
2821     @Run(test = "test99")
2822     public void test99_verifier()  {
2823         CircularValue1 val1 = new CircularValue1(null);
2824         CircularValue2 val2 = new CircularValue2(val1);
2825         CircularValue2 res = test99(val2);
2826         Asserts.assertEQ(res.val, val1);
2827     }
2828 
2829     @ImplicitlyConstructible
2830     @LooselyConsistentValue
2831     static value class CircularValue3 {
2832         CircularValue4 val;
2833         int x;
2834 
2835         @ForceInline
2836         public CircularValue3(CircularValue4 val, int x) {
2837             this.val = val;
2838             this.x = x;
2839         }
2840     }
2841 
2842     @ImplicitlyConstructible
2843     @LooselyConsistentValue
2844     static value class CircularValue4 {
2845         @NullRestricted
2846         CircularValue3 val;
2847 
2848         @ForceInline
2849         public CircularValue4(CircularValue3 val) {
2850             this.val = val;
2851         }
2852     }
2853 
2854     // Same as test94 but with "indirect" circularity through field of flattened field
2855     @Test
2856     public CircularValue4 test100(CircularValue4 val) {
2857         return new CircularValue4(new CircularValue3(val, rI));
2858     }
2859 
2860     @Run(test = "test100")
2861     public void test100_verifier()  {
2862         CircularValue3 val3 = new CircularValue3(null, 42);
2863         CircularValue4 val4 = new CircularValue4(val3);
2864         CircularValue4 res = test100(val4);
2865         Asserts.assertEQ(res.val, new CircularValue3(val4, rI));
2866     }
2867 
2868     @ImplicitlyConstructible
2869     @LooselyConsistentValue
2870     static value class CircularValue5 {
2871         @NullRestricted
2872         CircularValue6 val;
2873         int x;
2874 
2875         @ForceInline
2876         public CircularValue5(CircularValue6 val, int x) {
2877             this.val = val;
2878             this.x = x;
2879         }
2880     }
2881 
2882     @ImplicitlyConstructible
2883     @LooselyConsistentValue
2884     static value class CircularValue6 {
2885         CircularValue5 val;
2886 
2887         @ForceInline
2888         public CircularValue6(CircularValue5 val) {
2889             this.val = val;
2890         }
2891     }
2892 
2893     // Same as test100 but with different combination of field types
2894     @Test
2895     public CircularValue6 test101(CircularValue6 val) {
2896         return new CircularValue6(new CircularValue5(val, rI));
2897     }
2898 
2899     @Run(test = "test101")
2900     public void test101_verifier()  {
2901         CircularValue5 val5 = new CircularValue5(new CircularValue6(null), 42);
2902         CircularValue6 val6 = new CircularValue6(val5);
2903         CircularValue6 res = test101(val6);
2904         Asserts.assertEQ(res.val, new CircularValue5(val6, rI));
2905     }
2906 
2907     // Test merging of fields with different scalarization depth
2908     @Test
2909     public CircularValue1 test102(boolean b) {
2910         CircularValue1 val = new CircularValue1(new CircularValue1(null));
2911         if (b) {
2912             val = null;
2913         }
2914         return val;
2915     }
2916 
2917     @Run(test = "test102")
2918     public void test102_verifier() {
2919         Asserts.assertEQ(test102(false), new CircularValue1(new CircularValue1(null)));
2920         Asserts.assertEQ(test102(true), null);
2921     }
2922 
2923     // Might be incrementally inlined
2924     public static Object hide(Object obj) {
2925         return (MyValue1)obj;
2926     }
2927 
2928     // Test that the ConstraintCastNode::Ideal transformation propagates null-free information
2929     @Test
2930     public MyValue1 test103() {
2931         Object obj = hide(null);
2932         return (MyValue1)obj;
2933     }
2934 
2935     @Run(test = "test103")
2936     public void test103_verifier() {
2937         Asserts.assertEQ(test103(), null);
2938     }
2939 
2940     // Test null restricted fields
2941 
2942     @ImplicitlyConstructible
2943     @LooselyConsistentValue
2944     static value class MyValue104 {
2945         @NullRestricted
2946         static MyValue105 field1;
2947 
2948         @NullRestricted
2949         MyValue105 field2;
2950 
2951         @NullRestricted
2952         static MyValueEmpty field3;
2953 
2954         @NullRestricted
2955         MyValueEmpty field4;
2956 
2957         @ForceInline
2958         public MyValue104() {
2959             this.field1 = new MyValue105();
2960             this.field2 = new MyValue105();
2961             this.field3 = new MyValueEmpty();
2962             this.field4 = new MyValueEmpty();
2963         }
2964 
2965         @ForceInline
2966         public MyValue104(MyValue105 val1, MyValue105 val2, MyValueEmpty val3, MyValueEmpty val4) {
2967             this.field1 = val1;
2968             this.field2 = val2;
2969             this.field3 = val3;
2970             this.field4 = val4;
2971         }
2972     }
2973 
2974     @ImplicitlyConstructible
2975     @LooselyConsistentValue
2976     static value class MyValue105 {
2977         int x = 42;
2978     }
2979 
2980     @NullRestricted
2981     static MyValue104 field1;
2982 
2983     @NullRestricted
2984     MyValue104 field2;
2985 
2986     @NullRestricted
2987     static MyValueEmpty field3;
2988 
2989     @NullRestricted
2990     MyValueEmpty field4;
2991 
2992     @Test
2993     void test105(MyValue104 arg) {
2994         field1 = arg;
2995     }
2996 
2997     @Run(test = "test105")
2998     public void test105_verifier() {
2999         try {
3000             test105(null);
3001             throw new RuntimeException("No exception thrown");
3002         } catch (NullPointerException e) {
3003             // Expected
3004         }
3005     }
3006 
3007     @Test
3008     void test106() {
3009         field1 = null;
3010     }
3011 
3012     @Run(test = "test106")
3013     public void test106_verifier() {
3014         try {
3015             test106();
3016             throw new RuntimeException("No exception thrown");
3017         } catch (NullPointerException e) {
3018             // Expected
3019         }
3020     }
3021 
3022     @Test
3023     void test107(MyValue104 arg) {
3024         field2 = arg;
3025     }
3026 
3027     @Run(test = "test107")
3028     public void test107_verifier() {
3029         try {
3030             test107(null);
3031             throw new RuntimeException("No exception thrown");
3032         } catch (NullPointerException e) {
3033             // Expected
3034         }
3035     }
3036 
3037     @Test
3038     void test108(TestNullableInlineTypes t, MyValue104 arg) {
3039         t.field2 = arg;
3040     }
3041 
3042     @Run(test = "test108")
3043     public void test108_verifier() {
3044         try {
3045             test108(null, new MyValue104());
3046             throw new RuntimeException("No exception thrown");
3047         } catch (NullPointerException e) {
3048             // Expected
3049         }
3050     }
3051 
3052     @Test
3053     void test109(MyValue104 arg) {
3054         TestNullableInlineTypes t = null;
3055         t.field2 = null;
3056     }
3057 
3058     @Run(test = "test109")
3059     public void test109_verifier() {
3060         try {
3061             test109(new MyValue104());
3062             throw new RuntimeException("No exception thrown");
3063         } catch (NullPointerException e) {
3064             // Expected
3065         }
3066     }
3067 
3068     @Test
3069     void test110() {
3070         field2 = null;
3071     }
3072 
3073     @Run(test = "test110")
3074     public void test110_verifier() {
3075         try {
3076             test110();
3077             throw new RuntimeException("No exception thrown");
3078         } catch (NullPointerException e) {
3079             // Expected
3080         }
3081     }
3082 
3083     @Test
3084     void test111(MyValueEmpty arg) {
3085         field3 = arg;
3086     }
3087 
3088     @Run(test = "test111")
3089     public void test111_verifier() {
3090         try {
3091             test111(null);
3092             throw new RuntimeException("No exception thrown");
3093         } catch (NullPointerException e) {
3094             // Expected
3095         }
3096     }
3097 
3098     @Test
3099     void test112() {
3100         field3 = null;
3101     }
3102 
3103     @Run(test = "test112")
3104     public void test112_verifier() {
3105         try {
3106             test112();
3107             throw new RuntimeException("No exception thrown");
3108         } catch (NullPointerException e) {
3109             // Expected
3110         }
3111     }
3112 
3113     @Test
3114     void test113(MyValueEmpty arg) {
3115         field4 = arg;
3116     }
3117 
3118     @Run(test = "test113")
3119     public void test113_verifier() {
3120         try {
3121             test113(null);
3122             throw new RuntimeException("No exception thrown");
3123         } catch (NullPointerException e) {
3124             // Expected
3125         }
3126     }
3127 
3128     @Test
3129     void test114(TestNullableInlineTypes t, MyValueEmpty arg) {
3130         t.field4 = arg;
3131     }
3132 
3133     @Run(test = "test114")
3134     public void test114_verifier() {
3135         try {
3136             test114(null, new MyValueEmpty());
3137             throw new RuntimeException("No exception thrown");
3138         } catch (NullPointerException e) {
3139             // Expected
3140         }
3141     }
3142 
3143     @Test
3144     void test115(MyValueEmpty arg) {
3145         TestNullableInlineTypes t = null;
3146         t.field4 = arg;
3147     }
3148 
3149     @Run(test = "test115")
3150     public void test115_verifier() {
3151         try {
3152             test115(new MyValueEmpty());
3153             throw new RuntimeException("No exception thrown");
3154         } catch (NullPointerException e) {
3155             // Expected
3156         }
3157     }
3158 
3159     @Test
3160     void test116() {
3161         field4 = null;
3162     }
3163 
3164     @Run(test = "test116")
3165     public void test116_verifier() {
3166         try {
3167             test116();
3168             throw new RuntimeException("No exception thrown");
3169         } catch (NullPointerException e) {
3170             // Expected
3171         }
3172     }
3173 
3174     @Test
3175     MyValue104 test117(MyValue105 val1, MyValue105 val2, MyValueEmpty val3, MyValueEmpty val4) {
3176         return new MyValue104(val1, val2, val3, val4);
3177     }
3178 
3179     @Run(test = "test117")
3180     public void test117_verifier() {
3181         try {
3182             test117(null, new MyValue105(), new MyValueEmpty(), new MyValueEmpty());
3183             throw new RuntimeException("No exception thrown");
3184         } catch (NullPointerException e) {
3185             // Expected
3186         }
3187     }
3188 
3189     @Test
3190     MyValue104 test118(MyValue105 val1, MyValue105 val2, MyValueEmpty val3, MyValueEmpty val4) {
3191         return new MyValue104(val1, val2, val3, val4);
3192     }
3193 
3194     @Run(test = "test118")
3195     public void test118_verifier() {
3196         try {
3197             test118(new MyValue105(), null, new MyValueEmpty(), new MyValueEmpty());
3198             throw new RuntimeException("No exception thrown");
3199         } catch (NullPointerException e) {
3200             // Expected
3201         }
3202     }
3203 
3204     @Test
3205     MyValue104 test119(MyValue105 val1, MyValue105 val2, MyValueEmpty val3, MyValueEmpty val4) {
3206         return new MyValue104(val1, val2, val3, val4);
3207     }
3208 
3209     @Run(test = "test119")
3210     public void test119_verifier() {
3211         try {
3212             test119(new MyValue105(), new MyValue105(), null, new MyValueEmpty());
3213             throw new RuntimeException("No exception thrown");
3214         } catch (NullPointerException e) {
3215             // Expected
3216         }
3217     }
3218 
3219     @Test
3220     MyValue104 test120(MyValue105 val1, MyValue105 val2, MyValueEmpty val3, MyValueEmpty val4) {
3221         return new MyValue104(val1, val2, val3, val4);
3222     }
3223 
3224     @Run(test = "test120")
3225     public void test120_verifier() {
3226         try {
3227             test120(new MyValue105(), new MyValue105(), new MyValueEmpty(), null);
3228             throw new RuntimeException("No exception thrown");
3229         } catch (NullPointerException e) {
3230             // Expected
3231         }
3232     }
3233 
3234     @Test
3235     MyValue104 test121(MyValue105 val2, MyValueEmpty val3, MyValueEmpty val4) {
3236         return new MyValue104(null, val2, val3, val4);
3237     }
3238 
3239     @Run(test = "test121")
3240     public void test121_verifier() {
3241         try {
3242             test121(new MyValue105(), new MyValueEmpty(), new MyValueEmpty());
3243             throw new RuntimeException("No exception thrown");
3244         } catch (NullPointerException e) {
3245             // Expected
3246         }
3247     }
3248 
3249     @Test
3250     MyValue104 test122(MyValue105 val1, MyValueEmpty val3, MyValueEmpty val4) {
3251         return new MyValue104(val1, null, val3, val4);
3252     }
3253 
3254     @Run(test = "test122")
3255     public void test122_verifier() {
3256         try {
3257             test122(new MyValue105(), new MyValueEmpty(), new MyValueEmpty());
3258             throw new RuntimeException("No exception thrown");
3259         } catch (NullPointerException e) {
3260             // Expected
3261         }
3262     }
3263 
3264     @Test
3265     MyValue104 test123(MyValue105 val1, MyValue105 val2, MyValueEmpty val4) {
3266         return new MyValue104(val1, val2, null, val4);
3267     }
3268 
3269     @Run(test = "test123")
3270     public void test123_verifier() {
3271         try {
3272             test123(new MyValue105(), new MyValue105(), new MyValueEmpty());
3273             throw new RuntimeException("No exception thrown");
3274         } catch (NullPointerException e) {
3275             // Expected
3276         }
3277     }
3278 
3279     @Test
3280     MyValue104 test124(MyValue105 val1, MyValue105 val2, MyValueEmpty val3) {
3281         return new MyValue104(val1, val2, val3, null);
3282     }
3283 
3284     @Run(test = "test124")
3285     public void test124_verifier() {
3286         try {
3287             test124(new MyValue105(), new MyValue105(), new MyValueEmpty());
3288             throw new RuntimeException("No exception thrown");
3289         } catch (NullPointerException e) {
3290             // Expected
3291         }
3292     }
3293 }