mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
4d9dd35806
"Division by invariant integers using multiplication" paper by Granlund and Montgomery contains a method for directly computing divisibility (x%c == 0 for c constant) by means of the modular inverse. The method is further elaborated in "Hacker's Delight" by Warren Section 10-17 This general rule can compute divisibilty by one multiplication, and add and a compare for odd divisors and an additional rotate for even divisors. To apply the divisibility rule, we must take into account the rules to rewrite x%c = x-((x/c)*c) and (x/c) for c constant on the first optimization pass "opt". This complicates the matching as we want to match only in the cases where the result of (x/c) is not also needed. So, we must match on the expanded form of (x/c) in the expression x == c*(x/c) in the "late opt" pass after common subexpresion elimination. Note, that if there is an intermediate opt pass introduced in the future we could simplify these rules by delaying the magic division rewrite to "late opt" and matching directly on (x/c) in the intermediate opt pass. On amd64, the divisibility check is 30-45% faster. name old time/op new time/op delta` DivisiblePow2constI64-4 0.83ns ± 1% 0.82ns ± 0% ~ (p=0.079 n=5+4) DivisibleconstI64-4 2.68ns ± 1% 1.87ns ± 0% -30.33% (p=0.000 n=5+4) DivisibleWDivconstI64-4 2.69ns ± 1% 2.71ns ± 3% ~ (p=1.000 n=5+5) DivisiblePow2constI32-4 1.15ns ± 1% 1.15ns ± 0% ~ (p=0.238 n=5+4) DivisibleconstI32-4 2.24ns ± 1% 1.20ns ± 0% -46.48% (p=0.016 n=5+4) DivisibleWDivconstI32-4 2.27ns ± 1% 2.27ns ± 1% ~ (p=0.683 n=5+5) DivisiblePow2constI16-4 0.81ns ± 1% 0.82ns ± 1% ~ (p=0.135 n=5+5) DivisibleconstI16-4 2.11ns ± 2% 1.20ns ± 1% -42.99% (p=0.008 n=5+5) DivisibleWDivconstI16-4 2.23ns ± 0% 2.27ns ± 2% +1.79% (p=0.029 n=4+4) DivisiblePow2constI8-4 0.81ns ± 1% 0.81ns ± 1% ~ (p=0.286 n=5+5) DivisibleconstI8-4 2.13ns ± 3% 1.19ns ± 1% -43.84% (p=0.008 n=5+5) DivisibleWDivconstI8-4 2.23ns ± 1% 2.25ns ± 1% ~ (p=0.183 n=5+5) Fixes #30282 Fixes #15806 Change-Id: Id20d78263a4fdfe0509229ae4dfa2fede83fc1d0 Reviewed-on: https://go-review.googlesource.com/c/go/+/173998 Run-TryBot: Brian Kessler <brian.m.kessler@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> |
||
---|---|---|
.. | ||
alias3.dir | ||
bench | ||
chan | ||
closure3.dir | ||
codegen | ||
ddd2.dir | ||
dwarf | ||
fixedbugs | ||
import2.dir | ||
import4.dir | ||
interface | ||
intrinsic.dir | ||
ken | ||
linkname.dir | ||
method4.dir | ||
oldescape_linkname.dir | ||
retjmp.dir | ||
runtime | ||
stress | ||
syntax | ||
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 | ||
chancap.go | ||
chanlinear.go | ||
char_lit.go | ||
char_lit1.go | ||
checkbce.go | ||
clearfat.go | ||
closedchan.go | ||
closure.go | ||
closure1.go | ||
closure2.go | ||
closure3.go | ||
closure4.go | ||
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 | ||
convert.go | ||
convert1.go | ||
convert2.go | ||
convert3.go | ||
convlit.go | ||
convlit1.go | ||
convT2X.go | ||
copy.go | ||
copy1.go | ||
crlf.go | ||
ddd.go | ||
ddd1.go | ||
ddd2.go | ||
decl.go | ||
declbad.go | ||
defer.go | ||
deferfin.go | ||
deferprint.go | ||
deferprint.out | ||
devirt.go | ||
divide.go | ||
divmod.go | ||
empty.go | ||
env.go | ||
eof.go | ||
eof1.go | ||
escape.go | ||
escape2.go | ||
escape2n.go | ||
escape3.go | ||
escape4.go | ||
escape5.go | ||
escape_array.go | ||
escape_because.go | ||
escape_calls.go | ||
escape_closure.go | ||
escape_field.go | ||
escape_iface.go | ||
escape_indir.go | ||
escape_level.go | ||
escape_map.go | ||
escape_param.go | ||
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 | ||
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 | ||
initialize.go | ||
initializerr.go | ||
initloop.go | ||
inline.go | ||
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 | ||
linkobj.go | ||
linkx.go | ||
linkx_run.go | ||
literal.go | ||
literal2.go | ||
live.go | ||
live1.go | ||
live2.go | ||
live_syscall.go | ||
locklinear.go | ||
loopbce.go | ||
makechan.go | ||
makemap.go | ||
makenew.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 | ||
named.go | ||
named1.go | ||
nil.go | ||
nilcheck.go | ||
nilptr.go | ||
nilptr2.go | ||
nilptr3.go | ||
nilptr4.go | ||
nilptr5.go | ||
nilptr5_aix.go | ||
nilptr5_wasm.go | ||
nilptr_aix.go | ||
nosplit.go | ||
notinheap.go | ||
notinheap2.go | ||
notinheap3.go | ||
nowritebarrier.go | ||
nul1.go | ||
oldescape2.go | ||
oldescape2n.go | ||
oldescape5.go | ||
oldescape_calls.go | ||
oldescape_closure.go | ||
oldescape_field.go | ||
oldescape_iface.go | ||
oldescape_linkname.go | ||
oldescape_param.go | ||
oldescape_struct_return.go | ||
opt_branchlikely.go | ||
parentype.go | ||
peano.go | ||
phiopt.go | ||
print.go | ||
print.out | ||
printbig.go | ||
printbig.out | ||
prove.go | ||
range.go | ||
README.md | ||
recover.go | ||
recover1.go | ||
recover2.go | ||
recover3.go | ||
recover4.go | ||
recover5.go | ||
reflectmethod1.go | ||
reflectmethod2.go | ||
reflectmethod3.go | ||
reflectmethod4.go | ||
rename.go | ||
rename1.go | ||
reorder.go | ||
reorder2.go | ||
retjmp.go | ||
return.go | ||
rotate.go | ||
rotate0.go | ||
rotate1.go | ||
rotate2.go | ||
rotate3.go | ||
run.go | ||
rune.go | ||
runtime.go | ||
shift1.go | ||
shift2.go | ||
sieve.go | ||
sigchld.go | ||
sigchld.out | ||
simassign.go | ||
sinit.go | ||
sinit_run.go | ||
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 | ||
typeswitch3.go | ||
uintptrescapes.go | ||
uintptrescapes2.go | ||
undef.go | ||
utf.go | ||
varerr.go | ||
varinit.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
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.