|  | // 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" | 
|  | "testing" | 
|  | ) | 
|  |  | 
|  | func TestWriteBarrierStoreOrder(t *testing.T) { | 
|  | // Make sure writebarrier phase works even StoreWB ops are not in dependency order | 
|  | c := testConfig(t) | 
|  | ptrType := c.config.Types.BytePtr | 
|  | fun := c.Fun("entry", | 
|  | Bloc("entry", | 
|  | Valu("start", OpInitMem, types.TypeMem, 0, nil), | 
|  | Valu("sb", OpSB, c.config.Types.Uintptr, 0, nil), | 
|  | Valu("sp", OpSP, c.config.Types.Uintptr, 0, nil), | 
|  | Valu("v", OpConstNil, ptrType, 0, nil), | 
|  | Valu("addr1", OpAddr, ptrType, 0, nil, "sb"), | 
|  | Valu("wb2", OpStore, types.TypeMem, 0, ptrType, "addr1", "v", "wb1"), | 
|  | Valu("wb1", OpStore, types.TypeMem, 0, ptrType, "addr1", "v", "start"), // wb1 and wb2 are out of order | 
|  | Goto("exit")), | 
|  | Bloc("exit", | 
|  | Exit("wb2"))) | 
|  |  | 
|  | CheckFunc(fun.f) | 
|  | writebarrier(fun.f) | 
|  | CheckFunc(fun.f) | 
|  | } | 
|  |  | 
|  | func TestWriteBarrierPhi(t *testing.T) { | 
|  | // Make sure writebarrier phase works for single-block loop, where | 
|  | // a Phi op takes the store in the same block as argument. | 
|  | // See issue #19067. | 
|  | c := testConfig(t) | 
|  | ptrType := c.config.Types.BytePtr | 
|  | fun := c.Fun("entry", | 
|  | Bloc("entry", | 
|  | Valu("start", OpInitMem, types.TypeMem, 0, nil), | 
|  | Valu("sb", OpSB, c.config.Types.Uintptr, 0, nil), | 
|  | Valu("sp", OpSP, c.config.Types.Uintptr, 0, nil), | 
|  | Goto("loop")), | 
|  | Bloc("loop", | 
|  | Valu("phi", OpPhi, types.TypeMem, 0, nil, "start", "wb"), | 
|  | Valu("v", OpConstNil, ptrType, 0, nil), | 
|  | Valu("addr", OpAddr, ptrType, 0, nil, "sb"), | 
|  | Valu("wb", OpStore, types.TypeMem, 0, ptrType, "addr", "v", "phi"), // has write barrier | 
|  | Goto("loop"))) | 
|  |  | 
|  | CheckFunc(fun.f) | 
|  | writebarrier(fun.f) | 
|  | CheckFunc(fun.f) | 
|  | } |