diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index c8182653688..68d4f89b8f2 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -56,6 +56,9 @@ product(bool, StressIncrementalInlining, false, DIAGNOSTIC, \ "Randomize the incremental inlining decision") \ \ + product(bool, StressMacroExpansion, false, DIAGNOSTIC, \ + "Randomize macro node expansion order") \ + \ product(uint, StressSeed, 0, DIAGNOSTIC, \ "Seed for randomized stress testing (if unset, a random one is " \ "generated). The seed is recorded in the compilation log, if " \ diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index d67df3174b1..83b922492b3 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -844,7 +844,8 @@ Compile::Compile( ciEnv* ci_env, ciMethod* target, int osr_bci, // If any phase is randomized for stress testing, seed random number // generation and log the seed for repeatability. - if (StressLCM || StressGCM || StressIGVN || StressCCP || StressIncrementalInlining) { + if (StressLCM || StressGCM || StressIGVN || StressCCP || + StressIncrementalInlining || StressMacroExpansion) { if (FLAG_IS_DEFAULT(StressSeed) || (FLAG_IS_ERGO(StressSeed) && directive->RepeatCompilationOption)) { _stress_seed = static_cast(Ticks::now().nanoseconds()); FLAG_SET_ERGO(StressSeed, _stress_seed); @@ -2451,12 +2452,13 @@ void Compile::Optimize() { { TracePhase tp("macroExpand", &timers[_t_macroExpand]); + print_method(PHASE_BEFORE_MACRO_EXPANSION, 3); PhaseMacroExpand mex(igvn); if (mex.expand_macro_nodes()) { assert(failing(), "must bail out w/ explicit message"); return; } - print_method(PHASE_MACRO_EXPANSION, 2); + print_method(PHASE_AFTER_MACRO_EXPANSION, 2); } { @@ -5121,6 +5123,16 @@ void CloneMap::dump(node_idx_t key, outputStream* st) const { } } +void Compile::shuffle_macro_nodes() { + if (_macro_nodes.length() < 2) { + return; + } + for (uint i = _macro_nodes.length() - 1; i >= 1; i--) { + uint j = C->random() % (i + 1); + swap(_macro_nodes.at(i), _macro_nodes.at(j)); + } +} + // Move Allocate nodes to the start of the list void Compile::sort_macro_nodes() { int count = macro_count(); diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index 42f866df781..a5e4b69d263 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -794,6 +794,7 @@ private: void remove_useless_unstable_if_traps(Unique_Node_List &useful); void process_for_unstable_if_traps(PhaseIterGVN& igvn); + void shuffle_macro_nodes(); void sort_macro_nodes(); void mark_parse_predicate_nodes_useless(PhaseIterGVN& igvn); diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index 99b1ca7d31c..262fff7f8e9 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -2430,6 +2430,9 @@ void PhaseMacroExpand::eliminate_macro_nodes() { //------------------------------expand_macro_nodes---------------------- // Returns true if a failure occurred. bool PhaseMacroExpand::expand_macro_nodes() { + if (StressMacroExpansion) { + C->shuffle_macro_nodes(); + } // Last attempt to eliminate macro nodes. eliminate_macro_nodes(); if (C->failing()) return true; @@ -2511,6 +2514,9 @@ bool PhaseMacroExpand::expand_macro_nodes() { } assert(!success || (C->macro_count() == (old_macro_count - 1)), "elimination must have deleted one node from macro list"); progress = progress || success; + if (success) { + C->print_method(PHASE_AFTER_MACRO_EXPANSION_STEP, 5, n); + } } } @@ -2571,6 +2577,7 @@ bool PhaseMacroExpand::expand_macro_nodes() { } assert(C->macro_count() == (old_macro_count - 1), "expansion must have deleted one node from macro list"); if (C->failing()) return true; + C->print_method(PHASE_AFTER_MACRO_EXPANSION_STEP, 5, n); // Clean up the graph so we're less likely to hit the maximum node // limit @@ -2613,6 +2620,7 @@ bool PhaseMacroExpand::expand_macro_nodes() { } assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); if (C->failing()) return true; + C->print_method(PHASE_AFTER_MACRO_EXPANSION_STEP, 5, n); // Clean up the graph so we're less likely to hit the maximum node // limit diff --git a/src/hotspot/share/opto/phasetype.hpp b/src/hotspot/share/opto/phasetype.hpp index fc9a834e6f8..6448b8331cc 100644 --- a/src/hotspot/share/opto/phasetype.hpp +++ b/src/hotspot/share/opto/phasetype.hpp @@ -84,7 +84,9 @@ flags(CCP1, "PhaseCCP 1") \ flags(ITER_GVN2, "Iter GVN 2") \ flags(PHASEIDEALLOOP_ITERATIONS, "PhaseIdealLoop iterations") \ - flags(MACRO_EXPANSION, "Macro expand") \ + flags(BEFORE_MACRO_EXPANSION , "Before Macro Expansion") \ + flags(AFTER_MACRO_EXPANSION_STEP, "After Macro Expansion Step") \ + flags(AFTER_MACRO_EXPANSION, "After Macro Expansion") \ flags(BARRIER_EXPANSION, "Barrier expand") \ flags(OPTIMIZE_FINISHED, "Optimize finished") \ flags(BEFORE_MATCHING, "Before matching") \ diff --git a/src/utils/IdealGraphVisualizer/README.md b/src/utils/IdealGraphVisualizer/README.md index 83c9ee5889b..a14fc15d512 100644 --- a/src/utils/IdealGraphVisualizer/README.md +++ b/src/utils/IdealGraphVisualizer/README.md @@ -31,7 +31,7 @@ Ideal graphs are dumped at the following points: * `N=2`: additionally, after every major phase * `N=3`: additionally, after every minor phase * `N=4`: additionally, after every loop optimization -* `N=5`: additionally, after every effective IGVN step (slow) +* `N=5`: additionally, after every effective IGVN and every macro expansion step (slow) * `N=6`: additionally, after parsing every bytecode (very slow) By default the JVM expects that it will connect to a visualizer on the local diff --git a/test/hotspot/jtreg/compiler/arguments/TestStressOptions.java b/test/hotspot/jtreg/compiler/arguments/TestStressOptions.java index 2f16d7ff774..544f84c9b27 100644 --- a/test/hotspot/jtreg/compiler/arguments/TestStressOptions.java +++ b/test/hotspot/jtreg/compiler/arguments/TestStressOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,7 @@ /* * @test * @key stress randomness - * @bug 8252219 8256535 + * @bug 8252219 8256535 8317349 * @requires vm.compiler2.enabled * @summary Tests that different combinations of stress options and * -XX:StressSeed=N are accepted. @@ -44,6 +44,10 @@ * compiler.arguments.TestStressOptions * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+StressGCM -XX:StressSeed=42 * compiler.arguments.TestStressOptions + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+StressMacroExpansion + * compiler.arguments.TestStressOptions + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+StressMacroExpansion -XX:StressSeed=42 + * compiler.arguments.TestStressOptions */ package compiler.arguments; diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ProfileAtTypeCheck.java b/test/hotspot/jtreg/compiler/c2/irTests/ProfileAtTypeCheck.java index c5a02bc932f..dfc1cb9d281 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ProfileAtTypeCheck.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ProfileAtTypeCheck.java @@ -70,7 +70,7 @@ public class ProfileAtTypeCheck { @Test @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.SUBTYPE_CHECK, "1" }) - @IR(phase = { CompilePhase.MACRO_EXPANSION }, counts = { IRNode.CMP_P, "2", IRNode.LOAD_KLASS_OR_NKLASS, "2" }) + @IR(phase = { CompilePhase.AFTER_MACRO_EXPANSION }, counts = { IRNode.CMP_P, "2", IRNode.LOAD_KLASS_OR_NKLASS, "2" }) public static void test1(Object o) { dummyA((A)o); } @@ -103,7 +103,7 @@ public class ProfileAtTypeCheck { @Test @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.SUBTYPE_CHECK, "1" }) - @IR(phase = { CompilePhase.MACRO_EXPANSION }, counts = { IRNode.CMP_P, "2", IRNode.LOAD_KLASS_OR_NKLASS, "1" }) + @IR(phase = { CompilePhase.AFTER_MACRO_EXPANSION }, counts = { IRNode.CMP_P, "2", IRNode.LOAD_KLASS_OR_NKLASS, "1" }) public static void test3(Object o) { if (o instanceof B) { dummyB((B)o); @@ -121,7 +121,7 @@ public class ProfileAtTypeCheck { // full subtype check @Test @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.SUBTYPE_CHECK, "1" }) - @IR(phase = { CompilePhase.MACRO_EXPANSION }, counts = { IRNode.CMP_P, "3", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) + @IR(phase = { CompilePhase.AFTER_MACRO_EXPANSION }, counts = { IRNode.CMP_P, "3", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) public static void test4(Object o) { dummyI((I)o); } @@ -138,7 +138,7 @@ public class ProfileAtTypeCheck { // full subtype check + profile use for success path @Test @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.SUBTYPE_CHECK, "1" }) - @IR(phase = { CompilePhase.MACRO_EXPANSION }, counts = { IRNode.CMP_P, "5", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) + @IR(phase = { CompilePhase.AFTER_MACRO_EXPANSION }, counts = { IRNode.CMP_P, "5", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) public static void test5(Object o) { dummyI((I)o); } @@ -153,7 +153,7 @@ public class ProfileAtTypeCheck { // Check primary super @Test @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.SUBTYPE_CHECK, "1" }) - @IR(phase = { CompilePhase.MACRO_EXPANSION }, counts = { IRNode.CMP_P, "2", IRNode.LOAD_KLASS_OR_NKLASS, "2" }, failOn = { IRNode.PARTIAL_SUBTYPE_CHECK }) + @IR(phase = { CompilePhase.AFTER_MACRO_EXPANSION }, counts = { IRNode.CMP_P, "2", IRNode.LOAD_KLASS_OR_NKLASS, "2" }, failOn = { IRNode.PARTIAL_SUBTYPE_CHECK }) public static void test6(Object o) { dummyA((A)o); } @@ -169,7 +169,7 @@ public class ProfileAtTypeCheck { // full subtype check + profile use for both success and failure paths @Test @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.SUBTYPE_CHECK, "1" }) - @IR(phase = { CompilePhase.MACRO_EXPANSION }, counts = { IRNode.CMP_P, "5", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) + @IR(phase = { CompilePhase.AFTER_MACRO_EXPANSION }, counts = { IRNode.CMP_P, "5", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) public static boolean test7(Object o) { return o instanceof I; } @@ -184,7 +184,7 @@ public class ProfileAtTypeCheck { // full subtype check + profile use for success path (profile has unrecorded entries) @Test @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.SUBTYPE_CHECK, "1" }) - @IR(phase = { CompilePhase.MACRO_EXPANSION }, counts = { IRNode.CMP_P, "5", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) + @IR(phase = { CompilePhase.AFTER_MACRO_EXPANSION }, counts = { IRNode.CMP_P, "5", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) public static void test8(Object o) { dummyI((I)o); } @@ -394,7 +394,7 @@ public class ProfileAtTypeCheck { // full subtype check + profile use for success path @Test @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.SUBTYPE_CHECK, "1" }) - @IR(phase = { CompilePhase.MACRO_EXPANSION }, counts = { IRNode.CMP_P, "5", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) + @IR(phase = { CompilePhase.AFTER_MACRO_EXPANSION }, counts = { IRNode.CMP_P, "5", IRNode.LOAD_KLASS_OR_NKLASS, "2", IRNode.PARTIAL_SUBTYPE_CHECK, "1" }) public static void test15(Object o) { array[0] = o; } diff --git a/test/hotspot/jtreg/compiler/debug/TestGenerateStressSeed.java b/test/hotspot/jtreg/compiler/debug/TestGenerateStressSeed.java index f03667a55ce..bbcafb53460 100644 --- a/test/hotspot/jtreg/compiler/debug/TestGenerateStressSeed.java +++ b/test/hotspot/jtreg/compiler/debug/TestGenerateStressSeed.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ import jdk.test.lib.process.ProcessTools; * @run driver compiler.debug.TestGenerateStressSeed StressGCM * @run driver compiler.debug.TestGenerateStressSeed StressIGVN * @run driver compiler.debug.TestGenerateStressSeed StressCCP + * @run driver compiler.debug.TestGenerateStressSeed StressMacroExpansion */ public class TestGenerateStressSeed { diff --git a/test/hotspot/jtreg/compiler/debug/TestStressIGVNAndCCP.java b/test/hotspot/jtreg/compiler/debug/TestStress.java similarity index 74% rename from test/hotspot/jtreg/compiler/debug/TestStressIGVNAndCCP.java rename to test/hotspot/jtreg/compiler/debug/TestStress.java index 3ec49daa0ea..cdeecff91cd 100644 --- a/test/hotspot/jtreg/compiler/debug/TestStressIGVNAndCCP.java +++ b/test/hotspot/jtreg/compiler/debug/TestStress.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,22 +30,22 @@ import jdk.test.lib.Asserts; /* * @test * @key stress randomness - * @bug 8252219 8256535 + * @bug 8252219 8256535 8317349 * @requires vm.debug == true & vm.compiler2.enabled * @summary Tests that stress compilations with the same seed yield the same - * IGVN and CCP traces. + * IGVN, CCP, and macro expansion traces. * @library /test/lib / - * @run driver compiler.debug.TestStressIGVNAndCCP + * @run driver compiler.debug.TestStress */ -public class TestStressIGVNAndCCP { +public class TestStress { static String phaseTrace(String stressOption, String traceOption, int stressSeed) throws Exception { - String className = TestStressIGVNAndCCP.class.getName(); + String className = TestStress.class.getName(); String[] procArgs = { "-Xcomp", "-XX:-TieredCompilation", "-XX:-Inline", "-XX:+CICountNative", - "-XX:CompileOnly=" + className + "::sum", "-XX:+" + traceOption, + "-XX:CompileOnly=" + className + "::sum", "-XX:" + traceOption, "-XX:+" + stressOption, "-XX:StressSeed=" + stressSeed, className, "10"}; ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(procArgs); @@ -55,11 +55,17 @@ public class TestStressIGVNAndCCP { } static String igvnTrace(int stressSeed) throws Exception { - return phaseTrace("StressIGVN", "TraceIterativeGVN", stressSeed); + return phaseTrace("StressIGVN", "+TraceIterativeGVN", stressSeed); } static String ccpTrace(int stressSeed) throws Exception { - return phaseTrace("StressCCP", "TracePhaseCCP", stressSeed); + return phaseTrace("StressCCP", "+TracePhaseCCP", stressSeed); + } + + static String macroExpansionTrace(int stressSeed) throws Exception { + return phaseTrace("StressMacroExpansion", + "CompileCommand=PrintIdealPhase,*::*,AFTER_MACRO_EXPANSION_STEP", + stressSeed); } static void sum(int n) { @@ -75,6 +81,8 @@ public class TestStressIGVNAndCCP { "got different IGVN traces for the same seed"); Asserts.assertEQ(ccpTrace(s), ccpTrace(s), "got different CCP traces for the same seed"); + Asserts.assertEQ(macroExpansionTrace(s), macroExpansionTrace(s), + "got different macro expansion traces for the same seed"); } } else if (args.length > 0) { sum(Integer.parseInt(args[0])); diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java b/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java index 26a271949e7..3ee8fc8f45b 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/CompilePhase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,9 @@ public enum CompilePhase { CCP1("PhaseCCP 1"), ITER_GVN2("Iter GVN 2"), PHASEIDEALLOOP_ITERATIONS("PhaseIdealLoop iterations"), - MACRO_EXPANSION("Macro expand"), + BEFORE_MACRO_EXPANSION("Before Macro Expansion"), + AFTER_MACRO_EXPANSION_STEP("After Macro Expansion Step"), + AFTER_MACRO_EXPANSION("After Macro Expansion"), BARRIER_EXPANSION("Barrier expand"), OPTIMIZE_FINISHED("Optimize finished"), PRINT_IDEAL("PrintIdeal"), diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index 040fe5d0222..3fd0455da1d 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -2233,7 +2233,7 @@ public class IRNode { */ private static void fromMacroToBeforeMatching(String irNodePlaceholder, String regex) { IR_NODE_MAPPINGS.put(irNodePlaceholder, new SinglePhaseRangeEntry(CompilePhase.PRINT_IDEAL, regex, - CompilePhase.MACRO_EXPANSION, + CompilePhase.AFTER_MACRO_EXPANSION, CompilePhase.BEFORE_MATCHING)); } diff --git a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java index d9c64b89138..601f7ed91df 100644 --- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java +++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/CtwRunner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -298,6 +298,7 @@ public class CtwRunner { "-XX:+StressGCM", "-XX:+StressIGVN", "-XX:+StressCCP", + "-XX:+StressMacroExpansion", // StressSeed is uint "-XX:StressSeed=" + Math.abs(rng.nextInt()))); diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java index 99bf338e072..5205ce8c031 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestBadFormat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1095,11 +1095,11 @@ class BadIRNodeForPhase { @Test @FailCount(4) - @IR(failOn = IRNode.ALLOC, phase = {CompilePhase.FINAL_CODE, CompilePhase.MACRO_EXPANSION}) + @IR(failOn = IRNode.ALLOC, phase = {CompilePhase.FINAL_CODE, CompilePhase.AFTER_MACRO_EXPANSION}) @IR(failOn = IRNode.ALLOC, phase = CompilePhase.PRINT_IDEAL) @IR(failOn = IRNode.ALLOC, phase = {CompilePhase.ITER_GVN1, CompilePhase.AFTER_PARSING, CompilePhase.PRINT_OPTO_ASSEMBLY}) // works - @IR(failOn = IRNode.ALLOC_ARRAY, phase = {CompilePhase.FINAL_CODE, CompilePhase.MACRO_EXPANSION}) + @IR(failOn = IRNode.ALLOC_ARRAY, phase = {CompilePhase.FINAL_CODE, CompilePhase.AFTER_MACRO_EXPANSION}) @IR(failOn = IRNode.ALLOC_ARRAY, phase = CompilePhase.PRINT_IDEAL) @IR(failOn = IRNode.ALLOC_ARRAY, phase = {CompilePhase.ITER_GVN1, CompilePhase.AFTER_PARSING, CompilePhase.PRINT_OPTO_ASSEMBLY}) // works