}
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)
+ }
+}