From b411578005cf05f185a5685c78fa14f35fe0ee14 Mon Sep 17 00:00:00 2001 From: skishor Date: Wed, 20 Aug 2025 11:08:40 +0530 Subject: [PATCH] 8361492: [IR Framework] Has too restrictive regex for load and store --- .../compiler/lib/ir_framework/IRNode.java | 18 +- .../tests/TestPhaseIRMatching.java | 237 ++++++++++++++++++ 2 files changed, 251 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index f53bb45bd43..bb7162c11dc 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -102,8 +102,6 @@ public class IRNode { private static final String START = "(\\d+(\\s){2}("; private static final String MID = ".*)+(\\s){2}===.*"; private static final String END = ")"; - private static final String STORE_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; - private static final String LOAD_OF_CLASS_POSTFIX = "(:|\\+)\\S* \\*" + END; public static final String IS_REPLACED = "#IS_REPLACED#"; // Is replaced by an additional user-defined string. @@ -2938,13 +2936,25 @@ private static void parsePredicateNodes(String irNodePlaceholder, String label) CompilePhase.AFTER_LOOP_OPTS)); } + // Typename in load/store have the structure: + // @fully/qualified/package/name/to/TheClass+12 * + // And variation: + // - after @, we can have "stable:" or other labels, with optional space after ':' + // - the class can actually be a subclass, with $ separator (and it must be ok to give only the deepest one + // - after the class name, we can have a comma-separated list of implemented interfaces enclosed in parentheses + // - before the offset, we can have something like ":NotNull", either way, seeing "+" or ":" means the end of the type + // Worst case, it can be something like: + // @bla: bli:a/b/c$d$e (f/g,h/i/j):NotNull+24 * + private static final String LOAD_STORE_PREFIX = "@(\\w+: ?)*[\\w/\\$]*\\b"; + private static final String LOAD_STORE_SUFFIX = "( \\([^\\)]+\\))?(:|\\+)\\S* \\*"; + private static void loadOfNodes(String irNodePlaceholder, String irNodeRegex) { - String regex = START + irNodeRegex + MID + "@\\S*" + IS_REPLACED + LOAD_OF_CLASS_POSTFIX; + String regex = START + irNodeRegex + MID + LOAD_STORE_PREFIX + IS_REPLACED + LOAD_STORE_SUFFIX + END; beforeMatching(irNodePlaceholder, regex); } private static void storeOfNodes(String irNodePlaceholder, String irNodeRegex) { - String regex = START + irNodeRegex + MID + "@\\S*" + IS_REPLACED + STORE_OF_CLASS_POSTFIX; + String regex = START + irNodeRegex + MID + LOAD_STORE_PREFIX + IS_REPLACED + LOAD_STORE_SUFFIX + END; beforeMatching(irNodePlaceholder, regex); } diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java index a2d98d00502..fe21dce73b5 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestPhaseIRMatching.java @@ -60,6 +60,7 @@ public class TestPhaseIRMatching { public static void main(String[] args) { run(Basics.class); run(NoCompilationOutput.class); + run(LoadStore.class); } private static void run(Class testClass) { @@ -549,3 +550,239 @@ public static List sort(Set failures) { .thenComparing(Failure::constraintId)).collect(Collectors.toList()); } } + +// Test load and store regexes +class LoadStore { + int i; + float f; + interface I1 {} + static class Base implements I1 { + int i; + } + interface I2 {} + static class Derived extends Base implements I2 { + long l; + } + Base base = new Base(); + Derived derived = new Derived(); + + static class SingleNest { + static class DoubleNest { + int i; + } + } + + SingleNest.DoubleNest doubleNest = new SingleNest.DoubleNest(); + + + @Test + @IR(failOn = {IRNode.LOAD_OF_CLASS, ".*", IRNode.STORE_OF_CLASS, ".*"}) + public void triviallyFailBoth() { + } + + @Test + @IR(counts = { + IRNode.LOAD_OF_CLASS, "LoadS[a-z]+", "1", + IRNode.LOAD_OF_CLASS, "Load.tore", "1", + IRNode.LOAD_OF_CLASS, "LoadStore", "1", + IRNode.LOAD_OF_CLASS, "/LoadStore", "1", + IRNode.LOAD_OF_CLASS, "tests/LoadStore", "1", + IRNode.LOAD_OF_CLASS, "/tests/LoadStore", "1", + IRNode.LOAD_OF_CLASS, "ir_framework/tests/LoadStore", "1", + IRNode.LOAD_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore", "1", // To assert it's the whole qualification + IRNode.LOAD_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1", + }, + failOn = { + IRNode.LOAD_OF_CLASS, "oadStore", + IRNode.LOAD_OF_CLASS, "LoadStor", + IRNode.LOAD_OF_CLASS, "/ir_framework/tests/LoadStore", + IRNode.LOAD_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*", + } + ) + // @ir_framework/tests/LoadStore+12 * + public float simpleLoad() { + return f; + } + + @Test + @IR(counts = { + IRNode.STORE_OF_CLASS, "LoadS[a-z]+", "1", + IRNode.STORE_OF_CLASS, "Load.tore", "1", + IRNode.STORE_OF_CLASS, "LoadStore", "1", + IRNode.STORE_OF_CLASS, "/LoadStore", "1", + IRNode.STORE_OF_CLASS, "tests/LoadStore", "1", + IRNode.STORE_OF_CLASS, "/tests/LoadStore", "1", + IRNode.STORE_OF_CLASS, "ir_framework/tests/LoadStore", "1", + IRNode.STORE_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore", "1", + IRNode.STORE_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1", + }, + failOn = { + IRNode.STORE_OF_CLASS, "oadStore", + IRNode.STORE_OF_CLASS, "LoadStor", + IRNode.STORE_OF_CLASS, "/ir_framework/tests/LoadStore", + IRNode.STORE_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*", + } + ) + // @ir_framework/tests/LoadStore+12 * + public void simpleStore() { + i = 1; + } + + @Test + @IR(counts = { + IRNode.LOAD_I_OF_CLASS, "Base", "1", + IRNode.LOAD_I_OF_CLASS, "\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "LoadS[a-z]+\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "Load.tore\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "LoadStore\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "/LoadStore\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "tests/LoadStore\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "/tests/LoadStore\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "ir_framework/tests/LoadStore\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore\\$Base", "1", + IRNode.LOAD_I_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1", + }, + failOn = { + IRNode.LOAD_I_OF_CLASS, "/Base", + IRNode.LOAD_I_OF_CLASS, "oadStore\\$Base", + IRNode.LOAD_I_OF_CLASS, "LoadStore\\$Bas", + IRNode.LOAD_I_OF_CLASS, "LoadStore", + IRNode.LOAD_I_OF_CLASS, "/ir_framework/tests/LoadStore\\$Base", + IRNode.LOAD_I_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*", + } + ) + // @ir_framework/tests/LoadStore$Base (ir_framework/tests/LoadStore$I1)+12 * + public int loadWithInterface() { + return base.i; + } + + @Test + @IR(counts = { + IRNode.STORE_I_OF_CLASS, "Base", "1", + IRNode.STORE_I_OF_CLASS, "\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "LoadS[a-z]+\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "Load.tore\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "LoadStore\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "/LoadStore\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "tests/LoadStore\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "/tests/LoadStore\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "ir_framework/tests/LoadStore\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore\\$Base", "1", + IRNode.STORE_I_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1", + }, + failOn = { + IRNode.STORE_I_OF_CLASS, "/Base", + IRNode.STORE_I_OF_CLASS, "oadStore\\$Base", + IRNode.STORE_I_OF_CLASS, "LoadStore\\$Bas", + IRNode.STORE_I_OF_CLASS, "LoadStore", + IRNode.STORE_I_OF_CLASS, "/ir_framework/tests/LoadStore\\$Base", + IRNode.STORE_I_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*", + } + ) + // @ir_framework/tests/LoadStore$Base (ir_framework/tests/LoadStore$I1)+12 * + public void storeWithInterface() { + base.i = 1; + } + + @Test + @IR(counts = { + IRNode.LOAD_L_OF_CLASS, "Derived", "1", + IRNode.LOAD_L_OF_CLASS, "\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "LoadS[a-z]+\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "Load.tore\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "LoadStore\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "/LoadStore\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "tests/LoadStore\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "/tests/LoadStore\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "ir_framework/tests/LoadStore\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore\\$Derived", "1", + IRNode.LOAD_L_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1", + }, + failOn = { + IRNode.LOAD_L_OF_CLASS, "/Derived", + IRNode.LOAD_L_OF_CLASS, "oadStore\\$Derived", + IRNode.LOAD_L_OF_CLASS, "LoadStore\\$Derive", + IRNode.LOAD_L_OF_CLASS, "LoadStore", + IRNode.LOAD_L_OF_CLASS, "/ir_framework/tests/LoadStore\\$Derived", + IRNode.LOAD_L_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*", + } + ) + // @ir_framework/tests/LoadStore$Derived (ir_framework/tests/LoadStore$I1,ir_framework/tests/LoadStore$I2)+24 * + public long loadWithInterfaces() { + return derived.l; + } + + @Test + @IR(counts = { + IRNode.STORE_L_OF_CLASS, "Derived", "1", + IRNode.STORE_L_OF_CLASS, "\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "LoadS[a-z]+\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "Load.tore\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "LoadStore\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "/LoadStore\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "tests/LoadStore\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "/tests/LoadStore\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "ir_framework/tests/LoadStore\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "(?<=[@: ])ir_framework/tests/LoadStore\\$Derived", "1", + IRNode.STORE_L_OF_CLASS, "(?<=[@: ])[\\w\\$/]*tests[\\w\\$/]*", "1", + }, + failOn = { + IRNode.STORE_L_OF_CLASS, "/Derived", + IRNode.STORE_L_OF_CLASS, "oadStore\\$Derived", + IRNode.STORE_L_OF_CLASS, "LoadStore\\$Derive", + IRNode.STORE_L_OF_CLASS, "LoadStore", + IRNode.STORE_L_OF_CLASS, "/ir_framework/tests/LoadStore\\$Derived", + IRNode.STORE_L_OF_CLASS, "(?<=[@: ])[\\w\\$]*tests[\\w\\$]*", + } + ) + // @ir_framework/tests/LoadStore$Derived (ir_framework/tests/LoadStore$I1,ir_framework/tests/LoadStore$I2)+24 * + public void storeWithInterfaces() { + derived.l = 1; + } + + @Test + @IR(counts = { + IRNode.LOAD_I_OF_CLASS, "DoubleNest", "1", + IRNode.LOAD_I_OF_CLASS, "\\$DoubleNest", "1", + IRNode.LOAD_I_OF_CLASS, "SingleNest\\$DoubleNest", "1", + IRNode.LOAD_I_OF_CLASS, "\\$SingleNest\\$DoubleNest", "1", + IRNode.LOAD_I_OF_CLASS, "LoadStore\\$SingleNest\\$DoubleNest", "1", + IRNode.LOAD_I_OF_CLASS, "/LoadStore\\$SingleNest\\$DoubleNest", "1", + IRNode.LOAD_I_OF_CLASS, "tests/LoadStore\\$SingleNest\\$DoubleNest", "1", + IRNode.LOAD_I_OF_CLASS, "/tests/LoadStore\\$SingleNest\\$DoubleNest", "1", + IRNode.LOAD_I_OF_CLASS, "ir_framework/tests/LoadStore\\$SingleNest\\$DoubleNest", "1", + }, + failOn = { + IRNode.LOAD_I_OF_CLASS, "SingleNest", + IRNode.LOAD_I_OF_CLASS, "LoadStore", + IRNode.LOAD_I_OF_CLASS, "LoadStore\\$SingleNest", + } + ) + // @ir_framework/tests/LoadStore$SingleNest$DoubleNest+12 * + public int loadDoubleNested() { + return doubleNest.i; + } + + @Test + @IR(counts = { + IRNode.STORE_I_OF_CLASS, "DoubleNest", "1", + IRNode.STORE_I_OF_CLASS, "\\$DoubleNest", "1", + IRNode.STORE_I_OF_CLASS, "SingleNest\\$DoubleNest", "1", + IRNode.STORE_I_OF_CLASS, "\\$SingleNest\\$DoubleNest", "1", + IRNode.STORE_I_OF_CLASS, "LoadStore\\$SingleNest\\$DoubleNest", "1", + IRNode.STORE_I_OF_CLASS, "/LoadStore\\$SingleNest\\$DoubleNest", "1", + IRNode.STORE_I_OF_CLASS, "tests/LoadStore\\$SingleNest\\$DoubleNest", "1", + IRNode.STORE_I_OF_CLASS, "/tests/LoadStore\\$SingleNest\\$DoubleNest", "1", + IRNode.STORE_I_OF_CLASS, "ir_framework/tests/LoadStore\\$SingleNest\\$DoubleNest", "1", + }, + failOn = { + IRNode.STORE_I_OF_CLASS, "SingleNest", + IRNode.STORE_I_OF_CLASS, "LoadStore", + IRNode.STORE_I_OF_CLASS, "LoadStore\\$SingleNest", + } + ) + // @ir_framework/tests/LoadStore$SingleNest$DoubleNest+12 * + public void storeDoubleNested() { + doubleNest.i = 1; + } +} \ No newline at end of file