From e7eb2db06d1b9c529f94f2da3a087c83c0498e05 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Mon, 19 Oct 2026 10:40:35 -0700 Subject: Turn off Store GVN with explaination --- .../java/com/seaofnodes/simple/Chapter10Test.java | 23 ++++++++++++++++++-- .../java/com/seaofnodes/simple/Chapter17bTest.java | 25 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) (limited to 'chapter18/src/test/java') diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Chapter10Test.java b/chapter18/src/test/java/com/seaofnodes/simple/Chapter10Test.java index 2681e878..cf877cb8 100644 --- a/chapter18/src/test/java/com/seaofnodes/simple/Chapter10Test.java +++ b/chapter18/src/test/java/com/seaofnodes/simple/Chapter10Test.java @@ -7,6 +7,24 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class Chapter10Test { + @Test public void testConditionalStoreSharing() { + // Sharing the writes on two of three paths must not write on the third. + // Return the object so Load forwarding cannot hide the physical Store. + String src = """ + struct S { int x; }; + !S !a = new S; + a.x = 10; + if (arg == 1) a.x = 9; + else if (arg == 2) a.x = 9; + return a; + """; + var code = new CodeGen(src).driver(CodeGen.Phase.LocalSched); + for( int arg : new int[]{0,1,2,3} ) { + long expected = (arg==1 || arg==2) ? 9 : 10; + assertEquals("S{x="+expected+"}",Eval2.eval(code,arg)); + } + } + @Test public void testDeadReferenceReturn() { for( String body : new String[] { "return new S; return 0;", @@ -529,7 +547,7 @@ return 0; assertEquals("3",Eval2.eval(code,3)); } - @Test public void testDropStores() { + @Test public void testKeepBranchStores() { var code = new CodeGen(""" struct S { int x; }; !S !s = new S; @@ -537,7 +555,8 @@ return 0; return s; """).parse().iter(); StopNode stop = code._stop; - assertEquals(1,countMemoryNodes(stop,StoreNode.class,new BitSet())); + // Keep each Store on its own branch. + assertEquals(2,countMemoryNodes(stop,StoreNode.class,new BitSet())); assertEquals("S{x=2}",Eval2.eval(code,0)); assertEquals("S{x=4}",Eval2.eval(code,3)); } diff --git a/chapter18/src/test/java/com/seaofnodes/simple/Chapter17bTest.java b/chapter18/src/test/java/com/seaofnodes/simple/Chapter17bTest.java index a5ce8f49..3c40f684 100644 --- a/chapter18/src/test/java/com/seaofnodes/simple/Chapter17bTest.java +++ b/chapter18/src/test/java/com/seaofnodes/simple/Chapter17bTest.java @@ -7,6 +7,31 @@ import static org.junit.Assert.fail; public class Chapter17bTest { + @Test public void testSinkLoopStores() { + var code = new CodeGen(""" + struct S { int x; }; + !S !a = new S; + a.x = 10; + int i = 0; + while (i < arg) { a.x = i + 1; i++; } + return a; + """).driver(CodeGen.Phase.LocalSched); + int[] stores = {0}; + code._stop.walk(n -> { + if( n instanceof com.seaofnodes.simple.node.StoreNode st && st._name.equals("x") ) { + assertEquals(0,st.cfg0().loopDepth()); // One final Store outside the loop. + stores[0]++; + } + return null; + }); + assertEquals(1,stores[0]); + for( int arg : new int[]{-1,0,1,4} ) { + long expected = arg<=0 ? 10 : arg; + assertEquals("S{x="+expected+"}",Eval2.eval(code,arg)); + } + } + + @Ignore @Test public void testJig() { -- cgit v1.2.3