]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix storeOrder
authorCherry Zhang <cherryyz@google.com>
Sat, 18 Feb 2017 23:37:38 +0000 (18:37 -0500)
committerCherry Zhang <cherryyz@google.com>
Tue, 21 Feb 2017 16:29:12 +0000 (16:29 +0000)
storeOrder visits values in DFS order. It should "break" after
pushing one argument to stack, instead of "continue".

Fixes #19179.

Change-Id: I561afb44213df40ebf8bf7d28e0fd00f22a81ac0
Reviewed-on: https://go-review.googlesource.com/37250
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/schedule.go
src/cmd/compile/internal/ssa/schedule_test.go

index 35edd77b8dd9520503eb51546cff2cd718006714..b0a2f231028b3c7055336950ebd7f8cad59438e3 100644 (file)
@@ -400,7 +400,7 @@ func storeOrder(values []*Value, sset *sparseSet, storeNumber []int32) []*Value
                                        stack = append(stack, a)
                                        sset.add(a.ID)
                                        argsdone = false
-                                       continue
+                                       break
                                }
                                if storeNumber[a.ID]/3 > max {
                                        max = storeNumber[a.ID] / 3
index 0ff57e3689ce4c83fea8cdabc93b2f1c7b5cfd55..c3f16b6bd2e153748ef06a8b7d0bcfb2b4727f9c 100644 (file)
@@ -55,3 +55,44 @@ func isSingleLiveMem(f *Func) bool {
        }
        return true
 }
+
+func TestStoreOrder(t *testing.T) {
+       // In the function below, v2 depends on v3 and v4, v4 depends on v3, and v3 depends on store v5.
+       // storeOrder did not handle this case correctly.
+       c := testConfig(t)
+       fun := Fun(c, "entry",
+               Bloc("entry",
+                       Valu("mem0", OpInitMem, TypeMem, 0, nil),
+                       Valu("a", OpAdd64, TypeInt64, 0, nil, "b", "c"),            // v2
+                       Valu("b", OpLoad, TypeInt64, 0, nil, "ptr", "mem1"),        // v3
+                       Valu("c", OpNeg64, TypeInt64, 0, nil, "b"),                 // v4
+                       Valu("mem1", OpStore, TypeMem, 8, nil, "ptr", "v", "mem0"), // v5
+                       Valu("mem2", OpStore, TypeMem, 0, nil, "ptr", "a", "mem1"),
+                       Valu("ptr", OpConst64, TypeInt64, 0xABCD, nil),
+                       Valu("v", OpConst64, TypeInt64, 12, nil),
+                       Goto("exit")),
+               Bloc("exit",
+                       Exit("mem2")))
+
+       CheckFunc(fun.f)
+       order := storeOrder(fun.f.Blocks[0].Values, fun.f.newSparseSet(fun.f.NumValues()), make([]int32, fun.f.NumValues()))
+
+       // check that v2, v3, v4 is sorted after v5
+       var ai, bi, ci, si int
+       for i, v := range order {
+               switch v.ID {
+               case 2:
+                       ai = i
+               case 3:
+                       bi = i
+               case 4:
+                       ci = i
+               case 5:
+                       si = i
+               }
+       }
+       if ai < si || bi < si || ci < si {
+               t.Logf("Func: %s", fun.f)
+               t.Errorf("store order is wrong: got %v, want v2 v3 v4 after v5", order)
+       }
+}