go/test
Pat Gavlin 359f44910f cmd/compile: fix long RMW bit operations on AMD64
Under certain circumstances, the existing rules for bit operations can
produce code that writes beyond its intended bounds. For example,
consider the following code:

    func repro(b []byte, addr, bit int32) {
	    _ = b[3]
	    v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 | 1<<(bit&31)
	    b[0] = byte(v)
	    b[1] = byte(v >> 8)
	    b[2] = byte(v >> 16)
	    b[3] = byte(v >> 24)
    }

Roughly speaking:

1. The expression `1 << (bit & 31)` is rewritten into `(SHLL 1 bit)`
2. The expression `uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 |
   uint32(b[3])<<24` is rewritten into `(MOVLload &b[0])`
3. The statements `b[0] = byte(v) ... b[3] = byte(v >> 24)` are
   rewritten into `(MOVLstore &b[0], v)`
4. `(ORL (SHLL 1, bit) (MOVLload &b[0]))` is rewritten into
   `(BTSL (MOVLload &b[0]) bit)`. This is a valid transformation because
   the destination is a register: in this case, the bit offset is masked
   by the number of bits in the destination register. This is identical
   to the masking performed by `SHL`.
5. `(MOVLstore &b[0] (BTSL (MOVLload &b[0]) bit))` is rewritten into
   `(BTSLmodify &b[0] bit)`. This is an invalid transformation because
   the destination is memory: in this case, the bit offset is not
   masked, and the chosen instruction may write outside its intended
   32-bit location.

These changes fix the invalid rewrite performed in step (5) by
explicitly maksing the bit offset operand to `BT(S|R|C)(L|Q)modify`. In
the example above, the adjusted rules produce
`(BTSLmodify &b[0] (ANDLconst [31] bit))` in step (5).

These changes also add several new rules to rewrite bit sets, toggles,
and clears that are rooted at `(OR|XOR|AND)(L|Q)modify` operators into
appropriate `BT(S|R|C)(L|Q)modify` operators. These rules catch cases
where `MOV(L|Q)store ((OR|XOR|AND)(L|Q) ...)` is rewritten to
`(OR|XOR|AND)(L|Q)modify` before the `(OR|XOR|AND)(L|Q) ...` can be
rewritten to `BT(S|R|C)(L|Q) ...`.

Overall, compilecmp reports small improvements in code size on
darwin/amd64 when the changes to the compiler itself are exlcuded:

file                               before   after    Δ       %
runtime.s                          536464   536412   -52     -0.010%
bytes.s                            32629    32593    -36     -0.110%
strings.s                          44565    44529    -36     -0.081%
os/signal.s                        7967     7959     -8      -0.100%
cmd/vendor/golang.org/x/sys/unix.s 81686    81678    -8      -0.010%
math/big.s                         188235   188253   +18     +0.010%
cmd/link/internal/loader.s         89295    89056    -239    -0.268%
cmd/link/internal/ld.s             633551   633232   -319    -0.050%
cmd/link/internal/arm.s            18934    18928    -6      -0.032%
cmd/link/internal/arm64.s          31814    31801    -13     -0.041%
cmd/link/internal/riscv64.s        7347     7345     -2      -0.027%
cmd/compile/internal/ssa.s         4029173  4033066  +3893   +0.097%
total                              21298280 21301472 +3192   +0.015%

