--- /dev/null
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+import "testing"
+
+// This tests for a bug found when partitioning, but not sorting by the Aux value.
+func TestCSEAuxPartitionBug(t *testing.T) {
+ c := testConfig(t)
+ arg1Aux := "arg1-aux"
+ arg2Aux := "arg2-aux"
+ arg3Aux := "arg3-aux"
+
+ // construct lots of values with args that have aux values and place
+ // them in an order that triggers the bug
+ fun := Fun(c, "entry",
+ Bloc("entry",
+ Valu("start", OpInitMem, TypeMem, 0, nil),
+ Valu("sp", OpSP, TypeBytePtr, 0, nil),
+ Valu("r7", OpAdd64, TypeInt64, 0, nil, "arg3", "arg1"),
+ Valu("r1", OpAdd64, TypeInt64, 0, nil, "arg1", "arg2"),
+ Valu("arg1", OpArg, TypeInt64, 0, arg1Aux),
+ Valu("arg2", OpArg, TypeInt64, 0, arg2Aux),
+ Valu("arg3", OpArg, TypeInt64, 0, arg3Aux),
+ Valu("r9", OpAdd64, TypeInt64, 0, nil, "r7", "r8"),
+ Valu("r4", OpAdd64, TypeInt64, 0, nil, "r1", "r2"),
+ Valu("r8", OpAdd64, TypeInt64, 0, nil, "arg3", "arg2"),
+ Valu("r2", OpAdd64, TypeInt64, 0, nil, "arg1", "arg2"),
+ Valu("raddr", OpAddr, TypeInt64Ptr, 0, nil, "sp"),
+ Valu("raddrdef", OpVarDef, TypeMem, 0, nil, "start"),
+ Valu("r6", OpAdd64, TypeInt64, 0, nil, "r4", "r5"),
+ Valu("r3", OpAdd64, TypeInt64, 0, nil, "arg1", "arg2"),
+ Valu("r5", OpAdd64, TypeInt64, 0, nil, "r2", "r3"),
+ Valu("r10", OpAdd64, TypeInt64, 0, nil, "r6", "r9"),
+ Valu("rstore", OpStore, TypeMem, 8, nil, "raddr", "r10", "raddrdef"),
+ Goto("exit")),
+ Bloc("exit",
+ Exit("rstore")))
+
+ CheckFunc(fun.f)
+ cse(fun.f)
+ deadcode(fun.f)
+ CheckFunc(fun.f)
+
+ s1Cnt := 2
+ // r1 == r2 == r3, needs to remove two of this set
+ s2Cnt := 1
+ // r4 == r5, needs to remove one of these
+ for k, v := range fun.values {
+ if v.Op == OpInvalid {
+ switch k {
+ case "r1":
+ fallthrough
+ case "r2":
+ fallthrough
+ case "r3":
+ if s1Cnt == 0 {
+ t.Errorf("cse removed all of r1,r2,r3")
+ }
+ s1Cnt--
+
+ case "r4":
+ fallthrough
+ case "r5":
+ if s2Cnt == 0 {
+ t.Errorf("cse removed all of r4,r5")
+ }
+ s2Cnt--
+ default:
+ t.Errorf("cse removed %s, but shouldn't have", k)
+ }
+ }
+ }
+
+ if s1Cnt != 0 || s2Cnt != 0 {
+ t.Errorf("%d values missed during cse", s1Cnt+s2Cnt)
+ }
+
+}