1
2
3
4
5 package ssa
6
7 import (
8 "cmd/compile/internal/types"
9 "cmd/internal/src"
10 "testing"
11 )
12
13 type tstAux struct {
14 s string
15 }
16
17 func (*tstAux) CanBeAnSSAAux() {}
18
19
20 func TestCSEAuxPartitionBug(t *testing.T) {
21 c := testConfig(t)
22 arg1Aux := &tstAux{"arg1-aux"}
23 arg2Aux := &tstAux{"arg2-aux"}
24 arg3Aux := &tstAux{"arg3-aux"}
25 a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8)
26
27
28
29 fun := c.Fun("entry",
30 Bloc("entry",
31 Valu("start", OpInitMem, types.TypeMem, 0, nil),
32 Valu("sp", OpSP, c.config.Types.Uintptr, 0, nil),
33 Valu("r7", OpAdd64, c.config.Types.Int64, 0, nil, "arg3", "arg1"),
34 Valu("r1", OpAdd64, c.config.Types.Int64, 0, nil, "arg1", "arg2"),
35 Valu("arg1", OpArg, c.config.Types.Int64, 0, arg1Aux),
36 Valu("arg2", OpArg, c.config.Types.Int64, 0, arg2Aux),
37 Valu("arg3", OpArg, c.config.Types.Int64, 0, arg3Aux),
38 Valu("r9", OpAdd64, c.config.Types.Int64, 0, nil, "r7", "r8"),
39 Valu("r4", OpAdd64, c.config.Types.Int64, 0, nil, "r1", "r2"),
40 Valu("r8", OpAdd64, c.config.Types.Int64, 0, nil, "arg3", "arg2"),
41 Valu("r2", OpAdd64, c.config.Types.Int64, 0, nil, "arg1", "arg2"),
42 Valu("raddr", OpLocalAddr, c.config.Types.Int64.PtrTo(), 0, nil, "sp", "start"),
43 Valu("raddrdef", OpVarDef, types.TypeMem, 0, a, "start"),
44 Valu("r6", OpAdd64, c.config.Types.Int64, 0, nil, "r4", "r5"),
45 Valu("r3", OpAdd64, c.config.Types.Int64, 0, nil, "arg1", "arg2"),
46 Valu("r5", OpAdd64, c.config.Types.Int64, 0, nil, "r2", "r3"),
47 Valu("r10", OpAdd64, c.config.Types.Int64, 0, nil, "r6", "r9"),
48 Valu("rstore", OpStore, types.TypeMem, 0, c.config.Types.Int64, "raddr", "r10", "raddrdef"),
49 Goto("exit")),
50 Bloc("exit",
51 Exit("rstore")))
52
53 CheckFunc(fun.f)
54 cse(fun.f)
55 deadcode(fun.f)
56 CheckFunc(fun.f)
57
58 s1Cnt := 2
59
60 s2Cnt := 1
61
62 for k, v := range fun.values {
63 if v.Op == OpInvalid {
64 switch k {
65 case "r1":
66 fallthrough
67 case "r2":
68 fallthrough
69 case "r3":
70 if s1Cnt == 0 {
71 t.Errorf("cse removed all of r1,r2,r3")
72 }
73 s1Cnt--
74
75 case "r4":
76 fallthrough
77 case "r5":
78 if s2Cnt == 0 {
79 t.Errorf("cse removed all of r4,r5")
80 }
81 s2Cnt--
82 default:
83 t.Errorf("cse removed %s, but shouldn't have", k)
84 }
85 }
86 }
87
88 if s1Cnt != 0 || s2Cnt != 0 {
89 t.Errorf("%d values missed during cse", s1Cnt+s2Cnt)
90 }
91 }
92
93
94 func TestZCSE(t *testing.T) {
95 c := testConfig(t)
96 a := c.Frontend().Auto(src.NoXPos, c.config.Types.Int8)
97
98 fun := c.Fun("entry",
99 Bloc("entry",
100 Valu("start", OpInitMem, types.TypeMem, 0, nil),
101 Valu("sp", OpSP, c.config.Types.Uintptr, 0, nil),
102 Valu("sb1", OpSB, c.config.Types.Uintptr, 0, nil),
103 Valu("sb2", OpSB, c.config.Types.Uintptr, 0, nil),
104 Valu("addr1", OpAddr, c.config.Types.Int64.PtrTo(), 0, nil, "sb1"),
105 Valu("addr2", OpAddr, c.config.Types.Int64.PtrTo(), 0, nil, "sb2"),
106 Valu("a1ld", OpLoad, c.config.Types.Int64, 0, nil, "addr1", "start"),
107 Valu("a2ld", OpLoad, c.config.Types.Int64, 0, nil, "addr2", "start"),
108 Valu("c1", OpConst64, c.config.Types.Int64, 1, nil),
109 Valu("r1", OpAdd64, c.config.Types.Int64, 0, nil, "a1ld", "c1"),
110 Valu("c2", OpConst64, c.config.Types.Int64, 1, nil),
111 Valu("r2", OpAdd64, c.config.Types.Int64, 0, nil, "a2ld", "c2"),
112 Valu("r3", OpAdd64, c.config.Types.Int64, 0, nil, "r1", "r2"),
113 Valu("raddr", OpLocalAddr, c.config.Types.Int64.PtrTo(), 0, nil, "sp", "start"),
114 Valu("raddrdef", OpVarDef, types.TypeMem, 0, a, "start"),
115 Valu("rstore", OpStore, types.TypeMem, 0, c.config.Types.Int64, "raddr", "r3", "raddrdef"),
116 Goto("exit")),
117 Bloc("exit",
118 Exit("rstore")))
119
120 CheckFunc(fun.f)
121 zcse(fun.f)
122 deadcode(fun.f)
123 CheckFunc(fun.f)
124
125 if fun.values["c1"].Op != OpInvalid && fun.values["c2"].Op != OpInvalid {
126 t.Errorf("zsce should have removed c1 or c2")
127 }
128 if fun.values["sb1"].Op != OpInvalid && fun.values["sb2"].Op != OpInvalid {
129 t.Errorf("zsce should have removed sb1 or sb2")
130 }
131 }
132
View as plain text