github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/compile/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 ( 8 "testing" 9 10 "github.com/go-asm/go/cmd/compile/types" 11 ) 12 13 type tstAux struct { 14 s string 15 } 16 17 func (*tstAux) CanBeAnSSAAux() {} 18 19 // This tests for a bug found when partitioning, but not sorting by the Aux value. 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.Temp(c.config.Types.Int8.PtrTo()) 26 27 // construct lots of values with args that have aux values and place 28 // them in an order that triggers the bug 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 // r1 == r2 == r3, needs to remove two of this set 60 s2Cnt := 1 61 // r4 == r5, needs to remove one of these 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 // TestZCSE tests the zero arg cse. 94 func TestZCSE(t *testing.T) { 95 c := testConfig(t) 96 a := c.Temp(c.config.Types.Int8.PtrTo()) 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 }