github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/cmd/compile/internal/ssa/cse_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ssa 6 7 import "testing" 8 9 type tstAux struct { 10 s string 11 } 12 13 // This tests for a bug found when partitioning, but not sorting by the Aux value. 14 func TestCSEAuxPartitionBug(t *testing.T) { 15 c := testConfig(t) 16 arg1Aux := &tstAux{"arg1-aux"} 17 arg2Aux := &tstAux{"arg2-aux"} 18 arg3Aux := &tstAux{"arg3-aux"} 19 20 // construct lots of values with args that have aux values and place 21 // them in an order that triggers the bug 22 fun := Fun(c, "entry", 23 Bloc("entry", 24 Valu("start", OpInitMem, TypeMem, 0, nil), 25 Valu("sp", OpSP, TypeBytePtr, 0, nil), 26 Valu("r7", OpAdd64, TypeInt64, 0, nil, "arg3", "arg1"), 27 Valu("r1", OpAdd64, TypeInt64, 0, nil, "arg1", "arg2"), 28 Valu("arg1", OpArg, TypeInt64, 0, arg1Aux), 29 Valu("arg2", OpArg, TypeInt64, 0, arg2Aux), 30 Valu("arg3", OpArg, TypeInt64, 0, arg3Aux), 31 Valu("r9", OpAdd64, TypeInt64, 0, nil, "r7", "r8"), 32 Valu("r4", OpAdd64, TypeInt64, 0, nil, "r1", "r2"), 33 Valu("r8", OpAdd64, TypeInt64, 0, nil, "arg3", "arg2"), 34 Valu("r2", OpAdd64, TypeInt64, 0, nil, "arg1", "arg2"), 35 Valu("raddr", OpAddr, TypeInt64Ptr, 0, nil, "sp"), 36 Valu("raddrdef", OpVarDef, TypeMem, 0, nil, "start"), 37 Valu("r6", OpAdd64, TypeInt64, 0, nil, "r4", "r5"), 38 Valu("r3", OpAdd64, TypeInt64, 0, nil, "arg1", "arg2"), 39 Valu("r5", OpAdd64, TypeInt64, 0, nil, "r2", "r3"), 40 Valu("r10", OpAdd64, TypeInt64, 0, nil, "r6", "r9"), 41 Valu("rstore", OpStore, TypeMem, 8, nil, "raddr", "r10", "raddrdef"), 42 Goto("exit")), 43 Bloc("exit", 44 Exit("rstore"))) 45 46 CheckFunc(fun.f) 47 domTree(fun.f) 48 cse(fun.f) 49 deadcode(fun.f) 50 CheckFunc(fun.f) 51 52 s1Cnt := 2 53 // r1 == r2 == r3, needs to remove two of this set 54 s2Cnt := 1 55 // r4 == r5, needs to remove one of these 56 for k, v := range fun.values { 57 if v.Op == OpInvalid { 58 switch k { 59 case "r1": 60 fallthrough 61 case "r2": 62 fallthrough 63 case "r3": 64 if s1Cnt == 0 { 65 t.Errorf("cse removed all of r1,r2,r3") 66 } 67 s1Cnt-- 68 69 case "r4": 70 fallthrough 71 case "r5": 72 if s2Cnt == 0 { 73 t.Errorf("cse removed all of r4,r5") 74 } 75 s2Cnt-- 76 default: 77 t.Errorf("cse removed %s, but shouldn't have", k) 78 } 79 } 80 } 81 82 if s1Cnt != 0 || s2Cnt != 0 { 83 t.Errorf("%d values missed during cse", s1Cnt+s2Cnt) 84 } 85 } 86 87 // TestZCSE tests the zero arg cse. 88 func TestZCSE(t *testing.T) { 89 c := testConfig(t) 90 91 fun := Fun(c, "entry", 92 Bloc("entry", 93 Valu("start", OpInitMem, TypeMem, 0, nil), 94 Valu("sp", OpSP, TypeBytePtr, 0, nil), 95 Valu("sb1", OpSB, TypeBytePtr, 0, nil), 96 Valu("sb2", OpSB, TypeBytePtr, 0, nil), 97 Valu("addr1", OpAddr, TypeInt64Ptr, 0, nil, "sb1"), 98 Valu("addr2", OpAddr, TypeInt64Ptr, 0, nil, "sb2"), 99 Valu("a1ld", OpLoad, TypeInt64, 0, nil, "addr1", "start"), 100 Valu("a2ld", OpLoad, TypeInt64, 0, nil, "addr2", "start"), 101 Valu("c1", OpConst64, TypeInt64, 1, nil), 102 Valu("r1", OpAdd64, TypeInt64, 0, nil, "a1ld", "c1"), 103 Valu("c2", OpConst64, TypeInt64, 1, nil), 104 Valu("r2", OpAdd64, TypeInt64, 0, nil, "a2ld", "c2"), 105 Valu("r3", OpAdd64, TypeInt64, 0, nil, "r1", "r2"), 106 Valu("raddr", OpAddr, TypeInt64Ptr, 0, nil, "sp"), 107 Valu("raddrdef", OpVarDef, TypeMem, 0, nil, "start"), 108 Valu("rstore", OpStore, TypeMem, 8, nil, "raddr", "r3", "raddrdef"), 109 Goto("exit")), 110 Bloc("exit", 111 Exit("rstore"))) 112 113 CheckFunc(fun.f) 114 zcse(fun.f) 115 deadcode(fun.f) 116 CheckFunc(fun.f) 117 118 if fun.values["c1"].Op != OpInvalid && fun.values["c2"].Op != OpInvalid { 119 t.Errorf("zsce should have removed c1 or c2") 120 } 121 if fun.values["sb1"].Op != OpInvalid && fun.values["sb2"].Op != OpInvalid { 122 t.Errorf("zsce should have removed sb1 or sb2") 123 } 124 }