Change-Id: I2e560548b515865129e1724e150e30540e9d29ce
GitHub-Last-Rev: 9a42bd29a5
GitHub-Pull-Request: golang/go#45242
Reviewed-on: https://go-review.googlesource.com/c/go/+/304869
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
2021-03-26 19:40:37 +00:00
..
abi cmd/compile: fix open defer of method call 2021-03-16 19:23:36 +00:00
alias3.dir
bench
chan
closure3.dir [dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE 2021-01-20 22:53:32 +00:00
closure5.dir [dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE 2021-01-20 22:53:32 +00:00
codegen cmd/compile: fix long RMW bit operations on AMD64 2021-03-26 19:40:37 +00:00
ddd2.dir
dwarf
fixedbugs cmd/compile: fix long RMW bit operations on AMD64 2021-03-26 19:40:37 +00:00
import2.dir
import4.dir
interface
intrinsic.dir
ken
linkname.dir
method4.dir
oldescape_linkname.dir
retjmp.dir
runtime
stress
syntax
typeparam cmd/compile: replace calls to typecheck with transform functions 2021-03-23 04:23:52 +00:00
uintptrescapes.dir
64bit.go
235.go
alg.go
alias.go
alias1.go
alias2.go
alias3.go
align.go
append.go
append1.go
args.go
armimm.go
assign.go
assign1.go
atomicload.go
bigalg.go
bigmap.go
blank.go
blank1.go
bom.go
bombad.go
bounds.go
cannotassign.go
chancap.go [dev.regabi] cmd/compile: remove toolstash scaffolding 2021-01-05 21:44:30 +00:00
chanlinear.go
char_lit.go
char_lit1.go cmd/compile: do not report error for invalid constant 2021-03-05 18:46:43 +00:00
checkbce.go
clearfat.go
closedchan.go
closure.go
closure1.go
closure2.go [dev.regabi] test: add another closure test case 2021-01-01 13:44:37 +00:00
closure3.go cmd/compile: disable inlining functions with closures for now 2021-02-24 21:34:21 +00:00
closure4.go
closure5.go [dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE 2021-01-20 22:53:32 +00:00
closure6.go [dev.regabi] cmd/compile: fix escape analysis problem with closures 2021-01-23 02:15:24 +00:00
closure7.go [dev.regabi] test: add a test for inlining closures 2021-02-01 18:28:05 +00:00
cmp.go
cmp6.go
cmplx.go
cmplxdivide.c
cmplxdivide.go
cmplxdivide1.go
complit.go
complit1.go
compos.go
const.go
const1.go
const2.go
const3.go
const4.go
const5.go
const6.go
const7.go [dev.typeparams] cmd/compile: refuse excessively long constants 2021-02-03 20:22:34 +00:00
convert.go
convert1.go
convert2.go
convert3.go
convlit.go cmd/compile/internal/types2: refactor untyped conversions 2021-03-23 05:11:09 +00:00
convlit1.go
convT2X.go
copy.go
copy1.go
crlf.go
ddd.go
ddd1.go
ddd2.go
decl.go
declbad.go
defer.go
defererrcheck.go
deferfin.go [dev.regabi] test: enable finalizer tests on !amd64 2021-01-05 21:11:31 +00:00
defernil.go
deferprint.go
deferprint.out
devirt.go
directive.go
divide.go
divmod.go
embedfunc.go cmd/compile: require 'go 1.16' go.mod line for //go:embed 2021-01-19 20:07:52 +00:00
embedvers.go cmd/compile: require 'go 1.16' go.mod line for //go:embed 2021-01-19 20:07:52 +00:00
empty.go
env.go
eof.go
eof1.go
escape.go
escape2.go [dev.regabi] cmd/compile: convert OPANIC argument to interface{} during typecheck 2021-01-18 05:55:08 +00:00
escape2n.go [dev.regabi] cmd/compile: convert OPANIC argument to interface{} during typecheck 2021-01-18 05:55:08 +00:00
escape3.go
escape4.go [dev.regabi] cmd/compile: convert OPANIC argument to interface{} during typecheck 2021-01-18 05:55:08 +00:00
escape5.go cmd/compile: fix escape analysis of heap-allocated results 2021-02-27 19:01:19 +00:00
escape_array.go
escape_calls.go
escape_closure.go
escape_field.go
escape_goto.go
escape_hash_maphash.go
escape_iface.go
escape_indir.go
escape_level.go
escape_map.go
escape_param.go [dev.regabi] cmd/compile: update ir/fmt for concrete types 2020-12-17 03:50:03 +00:00
escape_runtime_atomic.go
escape_selfassign.go
escape_slice.go
escape_struct_param1.go
escape_struct_param2.go
escape_struct_return.go
escape_sync_atomic.go
escape_unsafe.go
fibo.go
finprofiled.go
float_lit.go
float_lit2.go
float_lit3.go [dev.regabi] cmd/compile: enable rational constant arithmetic 2021-01-25 18:53:24 +00:00
floatcmp.go
for.go
func.go
func1.go
func2.go
func3.go
func4.go
func5.go
func6.go
func7.go
func8.go
funcdup.go
funcdup2.go
gc.go
gc1.go
gc2.go
gcgort.go
gcstring.go
goprint.go
goprint.out
goto.go
heapsampling.go
helloworld.go
helloworld.out
if.go
import.go
import1.go
import2.go
import4.go
import5.go
import6.go
index.go
index0.go
index1.go
index2.go
indirect.go
indirect1.go
init.go
init1.go
initcomma.go
initempty.go
initexp.go cmd/compile: fix exponential-time init-cycle reporting 2021-01-08 17:14:20 +00:00
initialize.go
initializerr.go
initloop.go
inline.go test: fix inline.go test for linux-amd64-noopt 2021-02-25 02:22:12 +00:00
inline_big.go
inline_caller.go
inline_callers.go
inline_literal.go
inline_math_bits_rotate.go
inline_sync.go
inline_variadic.go
int_lit.go
intcvt.go
intrinsic.go
intrinsic_atomic.go
iota.go
label.go
label1.go
linkmain.go
linkmain_run.go
linkname.go
linkname2.go
linkobj.go test: recognize and use gc build tag 2020-12-18 00:10:44 +00:00
linkx.go
linkx_run.go test: recognize and use gc build tag 2020-12-18 00:10:44 +00:00
literal.go
literal2.go
live.go cmd/compile: wrap/desugar defer calls for register abi 2021-03-23 23:08:19 +00:00
live1.go
live2.go
live_syscall.go
locklinear.go
loopbce.go
mainsig.go [dev.regabi] cmd/compile: cleanup for concrete types - noder 2020-12-17 04:43:46 +00:00
makechan.go
makemap.go
makenew.go
makeslice.go
mallocfin.go
map.go
map1.go
mapclear.go
maplinear.go
mergemul.go
method.go
method1.go
method2.go
method3.go
method4.go
method5.go
method6.go
method7.go [dev.typeparams] cmd/compile: fix MethodExpr handling with embedded fields 2021-01-26 17:05:06 +00:00
named.go
named1.go
nil.go
nilcheck.go
nilptr.go test: disable nilptr on windows/arm64 2021-02-19 00:40:22 +00:00
nilptr2.go
nilptr3.go [dev.regabi] cmd/compile: deref PAUTOHEAPs during SSA construction 2021-01-10 08:01:49 +00:00
nilptr4.go
nilptr5.go
nilptr5_aix.go
nilptr5_wasm.go
nilptr_aix.go
nosplit.go test: make nosplit test invariant to ABI wrappers 2021-03-18 16:51:25 +00:00
notinheap.go
notinheap2.go
notinheap3.go
nowritebarrier.go
nul1.go
opt_branchlikely.go
parentype.go
peano.go
phiopt.go
print.go
print.out
printbig.go
printbig.out
prove.go docs: fix spelling 2021-02-24 04:11:43 +00:00
range.go
README.md
recover.go
recover1.go
recover2.go
recover3.go
recover4.go
recover5.go
reflectmethod1.go
reflectmethod2.go
reflectmethod3.go
reflectmethod4.go
reflectmethod5.go
reflectmethod6.go
reflectmethod7.go cmd/compile: mark concrete call of reflect.(*rtype).Method as REFLECTMETHOD 2021-02-10 22:44:54 +00:00
rename.go
rename1.go
reorder.go [dev.regabi] cmd/compile: cleanup OAS2FUNC ordering 2021-01-16 23:19:26 +00:00
reorder2.go
retjmp.go
return.go
rotate.go
rotate0.go
rotate1.go
rotate2.go
rotate3.go
run.go test: recognize cgo build tag 2021-03-24 21:19:57 +00:00
rune.go
runtime.go
shift1.go
shift2.go
sieve.go
sigchld.go
sigchld.out
simassign.go
sinit.go
sinit_run.go test: recognize and use gc build tag 2020-12-18 00:10:44 +00:00
sizeof.go
slice3.go
slice3err.go
slicecap.go
sliceopt.go
solitaire.go
stack.go
stackobj.go
stackobj2.go
stackobj3.go
strcopy.go
strength.go
string_lit.go
stringrange.go
struct0.go
switch.go
switch2.go
switch3.go
switch4.go
switch5.go
switch6.go
switch7.go
tinyfin.go
torture.go
turing.go
typecheck.go
typecheckloop.go
typeswitch.go
typeswitch1.go
typeswitch2.go
typeswitch2b.go
typeswitch3.go
uintptrescapes.go
uintptrescapes2.go
uintptrescapes3.go
undef.go
used.go [dev.typeparams] all: merge dev.regabi (07569da) into dev.typeparams 2020-12-28 00:39:17 -08:00
utf.go
varerr.go
varinit.go
winbatch.go
writebarrier.go
zerodivide.go

The test directory contains tests of the Go tool chain and runtime. It includes black box tests, regression tests, and error output tests. They are run as part of all.bash.

To run just these tests, execute:

../bin/go run run.go

To run just tests from specified files in this directory, execute:

../bin/go run run.go -- file1.go file2.go ...

Standard library tests should be written as regular Go tests in the appropriate package.

The tool chain and runtime also have regular Go tests in their packages. The main reasons to add a new test to this directory are:

  • it is most naturally expressed using the test runner; or
  • it is also applicable to gccgo and other Go tool chains.