1
2
3
4
5 package ssacompile
6
7 import (
8 "strings"
9 "testing"
10
11 "cmd/compile/internal/ssa/ssaop"
12 "cmd/compile/internal/types"
13 )
14
15 func TestSCCPBasic(t *testing.T) {
16 c := testConfig(t)
17 fun := c.Fun("b1",
18 Bloc("b1",
19 Valu("mem", ssaop.OpInitMem, types.TypeMem, 0, nil),
20 Valu("v1", ssaop.OpConst64, c.config.Types.Int64, 20, nil),
21 Valu("v2", ssaop.OpConst64, c.config.Types.Int64, 21, nil),
22 Valu("v3", ssaop.OpConst64F, c.config.Types.Float64, 21.0, nil),
23 Valu("v4", ssaop.OpConstBool, c.config.Types.Bool, 1, nil),
24 Valu("t1", ssaop.OpAdd64, c.config.Types.Int64, 0, nil, "v1", "v2"),
25 Valu("t2", ssaop.OpDiv64, c.config.Types.Int64, 0, nil, "t1", "v1"),
26 Valu("t3", ssaop.OpAdd64, c.config.Types.Int64, 0, nil, "t1", "t2"),
27 Valu("t4", ssaop.OpSub64, c.config.Types.Int64, 0, nil, "t3", "v2"),
28 Valu("t5", ssaop.OpMul64, c.config.Types.Int64, 0, nil, "t4", "v2"),
29 Valu("t6", ssaop.OpMod64, c.config.Types.Int64, 0, nil, "t5", "v2"),
30 Valu("t7", ssaop.OpAnd64, c.config.Types.Int64, 0, nil, "t6", "v2"),
31 Valu("t8", ssaop.OpOr64, c.config.Types.Int64, 0, nil, "t7", "v2"),
32 Valu("t9", ssaop.OpXor64, c.config.Types.Int64, 0, nil, "t8", "v2"),
33 Valu("t10", ssaop.OpNeg64, c.config.Types.Int64, 0, nil, "t9"),
34 Valu("t11", ssaop.OpCom64, c.config.Types.Int64, 0, nil, "t10"),
35 Valu("t12", ssaop.OpNeg64, c.config.Types.Int64, 0, nil, "t11"),
36 Valu("t13", ssaop.OpFloor, c.config.Types.Float64, 0, nil, "v3"),
37 Valu("t14", ssaop.OpSqrt, c.config.Types.Float64, 0, nil, "t13"),
38 Valu("t15", ssaop.OpCeil, c.config.Types.Float64, 0, nil, "t14"),
39 Valu("t16", ssaop.OpTrunc, c.config.Types.Float64, 0, nil, "t15"),
40 Valu("t17", ssaop.OpRoundToEven, c.config.Types.Float64, 0, nil, "t16"),
41 Valu("t18", ssaop.OpTrunc64to32, c.config.Types.Int64, 0, nil, "t12"),
42 Valu("t19", ssaop.OpCvt64Fto64, c.config.Types.Float64, 0, nil, "t17"),
43 Valu("t20", ssaop.OpCtz64, c.config.Types.Int64, 0, nil, "v2"),
44 Valu("t21", ssaop.OpSlicemask, c.config.Types.Int64, 0, nil, "t20"),
45 Valu("t22", ssaop.OpIsNonNil, c.config.Types.Int64, 0, nil, "v2"),
46 Valu("t23", ssaop.OpNot, c.config.Types.Bool, 0, nil, "v4"),
47 Valu("t24", ssaop.OpEq64, c.config.Types.Bool, 0, nil, "v1", "v2"),
48 Valu("t25", ssaop.OpLess64, c.config.Types.Bool, 0, nil, "v1", "v2"),
49 Valu("t26", ssaop.OpLeq64, c.config.Types.Bool, 0, nil, "v1", "v2"),
50 Valu("t27", ssaop.OpEqB, c.config.Types.Bool, 0, nil, "v4", "v4"),
51 Valu("t28", ssaop.OpLsh64x64, c.config.Types.Int64, 0, nil, "v2", "v1"),
52 Valu("t29", ssaop.OpIsInBounds, c.config.Types.Int64, 0, nil, "v2", "v1"),
53 Valu("t30", ssaop.OpIsSliceInBounds, c.config.Types.Int64, 0, nil, "v2", "v1"),
54 Goto("b2")),
55 Bloc("b2",
56 Exit("mem")))
57 sccp(fun.f)
58 CheckFunc(fun.f)
59 for name, value := range fun.values {
60 if strings.HasPrefix(name, "t") {
61 if !isConst(value) {
62 t.Errorf("Must be constant: %v", value.LongString())
63 }
64 }
65 }
66 }
67
68 func TestSCCPIf(t *testing.T) {
69 c := testConfig(t)
70 fun := c.Fun("b1",
71 Bloc("b1",
72 Valu("mem", ssaop.OpInitMem, types.TypeMem, 0, nil),
73 Valu("v1", ssaop.OpConst64, c.config.Types.Int64, 0, nil),
74 Valu("v2", ssaop.OpConst64, c.config.Types.Int64, 1, nil),
75 Valu("cmp", ssaop.OpLess64, c.config.Types.Bool, 0, nil, "v1", "v2"),
76 If("cmp", "b2", "b3")),
77 Bloc("b2",
78 Valu("v3", ssaop.OpConst64, c.config.Types.Int64, 3, nil),
79 Goto("b4")),
80 Bloc("b3",
81 Valu("v4", ssaop.OpConst64, c.config.Types.Int64, 4, nil),
82 Goto("b4")),
83 Bloc("b4",
84 Valu("merge", ssaop.OpPhi, c.config.Types.Int64, 0, nil, "v3", "v4"),
85 Exit("mem")))
86 sccp(fun.f)
87 CheckFunc(fun.f)
88 for _, b := range fun.blocks {
89 for _, v := range b.Values {
90 if v == fun.values["merge"] {
91 if !isConst(v) {
92 t.Errorf("Must be constant: %v", v.LongString())
93 }
94 }
95 }
96 }
97 }
98
View as plain text