diff options
Diffstat (limited to 'src/cmd/compile/internal/ssa/cse_test.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/cse_test.go | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/cse_test.go b/src/cmd/compile/internal/ssa/cse_test.go new file mode 100644 index 0000000..8052016 --- /dev/null +++ b/src/cmd/compile/internal/ssa/cse_test.go @@ -0,0 +1,131 @@ +// 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 ( + "cmd/compile/internal/types" + "cmd/internal/src" + "testing" +) + +type tstAux struct { + s string +} + +func (*tstAux) CanBeAnSSAAux() {} + +// This tests for a bug found when partitioning, but not sorting by the Aux value. +func TestCSEAuxPartitionBug(t *testing.T) { + c := testConfig(t) + arg1Aux := &tstAux{"arg1-aux"} + arg2Aux := &tstAux{"arg2-aux"} + arg3Aux := &tstAux{"arg3-aux"} + a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8) + + // construct lots of values with args that have aux values and place + // them in an order that triggers the bug + fun := c.Fun("entry", + Bloc("entry", + Valu("start", OpInitMem, types.TypeMem, 0, nil), + Valu("sp", OpSP, c.config.Types.Uintptr, 0, nil), + Valu("r7", OpAdd64, c.config.Types.Int64, 0, nil, "arg3", "arg1"), + Valu("r1", OpAdd64, c.config.Types.Int64, 0, nil, "arg1", "arg2"), + Valu("arg1", OpArg, c.config.Types.Int64, 0, arg1Aux), + Valu("arg2", OpArg, c.config.Types.Int64, 0, arg2Aux), + Valu("arg3", OpArg, c.config.Types.Int64, 0, arg3Aux), + Valu("r9", OpAdd64, c.config.Types.Int64, 0, nil, "r7", "r8"), + Valu("r4", OpAdd64, c.config.Types.Int64, 0, nil, "r1", "r2"), + Valu("r8", OpAdd64, c.config.Types.Int64, 0, nil, "arg3", "arg2"), + Valu("r2", OpAdd64, c.config.Types.Int64, 0, nil, "arg1", "arg2"), + Valu("raddr", OpLocalAddr, c.config.Types.Int64.PtrTo(), 0, nil, "sp", "start"), + Valu("raddrdef", OpVarDef, types.TypeMem, 0, a, "start"), + Valu("r6", OpAdd64, c.config.Types.Int64, 0, nil, "r4", "r5"), + Valu("r3", OpAdd64, c.config.Types.Int64, 0, nil, "arg1", "arg2"), + Valu("r5", OpAdd64, c.config.Types.Int64, 0, nil, "r2", "r3"), + Valu("r10", OpAdd64, c.config.Types.Int64, 0, nil, "r6", "r9"), + Valu("rstore", OpStore, types.TypeMem, 0, c.config.Types.Int64, "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) + } +} + +// TestZCSE tests the zero arg cse. +func TestZCSE(t *testing.T) { + c := testConfig(t) + a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8) + + fun := c.Fun("entry", + Bloc("entry", + Valu("start", OpInitMem, types.TypeMem, 0, nil), + Valu("sp", OpSP, c.config.Types.Uintptr, 0, nil), + Valu("sb1", OpSB, c.config.Types.Uintptr, 0, nil), + Valu("sb2", OpSB, c.config.Types.Uintptr, 0, nil), + Valu("addr1", OpAddr, c.config.Types.Int64.PtrTo(), 0, nil, "sb1"), + Valu("addr2", OpAddr, c.config.Types.Int64.PtrTo(), 0, nil, "sb2"), + Valu("a1ld", OpLoad, c.config.Types.Int64, 0, nil, "addr1", "start"), + Valu("a2ld", OpLoad, c.config.Types.Int64, 0, nil, "addr2", "start"), + Valu("c1", OpConst64, c.config.Types.Int64, 1, nil), + Valu("r1", OpAdd64, c.config.Types.Int64, 0, nil, "a1ld", "c1"), + Valu("c2", OpConst64, c.config.Types.Int64, 1, nil), + Valu("r2", OpAdd64, c.config.Types.Int64, 0, nil, "a2ld", "c2"), + Valu("r3", OpAdd64, c.config.Types.Int64, 0, nil, "r1", "r2"), + Valu("raddr", OpLocalAddr, c.config.Types.Int64.PtrTo(), 0, nil, "sp", "start"), + Valu("raddrdef", OpVarDef, types.TypeMem, 0, a, "start"), + Valu("rstore", OpStore, types.TypeMem, 0, c.config.Types.Int64, "raddr", "r3", "raddrdef"), + Goto("exit")), + Bloc("exit", + Exit("rstore"))) + + CheckFunc(fun.f) + zcse(fun.f) + deadcode(fun.f) + CheckFunc(fun.f) + + if fun.values["c1"].Op != OpInvalid && fun.values["c2"].Op != OpInvalid { + t.Errorf("zsce should have removed c1 or c2") + } + if fun.values["sb1"].Op != OpInvalid && fun.values["sb2"].Op != OpInvalid { + t.Errorf("zsce should have removed sb1 or sb2") + } +} |