8181 * @run driver compiler.codegen.TestRedundantLea StoreNParallel
8282 */
8383
84+ /*
85+ * @test id=Spill
86+ * @bug 8020282
87+ * @summary Test that we do not generate redundant leas and remove related spills on x86.
88+ * @requires os.simpleArch == "x64"
89+ * @modules jdk.compiler/com.sun.tools.javac.util
90+ * @library /test/lib /
91+ * @run driver compiler.codegen.TestRedundantLea Spill
92+ */
93+
8494
8595package compiler .codegen ;
8696
@@ -129,6 +139,9 @@ public static void main(String[] args) {
129139 framework = new TestFramework (StoreNTest .class );
130140 framework .addFlags ("-XX:+UseParallelGC" );
131141 }
142+ case "Spill" -> {
143+ framework = new TestFramework (SpillTest .class );
144+ }
132145 default -> {
133146 throw new IllegalArgumentException ("Unknown test name \" " + testName +"\" " );
134147 }
@@ -274,9 +287,7 @@ public boolean test(Matcher m) {
274287
275288// The matcher generates leaP* rules for storing an object in an array of objects
276289// at a constant offset, but only when using the Serial or Parallel GC.
277- // Here, we can also manipulate the offset such that we get a leaP32Narrow rule
278- // and we can demonstrate that the peephole also removes simple cases of unneeded
279- // spills.
290+ // Here, we can also manipulate the offset such that we get a leaP32Narrow rule.
280291class StoreNTest {
281292 private static final int SOME_SIZE = 42 ;
282293 private static final int OFFSET8BIT_IDX = 3 ;
@@ -287,8 +298,6 @@ class StoreNTest {
287298
288299 private StoreNTestHelper [] classArr8bit = new StoreNTestHelper [SOME_SIZE ];
289300 private StoreNTestHelper [] classArr32bit = new StoreNTestHelper [SOME_SIZE ];
290- private Object [] objArr8bit = new Object [SOME_SIZE ];
291- private Object [] objArr32bit = new Object [SOME_SIZE ];
292301
293302 @ Test
294303 @ IR (counts = {IRNode .LEA_P , "=2" },
@@ -302,13 +311,6 @@ class StoreNTest {
302311 @ IR (failOn = {IRNode .DECODE_HEAP_OOP_NOT_NULL },
303312 phase = {CompilePhase .FINAL_CODE },
304313 applyIf = {"OptoPeephole" , "true" })
305- // Test that the peephole removes a spill.
306- @ IR (counts = {IRNode .MEM_TO_REG_SPILL_COPY , "=4" },
307- phase = {CompilePhase .FINAL_CODE },
308- applyIfAnd ={"OptoPeephole" , "false" , "UseCompactObjectHeaders" , "false" })
309- @ IR (counts = {IRNode .MEM_TO_REG_SPILL_COPY , "=3" },
310- phase = {CompilePhase .FINAL_CODE },
311- applyIfAnd ={"OptoPeephole" , "true" , "UseCompactObjectHeaders" , "false" })
312314 public void testRemoveSpill () {
313315 this .classArr8bit [OFFSET8BIT_IDX ] = new StoreNTestHelper (CURRENT , OTHER );
314316 this .classArr32bit [OFFSET32BIT_IDX ] = new StoreNTestHelper (OTHER , CURRENT );
@@ -331,48 +333,65 @@ public void testPhiSpill() {
331333 this .classArr8bit [OFFSET8BIT_IDX ] = new StoreNTestHelper (CURRENT , OTHER );
332334 this .classArr8bit [OFFSET32BIT_IDX ] = new StoreNTestHelper (CURRENT , OTHER );
333335 }
336+ }
337+
338+ class StoreNTestHelper {
339+ Object o1 ;
340+ Object o2 ;
341+
342+ public StoreNTestHelper (Object o1 , Object o2 ) {
343+ this .o1 = o1 ;
344+ this .o2 = o2 ;
345+ }
346+ }
347+
348+ // This test validates that the peephole removes simple spills.
349+ // The code for the test originates from compiler/escapeAnalysis/Test6775880.java.
350+ class SpillTest {
351+ int cnt ;
352+ int b [];
353+ String s ;
354+
355+ @ Run (test = "test" )
356+ public static void run () {
357+ SpillTest t = new SpillTest ();
358+ t .cnt = 3 ;
359+ t .b = new int [3 ];
360+ t .b [0 ] = 0 ;
361+ t .b [1 ] = 1 ;
362+ t .b [2 ] = 2 ;
363+ int j = 0 ;
364+ t .s = "" ;
365+ t .test ();
366+ }
334367
335368 @ Test
369+ // TODO: Make tests more precise
336370 @ IR (counts = {IRNode .LEA_P , "=2" },
337371 phase = {CompilePhase .FINAL_CODE },
338372 applyIfPlatform = {"mac" , "false" })
339373 // Negative test
340374 @ IR (counts = {IRNode .DECODE_HEAP_OOP_NOT_NULL , "=2" },
341375 phase = {CompilePhase .FINAL_CODE },
342376 applyIf = {"OptoPeephole" , "false" })
343- // Test that the peephole worked for leaPCompressedOopOffset
344377 @ IR (failOn = {IRNode .DECODE_HEAP_OOP_NOT_NULL },
345378 phase = {CompilePhase .FINAL_CODE },
346379 applyIf = {"OptoPeephole" , "true" })
347- public void testNoAlloc () {
348- this .objArr8bit [OFFSET8BIT_IDX ] = CURRENT ;
349- this .objArr32bit [OFFSET32BIT_IDX ] = OTHER ;
350- }
351-
352- @ Test
353- @ IR (counts = {IRNode .LEA_P , "=2" },
354- phase = {CompilePhase .FINAL_CODE },
355- applyIfPlatform = {"mac" , "false" })
356- // Negative test
357- @ IR (counts = {IRNode .DECODE_HEAP_OOP_NOT_NULL , "=1" },
380+ // Test that the peephole removes a spill.
381+ @ IR (counts = {IRNode .MEM_TO_REG_SPILL_COPY , ">=20" },
358382 phase = {CompilePhase .FINAL_CODE },
359383 applyIf = {"OptoPeephole" , "false" })
360- // Test that the peephole worked for leaPCompressedOopOffset
361- @ IR (failOn = {IRNode .DECODE_HEAP_OOP_NOT_NULL },
384+ @ IR (counts = {IRNode .MEM_TO_REG_SPILL_COPY , ">=18" },
362385 phase = {CompilePhase .FINAL_CODE },
363386 applyIf = {"OptoPeephole" , "true" })
364- public void testNoAllocSameArray () {
365- this .objArr8bit [OFFSET8BIT_IDX ] = CURRENT ;
366- this .objArr8bit [OFFSET32BIT_IDX ] = OTHER ;
367- }
368- }
369-
370- class StoreNTestHelper {
371- Object o1 ;
372- Object o2 ;
373-
374- public StoreNTestHelper (Object o1 , Object o2 ) {
375- this .o1 = o1 ;
376- this .o2 = o2 ;
387+ String test () {
388+ String res = "" ;
389+ for (int i = 0 ; i < cnt ; i ++) {
390+ if (i != 0 ) {
391+ res = res + "." ;
392+ }
393+ res = res + b [i ];
394+ }
395+ return res ;
377396 }
378397}
0 commit comments