From 38d35f49e778160198a013b957e0b661b38b2c45 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Wed, 19 Apr 2017 10:00:32 -0700 Subject: [release-branch.go1.8] crypto/elliptic: fix carry bug in x86-64 P-256 implementation. Patch from Vlad Krasnov and confirmed to be under CLA. Fixes #20040. Change-Id: Ieb8436c4dcb6669a1620f1e0d257efd047b1b87c Reviewed-on: https://go-review.googlesource.com/41070 Run-TryBot: Adam Langley TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick (cherry picked from commit 9294fa2749ffee7edbbb817a0ef9fe633136fa9c) Reviewed-on: https://go-review.googlesource.com/43770 Run-TryBot: Brad Fitzpatrick Reviewed-by: Chris Broadfoot --- src/crypto/elliptic/elliptic_test.go | 36 ++++++++++++++++++++++++++++++++++++ src/crypto/elliptic/p256_asm_amd64.s | 10 +++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/crypto/elliptic/elliptic_test.go b/src/crypto/elliptic/elliptic_test.go index 902c414383..c3e4c17d25 100644 --- a/src/crypto/elliptic/elliptic_test.go +++ b/src/crypto/elliptic/elliptic_test.go @@ -300,6 +300,29 @@ var p224BaseMultTests = []baseMultTest{ }, } +type scalarMultTest struct { + k string + xIn, yIn string + xOut, yOut string +} + +var p256MultTests = []scalarMultTest{ + { + "2a265f8bcbdcaf94d58519141e578124cb40d64a501fba9c11847b28965bc737", + "023819813ac969847059028ea88a1f30dfbcde03fc791d3a252c6b41211882ea", + "f93e4ae433cc12cf2a43fc0ef26400c0e125508224cdb649380f25479148a4ad", + "4d4de80f1534850d261075997e3049321a0864082d24a917863366c0724f5ae3", + "a22d2b7f7818a3563e0f7a76c9bf0921ac55e06e2e4d11795b233824b1db8cc0", + }, + { + "313f72ff9fe811bf573176231b286a3bdb6f1b14e05c40146590727a71c3bccd", + "cc11887b2d66cbae8f4d306627192522932146b42f01d3c6f92bd5c8ba739b06", + "a2f08a029cd06b46183085bae9248b0ed15b70280c7ef13a457f5af382426031", + "831c3f6b5f762d2f461901577af41354ac5f228c2591f84f8a6e51e2e3f17991", + "93f90934cd0ef2c698cc471c60a93524e87ab31ca2412252337f364513e43684", + }, +} + func TestBaseMult(t *testing.T) { p224 := P224() for i, e := range p224BaseMultTests { @@ -379,6 +402,19 @@ func TestP256Mult(t *testing.T) { break } } + + for i, e := range p256MultTests { + x, _ := new(big.Int).SetString(e.xIn, 16) + y, _ := new(big.Int).SetString(e.yIn, 16) + k, _ := new(big.Int).SetString(e.k, 16) + expectedX, _ := new(big.Int).SetString(e.xOut, 16) + expectedY, _ := new(big.Int).SetString(e.yOut, 16) + + xx, yy := p256.ScalarMult(x, y, k.Bytes()) + if xx.Cmp(expectedX) != 0 || yy.Cmp(expectedY) != 0 { + t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, expectedX, expectedY) + } + } } func TestInfinity(t *testing.T) { diff --git a/src/crypto/elliptic/p256_asm_amd64.s b/src/crypto/elliptic/p256_asm_amd64.s index 6c7bde16e5..ea4a6fab9a 100644 --- a/src/crypto/elliptic/p256_asm_amd64.s +++ b/src/crypto/elliptic/p256_asm_amd64.s @@ -1314,12 +1314,12 @@ TEXT p256SubInternal(SB),NOSPLIT,$0 ADCQ p256const0<>(SB), acc5 ADCQ $0, acc6 ADCQ p256const1<>(SB), acc7 - ADCQ $0, mul0 + ANDQ $1, mul0 - CMOVQNE acc0, acc4 - CMOVQNE acc1, acc5 - CMOVQNE acc2, acc6 - CMOVQNE acc3, acc7 + CMOVQEQ acc0, acc4 + CMOVQEQ acc1, acc5 + CMOVQEQ acc2, acc6 + CMOVQEQ acc3, acc7 RET /* ---------------------------------------*/ -- cgit v1.2.3-54-g00ecf From c9688ddb6b9391983879269768a4243b6cd8f5a9 Mon Sep 17 00:00:00 2001 From: Chris Broadfoot Date: Tue, 23 May 2017 10:36:28 -0700 Subject: [release-branch.go1.8] doc: document go1.8.2 and go1.7.6 Change-Id: I2ed2e8c4890a65288cf3066ebe3c1d9a16fb4c05 Reviewed-on: https://go-review.googlesource.com/43990 Reviewed-by: Brad Fitzpatrick Reviewed-on: https://go-review.googlesource.com/43993 Reviewed-by: Chris Broadfoot --- doc/devel/release.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/devel/release.html b/doc/devel/release.html index c4ca6a625f..0be3dbbbd9 100644 --- a/doc/devel/release.html +++ b/doc/devel/release.html @@ -49,6 +49,13 @@ See the Go 1.8.1 milestone on our issue tracker for details.

+

+go1.8.2 (released 2017/05/23) includes a security fix to the +crypto/elliptic package. +See the Go +1.8.2 milestone on our issue tracker for details. +

+

go1.7 (released 2016/08/15)

@@ -95,6 +102,13 @@ See the Go 1.7.5 milestone on our issue tracker for details.

+

+go1.7.6 (released 2017/05/23) includes the same security fix as Go 1.8.2 and +was released at the same time. +See the Go +1.8.2 milestone on our issue tracker for details. +

+

go1.6 (released 2016/02/17)

-- cgit v1.2.3-54-g00ecf From 59870f9e19384c3155f603f799b61b401fa20cc9 Mon Sep 17 00:00:00 2001 From: Chris Broadfoot Date: Tue, 23 May 2017 10:47:02 -0700 Subject: [release-branch.go1.8] go1.8.2 Change-Id: Ib04878cbfbb0c09fbd0cc614df314c835e9a6eb0 Reviewed-on: https://go-review.googlesource.com/43991 Reviewed-by: Brad Fitzpatrick --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 854106e985..68ae0a04eb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.8 \ No newline at end of file +go1.8.2 \ No newline at end of file -- cgit v1.2.3-54-g00ecf From b6a8fc8d8cef50a62e6f5169054ae4c800481386 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 19 May 2017 19:39:20 +0000 Subject: [release-branch.go1.8] doc: remove mentions of yacc tool It was removed in CL 27325. Fixes #20431 Change-Id: I6842851444186e19029d040f61fdf4f87a3103a6 Reviewed-on: https://go-review.googlesource.com/43771 Reviewed-by: Ian Lance Taylor (cherry picked from commit deebd8fe273df2de2d590ee41ae1155c521219e9) Reviewed-on: https://go-review.googlesource.com/43772 Reviewed-by: Chris Broadfoot --- doc/cmd.html | 8 -------- 1 file changed, 8 deletions(-) diff --git a/doc/cmd.html b/doc/cmd.html index 992f176014..4d6ac01dc4 100644 --- a/doc/cmd.html +++ b/doc/cmd.html @@ -22,8 +22,6 @@ using the go tool subcommand, such as go tool vet. This style of invocation allows, for instance, checking a single source file rather than an entire package: go tool vet myprogram.go as compared to go vet mypackage. -Some of the commands, such as yacc, are accessible only through -the go tool subcommand.

@@ -95,12 +93,6 @@ gofmt command with more general options. calls whose arguments do not align with the format string. - -yacc -     -Yacc is a version of yacc that generates parsers implemented in Go. - -

-- cgit v1.2.3-54-g00ecf From fb9770f09b99293a4aba55ec1d0fc6e6733b9e6e Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 11 May 2017 15:22:10 -0400 Subject: [release-branch.go1.8] runtime: print debug info on "base out of range" Cherry-pick of CL 43310. This adds debugging information when we panic with "heapBitsForSpan: base out of range". Updates #20259. Change-Id: I0dc1a106aa9e9531051c7d08867ace5ef230eb3f Reviewed-on: https://go-review.googlesource.com/43410 Run-TryBot: Austin Clements Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/runtime/mbitmap.go | 1 + 1 file changed, 1 insertion(+) diff --git a/src/runtime/mbitmap.go b/src/runtime/mbitmap.go index 89d8a4cc76..9b988fae25 100644 --- a/src/runtime/mbitmap.go +++ b/src/runtime/mbitmap.go @@ -374,6 +374,7 @@ func heapBitsForAddr(addr uintptr) heapBits { // heapBitsForSpan returns the heapBits for the span base address base. func heapBitsForSpan(base uintptr) (hbits heapBits) { if base < mheap_.arena_start || base >= mheap_.arena_used { + print("runtime: base ", hex(base), " not in range [", hex(mheap_.arena_start), ",", hex(mheap_.arena_used), ")\n") throw("heapBitsForSpan: base out of range") } return heapBitsForAddr(base) -- cgit v1.2.3-54-g00ecf From 6efa2f22ac45e9f12eccdc0eafe1799b9eb78dd3 Mon Sep 17 00:00:00 2001 From: Daniel Theophanes Date: Wed, 3 May 2017 08:57:05 -0700 Subject: [release-branch.go1.8] database/sql: ensure releaseConn is defined before a possible close Applies https://golang.org/cl/42139 to the go1.8 release branch. Also correct two minor issues detected with go vet. Fixes #20217 Change-Id: I2c41af9497493598fbcfc140439b4e25b9bb7e72 Reviewed-on: https://go-review.googlesource.com/42532 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Chris Broadfoot --- src/database/sql/sql.go | 2 +- src/database/sql/sql_test.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go index c016681fca..f8a884446e 100644 --- a/src/database/sql/sql.go +++ b/src/database/sql/sql.go @@ -1955,12 +1955,12 @@ func (s *Stmt) QueryContext(ctx context.Context, args ...interface{}) (*Rows, er rowsi: rowsi, // releaseConn set below } - rows.initContextClose(ctx) s.db.addDep(s, rows) rows.releaseConn = func(err error) { releaseConn(err) s.db.removeDep(s, rows) } + rows.initContextClose(ctx) return rows, nil } diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go index 450e5f1f8c..381aafc86b 100644 --- a/src/database/sql/sql_test.go +++ b/src/database/sql/sql_test.go @@ -322,7 +322,7 @@ func TestQueryContext(t *testing.T) { select { case <-ctx.Done(): if err := ctx.Err(); err != context.Canceled { - t.Fatalf("context err = %v; want context.Canceled") + t.Fatalf("context err = %v; want context.Canceled", ctx.Err()) } default: t.Fatalf("context err = nil; want context.Canceled") @@ -413,7 +413,8 @@ func TestTxContextWait(t *testing.T) { db := newTestDB(t, "people") defer closeDB(t, db) - ctx, _ := context.WithTimeout(context.Background(), time.Millisecond*15) + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*15) + defer cancel() tx, err := db.BeginTx(ctx, nil) if err != nil { -- cgit v1.2.3-54-g00ecf From 18a13d373a0554a28835c58d1ddfb69b387f41bf Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 11 May 2017 15:28:39 -0400 Subject: [release-branch.go1.8] runtime: doubly fix "double wakeup" panic Cherry-pick of CL 43311. runtime.gchelper depends on the non-atomic load of work.ndone happening strictly before the atomic add of work.nwait. Until very recently (commit 978af9c2db, fixing #20334), the compiler reordered these operations. This created a race since work.ndone can change as soon as work.nwait is equal to work.ndone. If that happened, more than one gchelper could attempt to wake up the work.alldone note, causing a "double wakeup" panic. This was fixed in the compiler, but to make this code less subtle, make the load of work.ndone atomic. This clearly forces the order of these operations, ensuring the race doesn't happen. Fixes #19305 (though really 978af9c2db fixed it). Change-Id: Ieb1a84e1e5044c33ac612c8a5ab6297e7db4c57d Reviewed-on: https://go-review.googlesource.com/43412 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/runtime/mgc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go index cd57720917..8f424926cb 100644 --- a/src/runtime/mgc.go +++ b/src/runtime/mgc.go @@ -1918,7 +1918,7 @@ func gchelper() { traceGCScanDone() } - nproc := work.nproc // work.nproc can change right after we increment work.ndone + nproc := atomic.Load(&work.nproc) // work.nproc can change right after we increment work.ndone if atomic.Xadd(&work.ndone, +1) == nproc-1 { notewakeup(&work.alldone) } -- cgit v1.2.3-54-g00ecf From 1054085dcf88ce802e6aa45078f9d7f3abf5b85d Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 11 May 2017 14:46:49 -0700 Subject: [release-branch.go1.8] cmd/compile: fix store chain in schedule pass Cherry-pick of CL 43294. Tuple ops are weird. They are essentially a pair of ops, one which consumes a mem and one which generates a mem (the Select1). The schedule pass didn't handle these quite right. Fix the scheduler to include both parts of the paired op in the store chain. That makes sure that loads are correctly ordered with respect to the first of the pair. Add a check for the ssacheck builder, that there is only one live store at a time. I thought we already had such a check, but apparently not... Fixes #20335 Change-Id: I59eb3446a329100af38d22820b1ca2190ca46a78 Reviewed-on: https://go-review.googlesource.com/43411 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/compile/internal/ssa/check.go | 33 ++++++++++++++++++++++++++++++++ src/cmd/compile/internal/ssa/schedule.go | 31 +++++++++++++++--------------- test/fixedbugs/issue20335.go | 19 ++++++++++++++++++ 3 files changed, 68 insertions(+), 15 deletions(-) create mode 100644 test/fixedbugs/issue20335.go diff --git a/src/cmd/compile/internal/ssa/check.go b/src/cmd/compile/internal/ssa/check.go index d78e915091..d6d39aee76 100644 --- a/src/cmd/compile/internal/ssa/check.go +++ b/src/cmd/compile/internal/ssa/check.go @@ -294,6 +294,39 @@ func checkFunc(f *Func) { } } } + + // Check that if a tuple has a memory type, it is second. + for _, b := range f.Blocks { + for _, v := range b.Values { + if v.Type.IsTuple() && v.Type.FieldType(0).IsMemory() { + f.Fatalf("memory is first in a tuple: %s\n", v.LongString()) + } + } + } + + // Check that only one memory is live at any point. + // TODO: make this check examine interblock. + if f.scheduled { + for _, b := range f.Blocks { + var mem *Value // the live memory + for _, v := range b.Values { + if v.Op != OpPhi { + for _, a := range v.Args { + if a.Type.IsMemory() || a.Type.IsTuple() && a.Type.FieldType(1).IsMemory() { + if mem == nil { + mem = a + } else if mem != a { + f.Fatalf("two live mems @ %s: %s and %s", v, mem, a) + } + } + } + } + if v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() { + mem = v + } + } + } + } } // domCheck reports whether x dominates y (including x==y). diff --git a/src/cmd/compile/internal/ssa/schedule.go b/src/cmd/compile/internal/ssa/schedule.go index a455a9a399..78b61f0959 100644 --- a/src/cmd/compile/internal/ssa/schedule.go +++ b/src/cmd/compile/internal/ssa/schedule.go @@ -148,19 +148,20 @@ func schedule(f *Func) { } } + // TODO: make this logic permanent in types.IsMemory? + isMem := func(v *Value) bool { + return v.Type.IsMemory() || v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() + } + for _, b := range f.Blocks { // Find store chain for block. // Store chains for different blocks overwrite each other, so // the calculated store chain is good only for this block. for _, v := range b.Values { - if v.Op != OpPhi && v.Type.IsMemory() { - mem := v - if v.Op == OpSelect1 { - v = v.Args[0] - } + if v.Op != OpPhi && isMem(v) { for _, w := range v.Args { - if w.Type.IsMemory() { - nextMem[w.ID] = mem + if isMem(w) { + nextMem[w.ID] = v } } } @@ -179,15 +180,15 @@ func schedule(f *Func) { uses[w.ID]++ } // Any load must come before the following store. - if v.Type.IsMemory() || !w.Type.IsMemory() { - continue // not a load - } - s := nextMem[w.ID] - if s == nil || s.Block != b { - continue + if !isMem(v) && isMem(w) { + // v is a load. + s := nextMem[w.ID] + if s == nil || s.Block != b { + continue + } + additionalArgs[s.ID] = append(additionalArgs[s.ID], v) + uses[v.ID]++ } - additionalArgs[s.ID] = append(additionalArgs[s.ID], v) - uses[v.ID]++ } } diff --git a/test/fixedbugs/issue20335.go b/test/fixedbugs/issue20335.go new file mode 100644 index 0000000000..185c2f06ea --- /dev/null +++ b/test/fixedbugs/issue20335.go @@ -0,0 +1,19 @@ +// compile + +// Copyright 2017 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. + +// Issue 20335: don't reorder loads with stores. +// This test should fail on the ssacheck builder +// without the fix in the CL that added this file. +// TODO: check the generated assembly? + +package a + +import "sync/atomic" + +func f(p, q *int32) bool { + x := *q + return atomic.AddInt32(p, 1) == x +} -- cgit v1.2.3-54-g00ecf From a43c0d2dc83bc4f5baa0a91be28078fa892e5111 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Mon, 22 May 2017 15:53:49 -0400 Subject: [release-branch.go1.8] runtime: don't corrupt arena bounds on low mmap Cherry-pick of CL 43870. If mheap.sysAlloc doesn't have room in the heap arena for an allocation, it will attempt to map more address space with sysReserve. sysReserve is given a hint, but can return any unused address range. Currently, mheap.sysAlloc incorrectly assumes the returned region will never fall between arena_start and arena_used. If it does, mheap.sysAlloc will blindly accept the new region as the new arena_used and arena_end, causing these to decrease and make it so any Go heap above the new arena_used is no longer considered part of the Go heap. This assumption *used to be* safe because we had all memory between arena_start and arena_used mapped, but when we switched to an arena_start of 0 on 32-bit, it became no longer safe. Most likely, we've only recently seen this bug occur because we usually start arena_used just above the binary, which is low in the address space. Hence, the kernel is very unlikely to give us a region before arena_used. Since mheap.sysAlloc is a linear allocator, there's not much we can do to handle this well. Hence, we fix this problem by simply rejecting the new region if it isn't after arena_end. In this case, we'll take the fall-back path and mmap a small region at any address just for the requested memory. Fixes #20259. Change-Id: Ib72e8cd621545002d595c7cade1e817cfe3e5b1e Reviewed-on: https://go-review.googlesource.com/43954 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Chris Broadfoot --- src/runtime/malloc.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index da39dac510..6f07731a49 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -400,10 +400,12 @@ func (h *mheap) sysAlloc(n uintptr) unsafe.Pointer { if p == 0 { return nil } + // p can be just about anywhere in the address + // space, including before arena_end. if p == h.arena_end { h.arena_end = new_end h.arena_reserved = reserved - } else if h.arena_start <= p && p+p_size-h.arena_start-1 <= _MaxArena32 { + } else if h.arena_end < p && p+p_size-h.arena_start-1 <= _MaxArena32 { // Keep everything page-aligned. // Our pages are bigger than hardware pages. h.arena_end = p + p_size @@ -413,6 +415,16 @@ func (h *mheap) sysAlloc(n uintptr) unsafe.Pointer { h.arena_used = used h.arena_reserved = reserved } else { + // We got a mapping, but it's not + // linear with our current arena, so + // we can't use it. + // + // TODO: Make it possible to allocate + // from this. We can't decrease + // arena_used, but we could introduce + // a new variable for the current + // allocation position. + // We haven't added this allocation to // the stats, so subtract it from a // fake stat (but avoid underflow). -- cgit v1.2.3-54-g00ecf From 243dee1737c82340064d166abd589dae5f4f0b38 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 3 May 2017 17:50:19 +0000 Subject: [release-branch.go1.8] cmd/go: if we get a C compiler dwarf2 warning, try without -g Backport of CL 38072 Fixes #14705 Reviewed-on: https://go-review.googlesource.com/42500 Run-TryBot: Brad Fitzpatrick Reviewed-by: Ian Lance Taylor Change-Id: Ia6ce2a41434aef2f8745a6a862ea66608b1e25f7 Reviewed-on: https://go-review.googlesource.com/43995 Reviewed-by: Brad Fitzpatrick --- src/cmd/go/build.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go index 98a650918a..cad578daed 100644 --- a/src/cmd/go/build.go +++ b/src/cmd/go/build.go @@ -3073,6 +3073,26 @@ func (b *builder) ccompile(p *Package, outfile string, flags []string, file stri desc := p.ImportPath output, err := b.runOut(p.Dir, desc, nil, compiler, flags, "-o", outfile, "-c", file) if len(output) > 0 { + // On FreeBSD 11, when we pass -g to clang 3.8 it + // invokes its internal assembler with -dwarf-version=2. + // When it sees .section .note.GNU-stack, it warns + // "DWARF2 only supports one section per compilation unit". + // This warning makes no sense, since the section is empty, + // but it confuses people. + // We work around the problem by detecting the warning + // and dropping -g and trying again. + if bytes.Contains(output, []byte("DWARF2 only supports one section per compilation unit")) { + newFlags := make([]string, 0, len(flags)) + for _, f := range flags { + if !strings.HasPrefix(f, "-g") { + newFlags = append(newFlags, f) + } + } + if len(newFlags) < len(flags) { + return b.ccompile(p, outfile, newFlags, file, compiler) + } + } + b.showOutput(p.Dir, desc, b.processOutput(output)) if err != nil { err = errPrintedOutput -- cgit v1.2.3-54-g00ecf From 51f508bb4aab97e7d0401e78804916453dd77e4c Mon Sep 17 00:00:00 2001 From: Michael Munday Date: Mon, 17 Apr 2017 12:29:32 -0400 Subject: [release-branch.go1.8] cmd/compile: fix s390x unsigned comparison constant merging rules On s390x unsigned integer comparisons with immediates require the immediate to be an unsigned 32-bit integer. The rule was checking that the immediate was a signed 32-bit integer. This CL also adds a test for comparisons that could be turned into compare with immediate or equivalent instructions (depending on architecture and optimizations applied). Cherry-pick of CL 40433 and CL 40873. Fixes #19940. Reviewed-on: https://go-review.googlesource.com/40931 Reviewed-by: Brad Fitzpatrick Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Change-Id: I3daaeaa40d7637bd4421e6b8d37ea4ffd74448ce Reviewed-on: https://go-review.googlesource.com/43994 Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/gc/ssa_test.go | 3 + src/cmd/compile/internal/gc/testdata/cmpConst.go | 2217 ++++++++++++++++++++ .../internal/gc/testdata/gen/cmpConstGen.go | 248 +++ src/cmd/compile/internal/ssa/gen/S390X.rules | 4 +- src/cmd/compile/internal/ssa/rewriteS390X.go | 8 +- 5 files changed, 2474 insertions(+), 6 deletions(-) create mode 100644 src/cmd/compile/internal/gc/testdata/cmpConst.go create mode 100644 src/cmd/compile/internal/gc/testdata/gen/cmpConstGen.go diff --git a/src/cmd/compile/internal/gc/ssa_test.go b/src/cmd/compile/internal/gc/ssa_test.go index 1aebd90311..bb315b97e8 100644 --- a/src/cmd/compile/internal/gc/ssa_test.go +++ b/src/cmd/compile/internal/gc/ssa_test.go @@ -63,6 +63,9 @@ func TestArithmeticConst(t *testing.T) { runTest(t, "arithConst.go") } func TestChan(t *testing.T) { runTest(t, "chan.go") } +// TestComparisonsConst tests results for comparison operations against constants. +func TestComparisonsConst(t *testing.T) { runTest(t, "cmpConst.go") } + func TestCompound(t *testing.T) { runTest(t, "compound.go") } func TestCtl(t *testing.T) { runTest(t, "ctl.go") } diff --git a/src/cmd/compile/internal/gc/testdata/cmpConst.go b/src/cmd/compile/internal/gc/testdata/cmpConst.go new file mode 100644 index 0000000000..f7067bea2a --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/cmpConst.go @@ -0,0 +1,2217 @@ +// run +// Code generated by gen/cmpConstGen.go. DO NOT EDIT. + +package main + +import ( + "fmt" + "reflect" + "runtime" +) + +// results show the expected result for the elements left of, equal to and right of the index. +type result struct{ l, e, r bool } + +var ( + eq = result{l: false, e: true, r: false} + ne = result{l: true, e: false, r: true} + lt = result{l: true, e: false, r: false} + le = result{l: true, e: true, r: false} + gt = result{l: false, e: false, r: true} + ge = result{l: false, e: true, r: true} +) + +// uint64 tests +var uint64_vals = []uint64{ + 0, + 1, + 126, + 127, + 128, + 254, + 255, + 256, + 32766, + 32767, + 32768, + 65534, + 65535, + 65536, + 2147483646, + 2147483647, + 2147483648, + 4278190080, + 4294967294, + 4294967295, + 4294967296, + 1095216660480, + 9223372036854775806, + 9223372036854775807, + 9223372036854775808, + 18374686479671623680, + 18446744073709551614, + 18446744073709551615, +} + +func lt_0_uint64(x uint64) bool { return x < 0 } +func le_0_uint64(x uint64) bool { return x <= 0 } +func gt_0_uint64(x uint64) bool { return x > 0 } +func ge_0_uint64(x uint64) bool { return x >= 0 } +func eq_0_uint64(x uint64) bool { return x == 0 } +func ne_0_uint64(x uint64) bool { return x != 0 } +func lt_1_uint64(x uint64) bool { return x < 1 } +func le_1_uint64(x uint64) bool { return x <= 1 } +func gt_1_uint64(x uint64) bool { return x > 1 } +func ge_1_uint64(x uint64) bool { return x >= 1 } +func eq_1_uint64(x uint64) bool { return x == 1 } +func ne_1_uint64(x uint64) bool { return x != 1 } +func lt_126_uint64(x uint64) bool { return x < 126 } +func le_126_uint64(x uint64) bool { return x <= 126 } +func gt_126_uint64(x uint64) bool { return x > 126 } +func ge_126_uint64(x uint64) bool { return x >= 126 } +func eq_126_uint64(x uint64) bool { return x == 126 } +func ne_126_uint64(x uint64) bool { return x != 126 } +func lt_127_uint64(x uint64) bool { return x < 127 } +func le_127_uint64(x uint64) bool { return x <= 127 } +func gt_127_uint64(x uint64) bool { return x > 127 } +func ge_127_uint64(x uint64) bool { return x >= 127 } +func eq_127_uint64(x uint64) bool { return x == 127 } +func ne_127_uint64(x uint64) bool { return x != 127 } +func lt_128_uint64(x uint64) bool { return x < 128 } +func le_128_uint64(x uint64) bool { return x <= 128 } +func gt_128_uint64(x uint64) bool { return x > 128 } +func ge_128_uint64(x uint64) bool { return x >= 128 } +func eq_128_uint64(x uint64) bool { return x == 128 } +func ne_128_uint64(x uint64) bool { return x != 128 } +func lt_254_uint64(x uint64) bool { return x < 254 } +func le_254_uint64(x uint64) bool { return x <= 254 } +func gt_254_uint64(x uint64) bool { return x > 254 } +func ge_254_uint64(x uint64) bool { return x >= 254 } +func eq_254_uint64(x uint64) bool { return x == 254 } +func ne_254_uint64(x uint64) bool { return x != 254 } +func lt_255_uint64(x uint64) bool { return x < 255 } +func le_255_uint64(x uint64) bool { return x <= 255 } +func gt_255_uint64(x uint64) bool { return x > 255 } +func ge_255_uint64(x uint64) bool { return x >= 255 } +func eq_255_uint64(x uint64) bool { return x == 255 } +func ne_255_uint64(x uint64) bool { return x != 255 } +func lt_256_uint64(x uint64) bool { return x < 256 } +func le_256_uint64(x uint64) bool { return x <= 256 } +func gt_256_uint64(x uint64) bool { return x > 256 } +func ge_256_uint64(x uint64) bool { return x >= 256 } +func eq_256_uint64(x uint64) bool { return x == 256 } +func ne_256_uint64(x uint64) bool { return x != 256 } +func lt_32766_uint64(x uint64) bool { return x < 32766 } +func le_32766_uint64(x uint64) bool { return x <= 32766 } +func gt_32766_uint64(x uint64) bool { return x > 32766 } +func ge_32766_uint64(x uint64) bool { return x >= 32766 } +func eq_32766_uint64(x uint64) bool { return x == 32766 } +func ne_32766_uint64(x uint64) bool { return x != 32766 } +func lt_32767_uint64(x uint64) bool { return x < 32767 } +func le_32767_uint64(x uint64) bool { return x <= 32767 } +func gt_32767_uint64(x uint64) bool { return x > 32767 } +func ge_32767_uint64(x uint64) bool { return x >= 32767 } +func eq_32767_uint64(x uint64) bool { return x == 32767 } +func ne_32767_uint64(x uint64) bool { return x != 32767 } +func lt_32768_uint64(x uint64) bool { return x < 32768 } +func le_32768_uint64(x uint64) bool { return x <= 32768 } +func gt_32768_uint64(x uint64) bool { return x > 32768 } +func ge_32768_uint64(x uint64) bool { return x >= 32768 } +func eq_32768_uint64(x uint64) bool { return x == 32768 } +func ne_32768_uint64(x uint64) bool { return x != 32768 } +func lt_65534_uint64(x uint64) bool { return x < 65534 } +func le_65534_uint64(x uint64) bool { return x <= 65534 } +func gt_65534_uint64(x uint64) bool { return x > 65534 } +func ge_65534_uint64(x uint64) bool { return x >= 65534 } +func eq_65534_uint64(x uint64) bool { return x == 65534 } +func ne_65534_uint64(x uint64) bool { return x != 65534 } +func lt_65535_uint64(x uint64) bool { return x < 65535 } +func le_65535_uint64(x uint64) bool { return x <= 65535 } +func gt_65535_uint64(x uint64) bool { return x > 65535 } +func ge_65535_uint64(x uint64) bool { return x >= 65535 } +func eq_65535_uint64(x uint64) bool { return x == 65535 } +func ne_65535_uint64(x uint64) bool { return x != 65535 } +func lt_65536_uint64(x uint64) bool { return x < 65536 } +func le_65536_uint64(x uint64) bool { return x <= 65536 } +func gt_65536_uint64(x uint64) bool { return x > 65536 } +func ge_65536_uint64(x uint64) bool { return x >= 65536 } +func eq_65536_uint64(x uint64) bool { return x == 65536 } +func ne_65536_uint64(x uint64) bool { return x != 65536 } +func lt_2147483646_uint64(x uint64) bool { return x < 2147483646 } +func le_2147483646_uint64(x uint64) bool { return x <= 2147483646 } +func gt_2147483646_uint64(x uint64) bool { return x > 2147483646 } +func ge_2147483646_uint64(x uint64) bool { return x >= 2147483646 } +func eq_2147483646_uint64(x uint64) bool { return x == 2147483646 } +func ne_2147483646_uint64(x uint64) bool { return x != 2147483646 } +func lt_2147483647_uint64(x uint64) bool { return x < 2147483647 } +func le_2147483647_uint64(x uint64) bool { return x <= 2147483647 } +func gt_2147483647_uint64(x uint64) bool { return x > 2147483647 } +func ge_2147483647_uint64(x uint64) bool { return x >= 2147483647 } +func eq_2147483647_uint64(x uint64) bool { return x == 2147483647 } +func ne_2147483647_uint64(x uint64) bool { return x != 2147483647 } +func lt_2147483648_uint64(x uint64) bool { return x < 2147483648 } +func le_2147483648_uint64(x uint64) bool { return x <= 2147483648 } +func gt_2147483648_uint64(x uint64) bool { return x > 2147483648 } +func ge_2147483648_uint64(x uint64) bool { return x >= 2147483648 } +func eq_2147483648_uint64(x uint64) bool { return x == 2147483648 } +func ne_2147483648_uint64(x uint64) bool { return x != 2147483648 } +func lt_4278190080_uint64(x uint64) bool { return x < 4278190080 } +func le_4278190080_uint64(x uint64) bool { return x <= 4278190080 } +func gt_4278190080_uint64(x uint64) bool { return x > 4278190080 } +func ge_4278190080_uint64(x uint64) bool { return x >= 4278190080 } +func eq_4278190080_uint64(x uint64) bool { return x == 4278190080 } +func ne_4278190080_uint64(x uint64) bool { return x != 4278190080 } +func lt_4294967294_uint64(x uint64) bool { return x < 4294967294 } +func le_4294967294_uint64(x uint64) bool { return x <= 4294967294 } +func gt_4294967294_uint64(x uint64) bool { return x > 4294967294 } +func ge_4294967294_uint64(x uint64) bool { return x >= 4294967294 } +func eq_4294967294_uint64(x uint64) bool { return x == 4294967294 } +func ne_4294967294_uint64(x uint64) bool { return x != 4294967294 } +func lt_4294967295_uint64(x uint64) bool { return x < 4294967295 } +func le_4294967295_uint64(x uint64) bool { return x <= 4294967295 } +func gt_4294967295_uint64(x uint64) bool { return x > 4294967295 } +func ge_4294967295_uint64(x uint64) bool { return x >= 4294967295 } +func eq_4294967295_uint64(x uint64) bool { return x == 4294967295 } +func ne_4294967295_uint64(x uint64) bool { return x != 4294967295 } +func lt_4294967296_uint64(x uint64) bool { return x < 4294967296 } +func le_4294967296_uint64(x uint64) bool { return x <= 4294967296 } +func gt_4294967296_uint64(x uint64) bool { return x > 4294967296 } +func ge_4294967296_uint64(x uint64) bool { return x >= 4294967296 } +func eq_4294967296_uint64(x uint64) bool { return x == 4294967296 } +func ne_4294967296_uint64(x uint64) bool { return x != 4294967296 } +func lt_1095216660480_uint64(x uint64) bool { return x < 1095216660480 } +func le_1095216660480_uint64(x uint64) bool { return x <= 1095216660480 } +func gt_1095216660480_uint64(x uint64) bool { return x > 1095216660480 } +func ge_1095216660480_uint64(x uint64) bool { return x >= 1095216660480 } +func eq_1095216660480_uint64(x uint64) bool { return x == 1095216660480 } +func ne_1095216660480_uint64(x uint64) bool { return x != 1095216660480 } +func lt_9223372036854775806_uint64(x uint64) bool { return x < 9223372036854775806 } +func le_9223372036854775806_uint64(x uint64) bool { return x <= 9223372036854775806 } +func gt_9223372036854775806_uint64(x uint64) bool { return x > 9223372036854775806 } +func ge_9223372036854775806_uint64(x uint64) bool { return x >= 9223372036854775806 } +func eq_9223372036854775806_uint64(x uint64) bool { return x == 9223372036854775806 } +func ne_9223372036854775806_uint64(x uint64) bool { return x != 9223372036854775806 } +func lt_9223372036854775807_uint64(x uint64) bool { return x < 9223372036854775807 } +func le_9223372036854775807_uint64(x uint64) bool { return x <= 9223372036854775807 } +func gt_9223372036854775807_uint64(x uint64) bool { return x > 9223372036854775807 } +func ge_9223372036854775807_uint64(x uint64) bool { return x >= 9223372036854775807 } +func eq_9223372036854775807_uint64(x uint64) bool { return x == 9223372036854775807 } +func ne_9223372036854775807_uint64(x uint64) bool { return x != 9223372036854775807 } +func lt_9223372036854775808_uint64(x uint64) bool { return x < 9223372036854775808 } +func le_9223372036854775808_uint64(x uint64) bool { return x <= 9223372036854775808 } +func gt_9223372036854775808_uint64(x uint64) bool { return x > 9223372036854775808 } +func ge_9223372036854775808_uint64(x uint64) bool { return x >= 9223372036854775808 } +func eq_9223372036854775808_uint64(x uint64) bool { return x == 9223372036854775808 } +func ne_9223372036854775808_uint64(x uint64) bool { return x != 9223372036854775808 } +func lt_18374686479671623680_uint64(x uint64) bool { return x < 18374686479671623680 } +func le_18374686479671623680_uint64(x uint64) bool { return x <= 18374686479671623680 } +func gt_18374686479671623680_uint64(x uint64) bool { return x > 18374686479671623680 } +func ge_18374686479671623680_uint64(x uint64) bool { return x >= 18374686479671623680 } +func eq_18374686479671623680_uint64(x uint64) bool { return x == 18374686479671623680 } +func ne_18374686479671623680_uint64(x uint64) bool { return x != 18374686479671623680 } +func lt_18446744073709551614_uint64(x uint64) bool { return x < 18446744073709551614 } +func le_18446744073709551614_uint64(x uint64) bool { return x <= 18446744073709551614 } +func gt_18446744073709551614_uint64(x uint64) bool { return x > 18446744073709551614 } +func ge_18446744073709551614_uint64(x uint64) bool { return x >= 18446744073709551614 } +func eq_18446744073709551614_uint64(x uint64) bool { return x == 18446744073709551614 } +func ne_18446744073709551614_uint64(x uint64) bool { return x != 18446744073709551614 } +func lt_18446744073709551615_uint64(x uint64) bool { return x < 18446744073709551615 } +func le_18446744073709551615_uint64(x uint64) bool { return x <= 18446744073709551615 } +func gt_18446744073709551615_uint64(x uint64) bool { return x > 18446744073709551615 } +func ge_18446744073709551615_uint64(x uint64) bool { return x >= 18446744073709551615 } +func eq_18446744073709551615_uint64(x uint64) bool { return x == 18446744073709551615 } +func ne_18446744073709551615_uint64(x uint64) bool { return x != 18446744073709551615 } + +var uint64_tests = []struct { + idx int // index of the constant used + exp result // expected results + fn func(uint64) bool +}{ + {idx: 0, exp: lt, fn: lt_0_uint64}, + {idx: 0, exp: le, fn: le_0_uint64}, + {idx: 0, exp: gt, fn: gt_0_uint64}, + {idx: 0, exp: ge, fn: ge_0_uint64}, + {idx: 0, exp: eq, fn: eq_0_uint64}, + {idx: 0, exp: ne, fn: ne_0_uint64}, + {idx: 1, exp: lt, fn: lt_1_uint64}, + {idx: 1, exp: le, fn: le_1_uint64}, + {idx: 1, exp: gt, fn: gt_1_uint64}, + {idx: 1, exp: ge, fn: ge_1_uint64}, + {idx: 1, exp: eq, fn: eq_1_uint64}, + {idx: 1, exp: ne, fn: ne_1_uint64}, + {idx: 2, exp: lt, fn: lt_126_uint64}, + {idx: 2, exp: le, fn: le_126_uint64}, + {idx: 2, exp: gt, fn: gt_126_uint64}, + {idx: 2, exp: ge, fn: ge_126_uint64}, + {idx: 2, exp: eq, fn: eq_126_uint64}, + {idx: 2, exp: ne, fn: ne_126_uint64}, + {idx: 3, exp: lt, fn: lt_127_uint64}, + {idx: 3, exp: le, fn: le_127_uint64}, + {idx: 3, exp: gt, fn: gt_127_uint64}, + {idx: 3, exp: ge, fn: ge_127_uint64}, + {idx: 3, exp: eq, fn: eq_127_uint64}, + {idx: 3, exp: ne, fn: ne_127_uint64}, + {idx: 4, exp: lt, fn: lt_128_uint64}, + {idx: 4, exp: le, fn: le_128_uint64}, + {idx: 4, exp: gt, fn: gt_128_uint64}, + {idx: 4, exp: ge, fn: ge_128_uint64}, + {idx: 4, exp: eq, fn: eq_128_uint64}, + {idx: 4, exp: ne, fn: ne_128_uint64}, + {idx: 5, exp: lt, fn: lt_254_uint64}, + {idx: 5, exp: le, fn: le_254_uint64}, + {idx: 5, exp: gt, fn: gt_254_uint64}, + {idx: 5, exp: ge, fn: ge_254_uint64}, + {idx: 5, exp: eq, fn: eq_254_uint64}, + {idx: 5, exp: ne, fn: ne_254_uint64}, + {idx: 6, exp: lt, fn: lt_255_uint64}, + {idx: 6, exp: le, fn: le_255_uint64}, + {idx: 6, exp: gt, fn: gt_255_uint64}, + {idx: 6, exp: ge, fn: ge_255_uint64}, + {idx: 6, exp: eq, fn: eq_255_uint64}, + {idx: 6, exp: ne, fn: ne_255_uint64}, + {idx: 7, exp: lt, fn: lt_256_uint64}, + {idx: 7, exp: le, fn: le_256_uint64}, + {idx: 7, exp: gt, fn: gt_256_uint64}, + {idx: 7, exp: ge, fn: ge_256_uint64}, + {idx: 7, exp: eq, fn: eq_256_uint64}, + {idx: 7, exp: ne, fn: ne_256_uint64}, + {idx: 8, exp: lt, fn: lt_32766_uint64}, + {idx: 8, exp: le, fn: le_32766_uint64}, + {idx: 8, exp: gt, fn: gt_32766_uint64}, + {idx: 8, exp: ge, fn: ge_32766_uint64}, + {idx: 8, exp: eq, fn: eq_32766_uint64}, + {idx: 8, exp: ne, fn: ne_32766_uint64}, + {idx: 9, exp: lt, fn: lt_32767_uint64}, + {idx: 9, exp: le, fn: le_32767_uint64}, + {idx: 9, exp: gt, fn: gt_32767_uint64}, + {idx: 9, exp: ge, fn: ge_32767_uint64}, + {idx: 9, exp: eq, fn: eq_32767_uint64}, + {idx: 9, exp: ne, fn: ne_32767_uint64}, + {idx: 10, exp: lt, fn: lt_32768_uint64}, + {idx: 10, exp: le, fn: le_32768_uint64}, + {idx: 10, exp: gt, fn: gt_32768_uint64}, + {idx: 10, exp: ge, fn: ge_32768_uint64}, + {idx: 10, exp: eq, fn: eq_32768_uint64}, + {idx: 10, exp: ne, fn: ne_32768_uint64}, + {idx: 11, exp: lt, fn: lt_65534_uint64}, + {idx: 11, exp: le, fn: le_65534_uint64}, + {idx: 11, exp: gt, fn: gt_65534_uint64}, + {idx: 11, exp: ge, fn: ge_65534_uint64}, + {idx: 11, exp: eq, fn: eq_65534_uint64}, + {idx: 11, exp: ne, fn: ne_65534_uint64}, + {idx: 12, exp: lt, fn: lt_65535_uint64}, + {idx: 12, exp: le, fn: le_65535_uint64}, + {idx: 12, exp: gt, fn: gt_65535_uint64}, + {idx: 12, exp: ge, fn: ge_65535_uint64}, + {idx: 12, exp: eq, fn: eq_65535_uint64}, + {idx: 12, exp: ne, fn: ne_65535_uint64}, + {idx: 13, exp: lt, fn: lt_65536_uint64}, + {idx: 13, exp: le, fn: le_65536_uint64}, + {idx: 13, exp: gt, fn: gt_65536_uint64}, + {idx: 13, exp: ge, fn: ge_65536_uint64}, + {idx: 13, exp: eq, fn: eq_65536_uint64}, + {idx: 13, exp: ne, fn: ne_65536_uint64}, + {idx: 14, exp: lt, fn: lt_2147483646_uint64}, + {idx: 14, exp: le, fn: le_2147483646_uint64}, + {idx: 14, exp: gt, fn: gt_2147483646_uint64}, + {idx: 14, exp: ge, fn: ge_2147483646_uint64}, + {idx: 14, exp: eq, fn: eq_2147483646_uint64}, + {idx: 14, exp: ne, fn: ne_2147483646_uint64}, + {idx: 15, exp: lt, fn: lt_2147483647_uint64}, + {idx: 15, exp: le, fn: le_2147483647_uint64}, + {idx: 15, exp: gt, fn: gt_2147483647_uint64}, + {idx: 15, exp: ge, fn: ge_2147483647_uint64}, + {idx: 15, exp: eq, fn: eq_2147483647_uint64}, + {idx: 15, exp: ne, fn: ne_2147483647_uint64}, + {idx: 16, exp: lt, fn: lt_2147483648_uint64}, + {idx: 16, exp: le, fn: le_2147483648_uint64}, + {idx: 16, exp: gt, fn: gt_2147483648_uint64}, + {idx: 16, exp: ge, fn: ge_2147483648_uint64}, + {idx: 16, exp: eq, fn: eq_2147483648_uint64}, + {idx: 16, exp: ne, fn: ne_2147483648_uint64}, + {idx: 17, exp: lt, fn: lt_4278190080_uint64}, + {idx: 17, exp: le, fn: le_4278190080_uint64}, + {idx: 17, exp: gt, fn: gt_4278190080_uint64}, + {idx: 17, exp: ge, fn: ge_4278190080_uint64}, + {idx: 17, exp: eq, fn: eq_4278190080_uint64}, + {idx: 17, exp: ne, fn: ne_4278190080_uint64}, + {idx: 18, exp: lt, fn: lt_4294967294_uint64}, + {idx: 18, exp: le, fn: le_4294967294_uint64}, + {idx: 18, exp: gt, fn: gt_4294967294_uint64}, + {idx: 18, exp: ge, fn: ge_4294967294_uint64}, + {idx: 18, exp: eq, fn: eq_4294967294_uint64}, + {idx: 18, exp: ne, fn: ne_4294967294_uint64}, + {idx: 19, exp: lt, fn: lt_4294967295_uint64}, + {idx: 19, exp: le, fn: le_4294967295_uint64}, + {idx: 19, exp: gt, fn: gt_4294967295_uint64}, + {idx: 19, exp: ge, fn: ge_4294967295_uint64}, + {idx: 19, exp: eq, fn: eq_4294967295_uint64}, + {idx: 19, exp: ne, fn: ne_4294967295_uint64}, + {idx: 20, exp: lt, fn: lt_4294967296_uint64}, + {idx: 20, exp: le, fn: le_4294967296_uint64}, + {idx: 20, exp: gt, fn: gt_4294967296_uint64}, + {idx: 20, exp: ge, fn: ge_4294967296_uint64}, + {idx: 20, exp: eq, fn: eq_4294967296_uint64}, + {idx: 20, exp: ne, fn: ne_4294967296_uint64}, + {idx: 21, exp: lt, fn: lt_1095216660480_uint64}, + {idx: 21, exp: le, fn: le_1095216660480_uint64}, + {idx: 21, exp: gt, fn: gt_1095216660480_uint64}, + {idx: 21, exp: ge, fn: ge_1095216660480_uint64}, + {idx: 21, exp: eq, fn: eq_1095216660480_uint64}, + {idx: 21, exp: ne, fn: ne_1095216660480_uint64}, + {idx: 22, exp: lt, fn: lt_9223372036854775806_uint64}, + {idx: 22, exp: le, fn: le_9223372036854775806_uint64}, + {idx: 22, exp: gt, fn: gt_9223372036854775806_uint64}, + {idx: 22, exp: ge, fn: ge_9223372036854775806_uint64}, + {idx: 22, exp: eq, fn: eq_9223372036854775806_uint64}, + {idx: 22, exp: ne, fn: ne_9223372036854775806_uint64}, + {idx: 23, exp: lt, fn: lt_9223372036854775807_uint64}, + {idx: 23, exp: le, fn: le_9223372036854775807_uint64}, + {idx: 23, exp: gt, fn: gt_9223372036854775807_uint64}, + {idx: 23, exp: ge, fn: ge_9223372036854775807_uint64}, + {idx: 23, exp: eq, fn: eq_9223372036854775807_uint64}, + {idx: 23, exp: ne, fn: ne_9223372036854775807_uint64}, + {idx: 24, exp: lt, fn: lt_9223372036854775808_uint64}, + {idx: 24, exp: le, fn: le_9223372036854775808_uint64}, + {idx: 24, exp: gt, fn: gt_9223372036854775808_uint64}, + {idx: 24, exp: ge, fn: ge_9223372036854775808_uint64}, + {idx: 24, exp: eq, fn: eq_9223372036854775808_uint64}, + {idx: 24, exp: ne, fn: ne_9223372036854775808_uint64}, + {idx: 25, exp: lt, fn: lt_18374686479671623680_uint64}, + {idx: 25, exp: le, fn: le_18374686479671623680_uint64}, + {idx: 25, exp: gt, fn: gt_18374686479671623680_uint64}, + {idx: 25, exp: ge, fn: ge_18374686479671623680_uint64}, + {idx: 25, exp: eq, fn: eq_18374686479671623680_uint64}, + {idx: 25, exp: ne, fn: ne_18374686479671623680_uint64}, + {idx: 26, exp: lt, fn: lt_18446744073709551614_uint64}, + {idx: 26, exp: le, fn: le_18446744073709551614_uint64}, + {idx: 26, exp: gt, fn: gt_18446744073709551614_uint64}, + {idx: 26, exp: ge, fn: ge_18446744073709551614_uint64}, + {idx: 26, exp: eq, fn: eq_18446744073709551614_uint64}, + {idx: 26, exp: ne, fn: ne_18446744073709551614_uint64}, + {idx: 27, exp: lt, fn: lt_18446744073709551615_uint64}, + {idx: 27, exp: le, fn: le_18446744073709551615_uint64}, + {idx: 27, exp: gt, fn: gt_18446744073709551615_uint64}, + {idx: 27, exp: ge, fn: ge_18446744073709551615_uint64}, + {idx: 27, exp: eq, fn: eq_18446744073709551615_uint64}, + {idx: 27, exp: ne, fn: ne_18446744073709551615_uint64}, +} + +// uint32 tests +var uint32_vals = []uint32{ + 0, + 1, + 126, + 127, + 128, + 254, + 255, + 256, + 32766, + 32767, + 32768, + 65534, + 65535, + 65536, + 2147483646, + 2147483647, + 2147483648, + 4278190080, + 4294967294, + 4294967295, +} + +func lt_0_uint32(x uint32) bool { return x < 0 } +func le_0_uint32(x uint32) bool { return x <= 0 } +func gt_0_uint32(x uint32) bool { return x > 0 } +func ge_0_uint32(x uint32) bool { return x >= 0 } +func eq_0_uint32(x uint32) bool { return x == 0 } +func ne_0_uint32(x uint32) bool { return x != 0 } +func lt_1_uint32(x uint32) bool { return x < 1 } +func le_1_uint32(x uint32) bool { return x <= 1 } +func gt_1_uint32(x uint32) bool { return x > 1 } +func ge_1_uint32(x uint32) bool { return x >= 1 } +func eq_1_uint32(x uint32) bool { return x == 1 } +func ne_1_uint32(x uint32) bool { return x != 1 } +func lt_126_uint32(x uint32) bool { return x < 126 } +func le_126_uint32(x uint32) bool { return x <= 126 } +func gt_126_uint32(x uint32) bool { return x > 126 } +func ge_126_uint32(x uint32) bool { return x >= 126 } +func eq_126_uint32(x uint32) bool { return x == 126 } +func ne_126_uint32(x uint32) bool { return x != 126 } +func lt_127_uint32(x uint32) bool { return x < 127 } +func le_127_uint32(x uint32) bool { return x <= 127 } +func gt_127_uint32(x uint32) bool { return x > 127 } +func ge_127_uint32(x uint32) bool { return x >= 127 } +func eq_127_uint32(x uint32) bool { return x == 127 } +func ne_127_uint32(x uint32) bool { return x != 127 } +func lt_128_uint32(x uint32) bool { return x < 128 } +func le_128_uint32(x uint32) bool { return x <= 128 } +func gt_128_uint32(x uint32) bool { return x > 128 } +func ge_128_uint32(x uint32) bool { return x >= 128 } +func eq_128_uint32(x uint32) bool { return x == 128 } +func ne_128_uint32(x uint32) bool { return x != 128 } +func lt_254_uint32(x uint32) bool { return x < 254 } +func le_254_uint32(x uint32) bool { return x <= 254 } +func gt_254_uint32(x uint32) bool { return x > 254 } +func ge_254_uint32(x uint32) bool { return x >= 254 } +func eq_254_uint32(x uint32) bool { return x == 254 } +func ne_254_uint32(x uint32) bool { return x != 254 } +func lt_255_uint32(x uint32) bool { return x < 255 } +func le_255_uint32(x uint32) bool { return x <= 255 } +func gt_255_uint32(x uint32) bool { return x > 255 } +func ge_255_uint32(x uint32) bool { return x >= 255 } +func eq_255_uint32(x uint32) bool { return x == 255 } +func ne_255_uint32(x uint32) bool { return x != 255 } +func lt_256_uint32(x uint32) bool { return x < 256 } +func le_256_uint32(x uint32) bool { return x <= 256 } +func gt_256_uint32(x uint32) bool { return x > 256 } +func ge_256_uint32(x uint32) bool { return x >= 256 } +func eq_256_uint32(x uint32) bool { return x == 256 } +func ne_256_uint32(x uint32) bool { return x != 256 } +func lt_32766_uint32(x uint32) bool { return x < 32766 } +func le_32766_uint32(x uint32) bool { return x <= 32766 } +func gt_32766_uint32(x uint32) bool { return x > 32766 } +func ge_32766_uint32(x uint32) bool { return x >= 32766 } +func eq_32766_uint32(x uint32) bool { return x == 32766 } +func ne_32766_uint32(x uint32) bool { return x != 32766 } +func lt_32767_uint32(x uint32) bool { return x < 32767 } +func le_32767_uint32(x uint32) bool { return x <= 32767 } +func gt_32767_uint32(x uint32) bool { return x > 32767 } +func ge_32767_uint32(x uint32) bool { return x >= 32767 } +func eq_32767_uint32(x uint32) bool { return x == 32767 } +func ne_32767_uint32(x uint32) bool { return x != 32767 } +func lt_32768_uint32(x uint32) bool { return x < 32768 } +func le_32768_uint32(x uint32) bool { return x <= 32768 } +func gt_32768_uint32(x uint32) bool { return x > 32768 } +func ge_32768_uint32(x uint32) bool { return x >= 32768 } +func eq_32768_uint32(x uint32) bool { return x == 32768 } +func ne_32768_uint32(x uint32) bool { return x != 32768 } +func lt_65534_uint32(x uint32) bool { return x < 65534 } +func le_65534_uint32(x uint32) bool { return x <= 65534 } +func gt_65534_uint32(x uint32) bool { return x > 65534 } +func ge_65534_uint32(x uint32) bool { return x >= 65534 } +func eq_65534_uint32(x uint32) bool { return x == 65534 } +func ne_65534_uint32(x uint32) bool { return x != 65534 } +func lt_65535_uint32(x uint32) bool { return x < 65535 } +func le_65535_uint32(x uint32) bool { return x <= 65535 } +func gt_65535_uint32(x uint32) bool { return x > 65535 } +func ge_65535_uint32(x uint32) bool { return x >= 65535 } +func eq_65535_uint32(x uint32) bool { return x == 65535 } +func ne_65535_uint32(x uint32) bool { return x != 65535 } +func lt_65536_uint32(x uint32) bool { return x < 65536 } +func le_65536_uint32(x uint32) bool { return x <= 65536 } +func gt_65536_uint32(x uint32) bool { return x > 65536 } +func ge_65536_uint32(x uint32) bool { return x >= 65536 } +func eq_65536_uint32(x uint32) bool { return x == 65536 } +func ne_65536_uint32(x uint32) bool { return x != 65536 } +func lt_2147483646_uint32(x uint32) bool { return x < 2147483646 } +func le_2147483646_uint32(x uint32) bool { return x <= 2147483646 } +func gt_2147483646_uint32(x uint32) bool { return x > 2147483646 } +func ge_2147483646_uint32(x uint32) bool { return x >= 2147483646 } +func eq_2147483646_uint32(x uint32) bool { return x == 2147483646 } +func ne_2147483646_uint32(x uint32) bool { return x != 2147483646 } +func lt_2147483647_uint32(x uint32) bool { return x < 2147483647 } +func le_2147483647_uint32(x uint32) bool { return x <= 2147483647 } +func gt_2147483647_uint32(x uint32) bool { return x > 2147483647 } +func ge_2147483647_uint32(x uint32) bool { return x >= 2147483647 } +func eq_2147483647_uint32(x uint32) bool { return x == 2147483647 } +func ne_2147483647_uint32(x uint32) bool { return x != 2147483647 } +func lt_2147483648_uint32(x uint32) bool { return x < 2147483648 } +func le_2147483648_uint32(x uint32) bool { return x <= 2147483648 } +func gt_2147483648_uint32(x uint32) bool { return x > 2147483648 } +func ge_2147483648_uint32(x uint32) bool { return x >= 2147483648 } +func eq_2147483648_uint32(x uint32) bool { return x == 2147483648 } +func ne_2147483648_uint32(x uint32) bool { return x != 2147483648 } +func lt_4278190080_uint32(x uint32) bool { return x < 4278190080 } +func le_4278190080_uint32(x uint32) bool { return x <= 4278190080 } +func gt_4278190080_uint32(x uint32) bool { return x > 4278190080 } +func ge_4278190080_uint32(x uint32) bool { return x >= 4278190080 } +func eq_4278190080_uint32(x uint32) bool { return x == 4278190080 } +func ne_4278190080_uint32(x uint32) bool { return x != 4278190080 } +func lt_4294967294_uint32(x uint32) bool { return x < 4294967294 } +func le_4294967294_uint32(x uint32) bool { return x <= 4294967294 } +func gt_4294967294_uint32(x uint32) bool { return x > 4294967294 } +func ge_4294967294_uint32(x uint32) bool { return x >= 4294967294 } +func eq_4294967294_uint32(x uint32) bool { return x == 4294967294 } +func ne_4294967294_uint32(x uint32) bool { return x != 4294967294 } +func lt_4294967295_uint32(x uint32) bool { return x < 4294967295 } +func le_4294967295_uint32(x uint32) bool { return x <= 4294967295 } +func gt_4294967295_uint32(x uint32) bool { return x > 4294967295 } +func ge_4294967295_uint32(x uint32) bool { return x >= 4294967295 } +func eq_4294967295_uint32(x uint32) bool { return x == 4294967295 } +func ne_4294967295_uint32(x uint32) bool { return x != 4294967295 } + +var uint32_tests = []struct { + idx int // index of the constant used + exp result // expected results + fn func(uint32) bool +}{ + {idx: 0, exp: lt, fn: lt_0_uint32}, + {idx: 0, exp: le, fn: le_0_uint32}, + {idx: 0, exp: gt, fn: gt_0_uint32}, + {idx: 0, exp: ge, fn: ge_0_uint32}, + {idx: 0, exp: eq, fn: eq_0_uint32}, + {idx: 0, exp: ne, fn: ne_0_uint32}, + {idx: 1, exp: lt, fn: lt_1_uint32}, + {idx: 1, exp: le, fn: le_1_uint32}, + {idx: 1, exp: gt, fn: gt_1_uint32}, + {idx: 1, exp: ge, fn: ge_1_uint32}, + {idx: 1, exp: eq, fn: eq_1_uint32}, + {idx: 1, exp: ne, fn: ne_1_uint32}, + {idx: 2, exp: lt, fn: lt_126_uint32}, + {idx: 2, exp: le, fn: le_126_uint32}, + {idx: 2, exp: gt, fn: gt_126_uint32}, + {idx: 2, exp: ge, fn: ge_126_uint32}, + {idx: 2, exp: eq, fn: eq_126_uint32}, + {idx: 2, exp: ne, fn: ne_126_uint32}, + {idx: 3, exp: lt, fn: lt_127_uint32}, + {idx: 3, exp: le, fn: le_127_uint32}, + {idx: 3, exp: gt, fn: gt_127_uint32}, + {idx: 3, exp: ge, fn: ge_127_uint32}, + {idx: 3, exp: eq, fn: eq_127_uint32}, + {idx: 3, exp: ne, fn: ne_127_uint32}, + {idx: 4, exp: lt, fn: lt_128_uint32}, + {idx: 4, exp: le, fn: le_128_uint32}, + {idx: 4, exp: gt, fn: gt_128_uint32}, + {idx: 4, exp: ge, fn: ge_128_uint32}, + {idx: 4, exp: eq, fn: eq_128_uint32}, + {idx: 4, exp: ne, fn: ne_128_uint32}, + {idx: 5, exp: lt, fn: lt_254_uint32}, + {idx: 5, exp: le, fn: le_254_uint32}, + {idx: 5, exp: gt, fn: gt_254_uint32}, + {idx: 5, exp: ge, fn: ge_254_uint32}, + {idx: 5, exp: eq, fn: eq_254_uint32}, + {idx: 5, exp: ne, fn: ne_254_uint32}, + {idx: 6, exp: lt, fn: lt_255_uint32}, + {idx: 6, exp: le, fn: le_255_uint32}, + {idx: 6, exp: gt, fn: gt_255_uint32}, + {idx: 6, exp: ge, fn: ge_255_uint32}, + {idx: 6, exp: eq, fn: eq_255_uint32}, + {idx: 6, exp: ne, fn: ne_255_uint32}, + {idx: 7, exp: lt, fn: lt_256_uint32}, + {idx: 7, exp: le, fn: le_256_uint32}, + {idx: 7, exp: gt, fn: gt_256_uint32}, + {idx: 7, exp: ge, fn: ge_256_uint32}, + {idx: 7, exp: eq, fn: eq_256_uint32}, + {idx: 7, exp: ne, fn: ne_256_uint32}, + {idx: 8, exp: lt, fn: lt_32766_uint32}, + {idx: 8, exp: le, fn: le_32766_uint32}, + {idx: 8, exp: gt, fn: gt_32766_uint32}, + {idx: 8, exp: ge, fn: ge_32766_uint32}, + {idx: 8, exp: eq, fn: eq_32766_uint32}, + {idx: 8, exp: ne, fn: ne_32766_uint32}, + {idx: 9, exp: lt, fn: lt_32767_uint32}, + {idx: 9, exp: le, fn: le_32767_uint32}, + {idx: 9, exp: gt, fn: gt_32767_uint32}, + {idx: 9, exp: ge, fn: ge_32767_uint32}, + {idx: 9, exp: eq, fn: eq_32767_uint32}, + {idx: 9, exp: ne, fn: ne_32767_uint32}, + {idx: 10, exp: lt, fn: lt_32768_uint32}, + {idx: 10, exp: le, fn: le_32768_uint32}, + {idx: 10, exp: gt, fn: gt_32768_uint32}, + {idx: 10, exp: ge, fn: ge_32768_uint32}, + {idx: 10, exp: eq, fn: eq_32768_uint32}, + {idx: 10, exp: ne, fn: ne_32768_uint32}, + {idx: 11, exp: lt, fn: lt_65534_uint32}, + {idx: 11, exp: le, fn: le_65534_uint32}, + {idx: 11, exp: gt, fn: gt_65534_uint32}, + {idx: 11, exp: ge, fn: ge_65534_uint32}, + {idx: 11, exp: eq, fn: eq_65534_uint32}, + {idx: 11, exp: ne, fn: ne_65534_uint32}, + {idx: 12, exp: lt, fn: lt_65535_uint32}, + {idx: 12, exp: le, fn: le_65535_uint32}, + {idx: 12, exp: gt, fn: gt_65535_uint32}, + {idx: 12, exp: ge, fn: ge_65535_uint32}, + {idx: 12, exp: eq, fn: eq_65535_uint32}, + {idx: 12, exp: ne, fn: ne_65535_uint32}, + {idx: 13, exp: lt, fn: lt_65536_uint32}, + {idx: 13, exp: le, fn: le_65536_uint32}, + {idx: 13, exp: gt, fn: gt_65536_uint32}, + {idx: 13, exp: ge, fn: ge_65536_uint32}, + {idx: 13, exp: eq, fn: eq_65536_uint32}, + {idx: 13, exp: ne, fn: ne_65536_uint32}, + {idx: 14, exp: lt, fn: lt_2147483646_uint32}, + {idx: 14, exp: le, fn: le_2147483646_uint32}, + {idx: 14, exp: gt, fn: gt_2147483646_uint32}, + {idx: 14, exp: ge, fn: ge_2147483646_uint32}, + {idx: 14, exp: eq, fn: eq_2147483646_uint32}, + {idx: 14, exp: ne, fn: ne_2147483646_uint32}, + {idx: 15, exp: lt, fn: lt_2147483647_uint32}, + {idx: 15, exp: le, fn: le_2147483647_uint32}, + {idx: 15, exp: gt, fn: gt_2147483647_uint32}, + {idx: 15, exp: ge, fn: ge_2147483647_uint32}, + {idx: 15, exp: eq, fn: eq_2147483647_uint32}, + {idx: 15, exp: ne, fn: ne_2147483647_uint32}, + {idx: 16, exp: lt, fn: lt_2147483648_uint32}, + {idx: 16, exp: le, fn: le_2147483648_uint32}, + {idx: 16, exp: gt, fn: gt_2147483648_uint32}, + {idx: 16, exp: ge, fn: ge_2147483648_uint32}, + {idx: 16, exp: eq, fn: eq_2147483648_uint32}, + {idx: 16, exp: ne, fn: ne_2147483648_uint32}, + {idx: 17, exp: lt, fn: lt_4278190080_uint32}, + {idx: 17, exp: le, fn: le_4278190080_uint32}, + {idx: 17, exp: gt, fn: gt_4278190080_uint32}, + {idx: 17, exp: ge, fn: ge_4278190080_uint32}, + {idx: 17, exp: eq, fn: eq_4278190080_uint32}, + {idx: 17, exp: ne, fn: ne_4278190080_uint32}, + {idx: 18, exp: lt, fn: lt_4294967294_uint32}, + {idx: 18, exp: le, fn: le_4294967294_uint32}, + {idx: 18, exp: gt, fn: gt_4294967294_uint32}, + {idx: 18, exp: ge, fn: ge_4294967294_uint32}, + {idx: 18, exp: eq, fn: eq_4294967294_uint32}, + {idx: 18, exp: ne, fn: ne_4294967294_uint32}, + {idx: 19, exp: lt, fn: lt_4294967295_uint32}, + {idx: 19, exp: le, fn: le_4294967295_uint32}, + {idx: 19, exp: gt, fn: gt_4294967295_uint32}, + {idx: 19, exp: ge, fn: ge_4294967295_uint32}, + {idx: 19, exp: eq, fn: eq_4294967295_uint32}, + {idx: 19, exp: ne, fn: ne_4294967295_uint32}, +} + +// uint16 tests +var uint16_vals = []uint16{ + 0, + 1, + 126, + 127, + 128, + 254, + 255, + 256, + 32766, + 32767, + 32768, + 65534, + 65535, +} + +func lt_0_uint16(x uint16) bool { return x < 0 } +func le_0_uint16(x uint16) bool { return x <= 0 } +func gt_0_uint16(x uint16) bool { return x > 0 } +func ge_0_uint16(x uint16) bool { return x >= 0 } +func eq_0_uint16(x uint16) bool { return x == 0 } +func ne_0_uint16(x uint16) bool { return x != 0 } +func lt_1_uint16(x uint16) bool { return x < 1 } +func le_1_uint16(x uint16) bool { return x <= 1 } +func gt_1_uint16(x uint16) bool { return x > 1 } +func ge_1_uint16(x uint16) bool { return x >= 1 } +func eq_1_uint16(x uint16) bool { return x == 1 } +func ne_1_uint16(x uint16) bool { return x != 1 } +func lt_126_uint16(x uint16) bool { return x < 126 } +func le_126_uint16(x uint16) bool { return x <= 126 } +func gt_126_uint16(x uint16) bool { return x > 126 } +func ge_126_uint16(x uint16) bool { return x >= 126 } +func eq_126_uint16(x uint16) bool { return x == 126 } +func ne_126_uint16(x uint16) bool { return x != 126 } +func lt_127_uint16(x uint16) bool { return x < 127 } +func le_127_uint16(x uint16) bool { return x <= 127 } +func gt_127_uint16(x uint16) bool { return x > 127 } +func ge_127_uint16(x uint16) bool { return x >= 127 } +func eq_127_uint16(x uint16) bool { return x == 127 } +func ne_127_uint16(x uint16) bool { return x != 127 } +func lt_128_uint16(x uint16) bool { return x < 128 } +func le_128_uint16(x uint16) bool { return x <= 128 } +func gt_128_uint16(x uint16) bool { return x > 128 } +func ge_128_uint16(x uint16) bool { return x >= 128 } +func eq_128_uint16(x uint16) bool { return x == 128 } +func ne_128_uint16(x uint16) bool { return x != 128 } +func lt_254_uint16(x uint16) bool { return x < 254 } +func le_254_uint16(x uint16) bool { return x <= 254 } +func gt_254_uint16(x uint16) bool { return x > 254 } +func ge_254_uint16(x uint16) bool { return x >= 254 } +func eq_254_uint16(x uint16) bool { return x == 254 } +func ne_254_uint16(x uint16) bool { return x != 254 } +func lt_255_uint16(x uint16) bool { return x < 255 } +func le_255_uint16(x uint16) bool { return x <= 255 } +func gt_255_uint16(x uint16) bool { return x > 255 } +func ge_255_uint16(x uint16) bool { return x >= 255 } +func eq_255_uint16(x uint16) bool { return x == 255 } +func ne_255_uint16(x uint16) bool { return x != 255 } +func lt_256_uint16(x uint16) bool { return x < 256 } +func le_256_uint16(x uint16) bool { return x <= 256 } +func gt_256_uint16(x uint16) bool { return x > 256 } +func ge_256_uint16(x uint16) bool { return x >= 256 } +func eq_256_uint16(x uint16) bool { return x == 256 } +func ne_256_uint16(x uint16) bool { return x != 256 } +func lt_32766_uint16(x uint16) bool { return x < 32766 } +func le_32766_uint16(x uint16) bool { return x <= 32766 } +func gt_32766_uint16(x uint16) bool { return x > 32766 } +func ge_32766_uint16(x uint16) bool { return x >= 32766 } +func eq_32766_uint16(x uint16) bool { return x == 32766 } +func ne_32766_uint16(x uint16) bool { return x != 32766 } +func lt_32767_uint16(x uint16) bool { return x < 32767 } +func le_32767_uint16(x uint16) bool { return x <= 32767 } +func gt_32767_uint16(x uint16) bool { return x > 32767 } +func ge_32767_uint16(x uint16) bool { return x >= 32767 } +func eq_32767_uint16(x uint16) bool { return x == 32767 } +func ne_32767_uint16(x uint16) bool { return x != 32767 } +func lt_32768_uint16(x uint16) bool { return x < 32768 } +func le_32768_uint16(x uint16) bool { return x <= 32768 } +func gt_32768_uint16(x uint16) bool { return x > 32768 } +func ge_32768_uint16(x uint16) bool { return x >= 32768 } +func eq_32768_uint16(x uint16) bool { return x == 32768 } +func ne_32768_uint16(x uint16) bool { return x != 32768 } +func lt_65534_uint16(x uint16) bool { return x < 65534 } +func le_65534_uint16(x uint16) bool { return x <= 65534 } +func gt_65534_uint16(x uint16) bool { return x > 65534 } +func ge_65534_uint16(x uint16) bool { return x >= 65534 } +func eq_65534_uint16(x uint16) bool { return x == 65534 } +func ne_65534_uint16(x uint16) bool { return x != 65534 } +func lt_65535_uint16(x uint16) bool { return x < 65535 } +func le_65535_uint16(x uint16) bool { return x <= 65535 } +func gt_65535_uint16(x uint16) bool { return x > 65535 } +func ge_65535_uint16(x uint16) bool { return x >= 65535 } +func eq_65535_uint16(x uint16) bool { return x == 65535 } +func ne_65535_uint16(x uint16) bool { return x != 65535 } + +var uint16_tests = []struct { + idx int // index of the constant used + exp result // expected results + fn func(uint16) bool +}{ + {idx: 0, exp: lt, fn: lt_0_uint16}, + {idx: 0, exp: le, fn: le_0_uint16}, + {idx: 0, exp: gt, fn: gt_0_uint16}, + {idx: 0, exp: ge, fn: ge_0_uint16}, + {idx: 0, exp: eq, fn: eq_0_uint16}, + {idx: 0, exp: ne, fn: ne_0_uint16}, + {idx: 1, exp: lt, fn: lt_1_uint16}, + {idx: 1, exp: le, fn: le_1_uint16}, + {idx: 1, exp: gt, fn: gt_1_uint16}, + {idx: 1, exp: ge, fn: ge_1_uint16}, + {idx: 1, exp: eq, fn: eq_1_uint16}, + {idx: 1, exp: ne, fn: ne_1_uint16}, + {idx: 2, exp: lt, fn: lt_126_uint16}, + {idx: 2, exp: le, fn: le_126_uint16}, + {idx: 2, exp: gt, fn: gt_126_uint16}, + {idx: 2, exp: ge, fn: ge_126_uint16}, + {idx: 2, exp: eq, fn: eq_126_uint16}, + {idx: 2, exp: ne, fn: ne_126_uint16}, + {idx: 3, exp: lt, fn: lt_127_uint16}, + {idx: 3, exp: le, fn: le_127_uint16}, + {idx: 3, exp: gt, fn: gt_127_uint16}, + {idx: 3, exp: ge, fn: ge_127_uint16}, + {idx: 3, exp: eq, fn: eq_127_uint16}, + {idx: 3, exp: ne, fn: ne_127_uint16}, + {idx: 4, exp: lt, fn: lt_128_uint16}, + {idx: 4, exp: le, fn: le_128_uint16}, + {idx: 4, exp: gt, fn: gt_128_uint16}, + {idx: 4, exp: ge, fn: ge_128_uint16}, + {idx: 4, exp: eq, fn: eq_128_uint16}, + {idx: 4, exp: ne, fn: ne_128_uint16}, + {idx: 5, exp: lt, fn: lt_254_uint16}, + {idx: 5, exp: le, fn: le_254_uint16}, + {idx: 5, exp: gt, fn: gt_254_uint16}, + {idx: 5, exp: ge, fn: ge_254_uint16}, + {idx: 5, exp: eq, fn: eq_254_uint16}, + {idx: 5, exp: ne, fn: ne_254_uint16}, + {idx: 6, exp: lt, fn: lt_255_uint16}, + {idx: 6, exp: le, fn: le_255_uint16}, + {idx: 6, exp: gt, fn: gt_255_uint16}, + {idx: 6, exp: ge, fn: ge_255_uint16}, + {idx: 6, exp: eq, fn: eq_255_uint16}, + {idx: 6, exp: ne, fn: ne_255_uint16}, + {idx: 7, exp: lt, fn: lt_256_uint16}, + {idx: 7, exp: le, fn: le_256_uint16}, + {idx: 7, exp: gt, fn: gt_256_uint16}, + {idx: 7, exp: ge, fn: ge_256_uint16}, + {idx: 7, exp: eq, fn: eq_256_uint16}, + {idx: 7, exp: ne, fn: ne_256_uint16}, + {idx: 8, exp: lt, fn: lt_32766_uint16}, + {idx: 8, exp: le, fn: le_32766_uint16}, + {idx: 8, exp: gt, fn: gt_32766_uint16}, + {idx: 8, exp: ge, fn: ge_32766_uint16}, + {idx: 8, exp: eq, fn: eq_32766_uint16}, + {idx: 8, exp: ne, fn: ne_32766_uint16}, + {idx: 9, exp: lt, fn: lt_32767_uint16}, + {idx: 9, exp: le, fn: le_32767_uint16}, + {idx: 9, exp: gt, fn: gt_32767_uint16}, + {idx: 9, exp: ge, fn: ge_32767_uint16}, + {idx: 9, exp: eq, fn: eq_32767_uint16}, + {idx: 9, exp: ne, fn: ne_32767_uint16}, + {idx: 10, exp: lt, fn: lt_32768_uint16}, + {idx: 10, exp: le, fn: le_32768_uint16}, + {idx: 10, exp: gt, fn: gt_32768_uint16}, + {idx: 10, exp: ge, fn: ge_32768_uint16}, + {idx: 10, exp: eq, fn: eq_32768_uint16}, + {idx: 10, exp: ne, fn: ne_32768_uint16}, + {idx: 11, exp: lt, fn: lt_65534_uint16}, + {idx: 11, exp: le, fn: le_65534_uint16}, + {idx: 11, exp: gt, fn: gt_65534_uint16}, + {idx: 11, exp: ge, fn: ge_65534_uint16}, + {idx: 11, exp: eq, fn: eq_65534_uint16}, + {idx: 11, exp: ne, fn: ne_65534_uint16}, + {idx: 12, exp: lt, fn: lt_65535_uint16}, + {idx: 12, exp: le, fn: le_65535_uint16}, + {idx: 12, exp: gt, fn: gt_65535_uint16}, + {idx: 12, exp: ge, fn: ge_65535_uint16}, + {idx: 12, exp: eq, fn: eq_65535_uint16}, + {idx: 12, exp: ne, fn: ne_65535_uint16}, +} + +// uint8 tests +var uint8_vals = []uint8{ + 0, + 1, + 126, + 127, + 128, + 254, + 255, +} + +func lt_0_uint8(x uint8) bool { return x < 0 } +func le_0_uint8(x uint8) bool { return x <= 0 } +func gt_0_uint8(x uint8) bool { return x > 0 } +func ge_0_uint8(x uint8) bool { return x >= 0 } +func eq_0_uint8(x uint8) bool { return x == 0 } +func ne_0_uint8(x uint8) bool { return x != 0 } +func lt_1_uint8(x uint8) bool { return x < 1 } +func le_1_uint8(x uint8) bool { return x <= 1 } +func gt_1_uint8(x uint8) bool { return x > 1 } +func ge_1_uint8(x uint8) bool { return x >= 1 } +func eq_1_uint8(x uint8) bool { return x == 1 } +func ne_1_uint8(x uint8) bool { return x != 1 } +func lt_126_uint8(x uint8) bool { return x < 126 } +func le_126_uint8(x uint8) bool { return x <= 126 } +func gt_126_uint8(x uint8) bool { return x > 126 } +func ge_126_uint8(x uint8) bool { return x >= 126 } +func eq_126_uint8(x uint8) bool { return x == 126 } +func ne_126_uint8(x uint8) bool { return x != 126 } +func lt_127_uint8(x uint8) bool { return x < 127 } +func le_127_uint8(x uint8) bool { return x <= 127 } +func gt_127_uint8(x uint8) bool { return x > 127 } +func ge_127_uint8(x uint8) bool { return x >= 127 } +func eq_127_uint8(x uint8) bool { return x == 127 } +func ne_127_uint8(x uint8) bool { return x != 127 } +func lt_128_uint8(x uint8) bool { return x < 128 } +func le_128_uint8(x uint8) bool { return x <= 128 } +func gt_128_uint8(x uint8) bool { return x > 128 } +func ge_128_uint8(x uint8) bool { return x >= 128 } +func eq_128_uint8(x uint8) bool { return x == 128 } +func ne_128_uint8(x uint8) bool { return x != 128 } +func lt_254_uint8(x uint8) bool { return x < 254 } +func le_254_uint8(x uint8) bool { return x <= 254 } +func gt_254_uint8(x uint8) bool { return x > 254 } +func ge_254_uint8(x uint8) bool { return x >= 254 } +func eq_254_uint8(x uint8) bool { return x == 254 } +func ne_254_uint8(x uint8) bool { return x != 254 } +func lt_255_uint8(x uint8) bool { return x < 255 } +func le_255_uint8(x uint8) bool { return x <= 255 } +func gt_255_uint8(x uint8) bool { return x > 255 } +func ge_255_uint8(x uint8) bool { return x >= 255 } +func eq_255_uint8(x uint8) bool { return x == 255 } +func ne_255_uint8(x uint8) bool { return x != 255 } + +var uint8_tests = []struct { + idx int // index of the constant used + exp result // expected results + fn func(uint8) bool +}{ + {idx: 0, exp: lt, fn: lt_0_uint8}, + {idx: 0, exp: le, fn: le_0_uint8}, + {idx: 0, exp: gt, fn: gt_0_uint8}, + {idx: 0, exp: ge, fn: ge_0_uint8}, + {idx: 0, exp: eq, fn: eq_0_uint8}, + {idx: 0, exp: ne, fn: ne_0_uint8}, + {idx: 1, exp: lt, fn: lt_1_uint8}, + {idx: 1, exp: le, fn: le_1_uint8}, + {idx: 1, exp: gt, fn: gt_1_uint8}, + {idx: 1, exp: ge, fn: ge_1_uint8}, + {idx: 1, exp: eq, fn: eq_1_uint8}, + {idx: 1, exp: ne, fn: ne_1_uint8}, + {idx: 2, exp: lt, fn: lt_126_uint8}, + {idx: 2, exp: le, fn: le_126_uint8}, + {idx: 2, exp: gt, fn: gt_126_uint8}, + {idx: 2, exp: ge, fn: ge_126_uint8}, + {idx: 2, exp: eq, fn: eq_126_uint8}, + {idx: 2, exp: ne, fn: ne_126_uint8}, + {idx: 3, exp: lt, fn: lt_127_uint8}, + {idx: 3, exp: le, fn: le_127_uint8}, + {idx: 3, exp: gt, fn: gt_127_uint8}, + {idx: 3, exp: ge, fn: ge_127_uint8}, + {idx: 3, exp: eq, fn: eq_127_uint8}, + {idx: 3, exp: ne, fn: ne_127_uint8}, + {idx: 4, exp: lt, fn: lt_128_uint8}, + {idx: 4, exp: le, fn: le_128_uint8}, + {idx: 4, exp: gt, fn: gt_128_uint8}, + {idx: 4, exp: ge, fn: ge_128_uint8}, + {idx: 4, exp: eq, fn: eq_128_uint8}, + {idx: 4, exp: ne, fn: ne_128_uint8}, + {idx: 5, exp: lt, fn: lt_254_uint8}, + {idx: 5, exp: le, fn: le_254_uint8}, + {idx: 5, exp: gt, fn: gt_254_uint8}, + {idx: 5, exp: ge, fn: ge_254_uint8}, + {idx: 5, exp: eq, fn: eq_254_uint8}, + {idx: 5, exp: ne, fn: ne_254_uint8}, + {idx: 6, exp: lt, fn: lt_255_uint8}, + {idx: 6, exp: le, fn: le_255_uint8}, + {idx: 6, exp: gt, fn: gt_255_uint8}, + {idx: 6, exp: ge, fn: ge_255_uint8}, + {idx: 6, exp: eq, fn: eq_255_uint8}, + {idx: 6, exp: ne, fn: ne_255_uint8}, +} + +// int64 tests +var int64_vals = []int64{ + -9223372036854775808, + -9223372036854775807, + -2147483649, + -2147483648, + -2147483647, + -32769, + -32768, + -32767, + -129, + -128, + -127, + -1, + 0, + 1, + 126, + 127, + 128, + 254, + 255, + 256, + 32766, + 32767, + 32768, + 65534, + 65535, + 65536, + 2147483646, + 2147483647, + 2147483648, + 4278190080, + 4294967294, + 4294967295, + 4294967296, + 1095216660480, + 9223372036854775806, + 9223372036854775807, +} + +func lt_neg9223372036854775808_int64(x int64) bool { return x < -9223372036854775808 } +func le_neg9223372036854775808_int64(x int64) bool { return x <= -9223372036854775808 } +func gt_neg9223372036854775808_int64(x int64) bool { return x > -9223372036854775808 } +func ge_neg9223372036854775808_int64(x int64) bool { return x >= -9223372036854775808 } +func eq_neg9223372036854775808_int64(x int64) bool { return x == -9223372036854775808 } +func ne_neg9223372036854775808_int64(x int64) bool { return x != -9223372036854775808 } +func lt_neg9223372036854775807_int64(x int64) bool { return x < -9223372036854775807 } +func le_neg9223372036854775807_int64(x int64) bool { return x <= -9223372036854775807 } +func gt_neg9223372036854775807_int64(x int64) bool { return x > -9223372036854775807 } +func ge_neg9223372036854775807_int64(x int64) bool { return x >= -9223372036854775807 } +func eq_neg9223372036854775807_int64(x int64) bool { return x == -9223372036854775807 } +func ne_neg9223372036854775807_int64(x int64) bool { return x != -9223372036854775807 } +func lt_neg2147483649_int64(x int64) bool { return x < -2147483649 } +func le_neg2147483649_int64(x int64) bool { return x <= -2147483649 } +func gt_neg2147483649_int64(x int64) bool { return x > -2147483649 } +func ge_neg2147483649_int64(x int64) bool { return x >= -2147483649 } +func eq_neg2147483649_int64(x int64) bool { return x == -2147483649 } +func ne_neg2147483649_int64(x int64) bool { return x != -2147483649 } +func lt_neg2147483648_int64(x int64) bool { return x < -2147483648 } +func le_neg2147483648_int64(x int64) bool { return x <= -2147483648 } +func gt_neg2147483648_int64(x int64) bool { return x > -2147483648 } +func ge_neg2147483648_int64(x int64) bool { return x >= -2147483648 } +func eq_neg2147483648_int64(x int64) bool { return x == -2147483648 } +func ne_neg2147483648_int64(x int64) bool { return x != -2147483648 } +func lt_neg2147483647_int64(x int64) bool { return x < -2147483647 } +func le_neg2147483647_int64(x int64) bool { return x <= -2147483647 } +func gt_neg2147483647_int64(x int64) bool { return x > -2147483647 } +func ge_neg2147483647_int64(x int64) bool { return x >= -2147483647 } +func eq_neg2147483647_int64(x int64) bool { return x == -2147483647 } +func ne_neg2147483647_int64(x int64) bool { return x != -2147483647 } +func lt_neg32769_int64(x int64) bool { return x < -32769 } +func le_neg32769_int64(x int64) bool { return x <= -32769 } +func gt_neg32769_int64(x int64) bool { return x > -32769 } +func ge_neg32769_int64(x int64) bool { return x >= -32769 } +func eq_neg32769_int64(x int64) bool { return x == -32769 } +func ne_neg32769_int64(x int64) bool { return x != -32769 } +func lt_neg32768_int64(x int64) bool { return x < -32768 } +func le_neg32768_int64(x int64) bool { return x <= -32768 } +func gt_neg32768_int64(x int64) bool { return x > -32768 } +func ge_neg32768_int64(x int64) bool { return x >= -32768 } +func eq_neg32768_int64(x int64) bool { return x == -32768 } +func ne_neg32768_int64(x int64) bool { return x != -32768 } +func lt_neg32767_int64(x int64) bool { return x < -32767 } +func le_neg32767_int64(x int64) bool { return x <= -32767 } +func gt_neg32767_int64(x int64) bool { return x > -32767 } +func ge_neg32767_int64(x int64) bool { return x >= -32767 } +func eq_neg32767_int64(x int64) bool { return x == -32767 } +func ne_neg32767_int64(x int64) bool { return x != -32767 } +func lt_neg129_int64(x int64) bool { return x < -129 } +func le_neg129_int64(x int64) bool { return x <= -129 } +func gt_neg129_int64(x int64) bool { return x > -129 } +func ge_neg129_int64(x int64) bool { return x >= -129 } +func eq_neg129_int64(x int64) bool { return x == -129 } +func ne_neg129_int64(x int64) bool { return x != -129 } +func lt_neg128_int64(x int64) bool { return x < -128 } +func le_neg128_int64(x int64) bool { return x <= -128 } +func gt_neg128_int64(x int64) bool { return x > -128 } +func ge_neg128_int64(x int64) bool { return x >= -128 } +func eq_neg128_int64(x int64) bool { return x == -128 } +func ne_neg128_int64(x int64) bool { return x != -128 } +func lt_neg127_int64(x int64) bool { return x < -127 } +func le_neg127_int64(x int64) bool { return x <= -127 } +func gt_neg127_int64(x int64) bool { return x > -127 } +func ge_neg127_int64(x int64) bool { return x >= -127 } +func eq_neg127_int64(x int64) bool { return x == -127 } +func ne_neg127_int64(x int64) bool { return x != -127 } +func lt_neg1_int64(x int64) bool { return x < -1 } +func le_neg1_int64(x int64) bool { return x <= -1 } +func gt_neg1_int64(x int64) bool { return x > -1 } +func ge_neg1_int64(x int64) bool { return x >= -1 } +func eq_neg1_int64(x int64) bool { return x == -1 } +func ne_neg1_int64(x int64) bool { return x != -1 } +func lt_0_int64(x int64) bool { return x < 0 } +func le_0_int64(x int64) bool { return x <= 0 } +func gt_0_int64(x int64) bool { return x > 0 } +func ge_0_int64(x int64) bool { return x >= 0 } +func eq_0_int64(x int64) bool { return x == 0 } +func ne_0_int64(x int64) bool { return x != 0 } +func lt_1_int64(x int64) bool { return x < 1 } +func le_1_int64(x int64) bool { return x <= 1 } +func gt_1_int64(x int64) bool { return x > 1 } +func ge_1_int64(x int64) bool { return x >= 1 } +func eq_1_int64(x int64) bool { return x == 1 } +func ne_1_int64(x int64) bool { return x != 1 } +func lt_126_int64(x int64) bool { return x < 126 } +func le_126_int64(x int64) bool { return x <= 126 } +func gt_126_int64(x int64) bool { return x > 126 } +func ge_126_int64(x int64) bool { return x >= 126 } +func eq_126_int64(x int64) bool { return x == 126 } +func ne_126_int64(x int64) bool { return x != 126 } +func lt_127_int64(x int64) bool { return x < 127 } +func le_127_int64(x int64) bool { return x <= 127 } +func gt_127_int64(x int64) bool { return x > 127 } +func ge_127_int64(x int64) bool { return x >= 127 } +func eq_127_int64(x int64) bool { return x == 127 } +func ne_127_int64(x int64) bool { return x != 127 } +func lt_128_int64(x int64) bool { return x < 128 } +func le_128_int64(x int64) bool { return x <= 128 } +func gt_128_int64(x int64) bool { return x > 128 } +func ge_128_int64(x int64) bool { return x >= 128 } +func eq_128_int64(x int64) bool { return x == 128 } +func ne_128_int64(x int64) bool { return x != 128 } +func lt_254_int64(x int64) bool { return x < 254 } +func le_254_int64(x int64) bool { return x <= 254 } +func gt_254_int64(x int64) bool { return x > 254 } +func ge_254_int64(x int64) bool { return x >= 254 } +func eq_254_int64(x int64) bool { return x == 254 } +func ne_254_int64(x int64) bool { return x != 254 } +func lt_255_int64(x int64) bool { return x < 255 } +func le_255_int64(x int64) bool { return x <= 255 } +func gt_255_int64(x int64) bool { return x > 255 } +func ge_255_int64(x int64) bool { return x >= 255 } +func eq_255_int64(x int64) bool { return x == 255 } +func ne_255_int64(x int64) bool { return x != 255 } +func lt_256_int64(x int64) bool { return x < 256 } +func le_256_int64(x int64) bool { return x <= 256 } +func gt_256_int64(x int64) bool { return x > 256 } +func ge_256_int64(x int64) bool { return x >= 256 } +func eq_256_int64(x int64) bool { return x == 256 } +func ne_256_int64(x int64) bool { return x != 256 } +func lt_32766_int64(x int64) bool { return x < 32766 } +func le_32766_int64(x int64) bool { return x <= 32766 } +func gt_32766_int64(x int64) bool { return x > 32766 } +func ge_32766_int64(x int64) bool { return x >= 32766 } +func eq_32766_int64(x int64) bool { return x == 32766 } +func ne_32766_int64(x int64) bool { return x != 32766 } +func lt_32767_int64(x int64) bool { return x < 32767 } +func le_32767_int64(x int64) bool { return x <= 32767 } +func gt_32767_int64(x int64) bool { return x > 32767 } +func ge_32767_int64(x int64) bool { return x >= 32767 } +func eq_32767_int64(x int64) bool { return x == 32767 } +func ne_32767_int64(x int64) bool { return x != 32767 } +func lt_32768_int64(x int64) bool { return x < 32768 } +func le_32768_int64(x int64) bool { return x <= 32768 } +func gt_32768_int64(x int64) bool { return x > 32768 } +func ge_32768_int64(x int64) bool { return x >= 32768 } +func eq_32768_int64(x int64) bool { return x == 32768 } +func ne_32768_int64(x int64) bool { return x != 32768 } +func lt_65534_int64(x int64) bool { return x < 65534 } +func le_65534_int64(x int64) bool { return x <= 65534 } +func gt_65534_int64(x int64) bool { return x > 65534 } +func ge_65534_int64(x int64) bool { return x >= 65534 } +func eq_65534_int64(x int64) bool { return x == 65534 } +func ne_65534_int64(x int64) bool { return x != 65534 } +func lt_65535_int64(x int64) bool { return x < 65535 } +func le_65535_int64(x int64) bool { return x <= 65535 } +func gt_65535_int64(x int64) bool { return x > 65535 } +func ge_65535_int64(x int64) bool { return x >= 65535 } +func eq_65535_int64(x int64) bool { return x == 65535 } +func ne_65535_int64(x int64) bool { return x != 65535 } +func lt_65536_int64(x int64) bool { return x < 65536 } +func le_65536_int64(x int64) bool { return x <= 65536 } +func gt_65536_int64(x int64) bool { return x > 65536 } +func ge_65536_int64(x int64) bool { return x >= 65536 } +func eq_65536_int64(x int64) bool { return x == 65536 } +func ne_65536_int64(x int64) bool { return x != 65536 } +func lt_2147483646_int64(x int64) bool { return x < 2147483646 } +func le_2147483646_int64(x int64) bool { return x <= 2147483646 } +func gt_2147483646_int64(x int64) bool { return x > 2147483646 } +func ge_2147483646_int64(x int64) bool { return x >= 2147483646 } +func eq_2147483646_int64(x int64) bool { return x == 2147483646 } +func ne_2147483646_int64(x int64) bool { return x != 2147483646 } +func lt_2147483647_int64(x int64) bool { return x < 2147483647 } +func le_2147483647_int64(x int64) bool { return x <= 2147483647 } +func gt_2147483647_int64(x int64) bool { return x > 2147483647 } +func ge_2147483647_int64(x int64) bool { return x >= 2147483647 } +func eq_2147483647_int64(x int64) bool { return x == 2147483647 } +func ne_2147483647_int64(x int64) bool { return x != 2147483647 } +func lt_2147483648_int64(x int64) bool { return x < 2147483648 } +func le_2147483648_int64(x int64) bool { return x <= 2147483648 } +func gt_2147483648_int64(x int64) bool { return x > 2147483648 } +func ge_2147483648_int64(x int64) bool { return x >= 2147483648 } +func eq_2147483648_int64(x int64) bool { return x == 2147483648 } +func ne_2147483648_int64(x int64) bool { return x != 2147483648 } +func lt_4278190080_int64(x int64) bool { return x < 4278190080 } +func le_4278190080_int64(x int64) bool { return x <= 4278190080 } +func gt_4278190080_int64(x int64) bool { return x > 4278190080 } +func ge_4278190080_int64(x int64) bool { return x >= 4278190080 } +func eq_4278190080_int64(x int64) bool { return x == 4278190080 } +func ne_4278190080_int64(x int64) bool { return x != 4278190080 } +func lt_4294967294_int64(x int64) bool { return x < 4294967294 } +func le_4294967294_int64(x int64) bool { return x <= 4294967294 } +func gt_4294967294_int64(x int64) bool { return x > 4294967294 } +func ge_4294967294_int64(x int64) bool { return x >= 4294967294 } +func eq_4294967294_int64(x int64) bool { return x == 4294967294 } +func ne_4294967294_int64(x int64) bool { return x != 4294967294 } +func lt_4294967295_int64(x int64) bool { return x < 4294967295 } +func le_4294967295_int64(x int64) bool { return x <= 4294967295 } +func gt_4294967295_int64(x int64) bool { return x > 4294967295 } +func ge_4294967295_int64(x int64) bool { return x >= 4294967295 } +func eq_4294967295_int64(x int64) bool { return x == 4294967295 } +func ne_4294967295_int64(x int64) bool { return x != 4294967295 } +func lt_4294967296_int64(x int64) bool { return x < 4294967296 } +func le_4294967296_int64(x int64) bool { return x <= 4294967296 } +func gt_4294967296_int64(x int64) bool { return x > 4294967296 } +func ge_4294967296_int64(x int64) bool { return x >= 4294967296 } +func eq_4294967296_int64(x int64) bool { return x == 4294967296 } +func ne_4294967296_int64(x int64) bool { return x != 4294967296 } +func lt_1095216660480_int64(x int64) bool { return x < 1095216660480 } +func le_1095216660480_int64(x int64) bool { return x <= 1095216660480 } +func gt_1095216660480_int64(x int64) bool { return x > 1095216660480 } +func ge_1095216660480_int64(x int64) bool { return x >= 1095216660480 } +func eq_1095216660480_int64(x int64) bool { return x == 1095216660480 } +func ne_1095216660480_int64(x int64) bool { return x != 1095216660480 } +func lt_9223372036854775806_int64(x int64) bool { return x < 9223372036854775806 } +func le_9223372036854775806_int64(x int64) bool { return x <= 9223372036854775806 } +func gt_9223372036854775806_int64(x int64) bool { return x > 9223372036854775806 } +func ge_9223372036854775806_int64(x int64) bool { return x >= 9223372036854775806 } +func eq_9223372036854775806_int64(x int64) bool { return x == 9223372036854775806 } +func ne_9223372036854775806_int64(x int64) bool { return x != 9223372036854775806 } +func lt_9223372036854775807_int64(x int64) bool { return x < 9223372036854775807 } +func le_9223372036854775807_int64(x int64) bool { return x <= 9223372036854775807 } +func gt_9223372036854775807_int64(x int64) bool { return x > 9223372036854775807 } +func ge_9223372036854775807_int64(x int64) bool { return x >= 9223372036854775807 } +func eq_9223372036854775807_int64(x int64) bool { return x == 9223372036854775807 } +func ne_9223372036854775807_int64(x int64) bool { return x != 9223372036854775807 } + +var int64_tests = []struct { + idx int // index of the constant used + exp result // expected results + fn func(int64) bool +}{ + {idx: 0, exp: lt, fn: lt_neg9223372036854775808_int64}, + {idx: 0, exp: le, fn: le_neg9223372036854775808_int64}, + {idx: 0, exp: gt, fn: gt_neg9223372036854775808_int64}, + {idx: 0, exp: ge, fn: ge_neg9223372036854775808_int64}, + {idx: 0, exp: eq, fn: eq_neg9223372036854775808_int64}, + {idx: 0, exp: ne, fn: ne_neg9223372036854775808_int64}, + {idx: 1, exp: lt, fn: lt_neg9223372036854775807_int64}, + {idx: 1, exp: le, fn: le_neg9223372036854775807_int64}, + {idx: 1, exp: gt, fn: gt_neg9223372036854775807_int64}, + {idx: 1, exp: ge, fn: ge_neg9223372036854775807_int64}, + {idx: 1, exp: eq, fn: eq_neg9223372036854775807_int64}, + {idx: 1, exp: ne, fn: ne_neg9223372036854775807_int64}, + {idx: 2, exp: lt, fn: lt_neg2147483649_int64}, + {idx: 2, exp: le, fn: le_neg2147483649_int64}, + {idx: 2, exp: gt, fn: gt_neg2147483649_int64}, + {idx: 2, exp: ge, fn: ge_neg2147483649_int64}, + {idx: 2, exp: eq, fn: eq_neg2147483649_int64}, + {idx: 2, exp: ne, fn: ne_neg2147483649_int64}, + {idx: 3, exp: lt, fn: lt_neg2147483648_int64}, + {idx: 3, exp: le, fn: le_neg2147483648_int64}, + {idx: 3, exp: gt, fn: gt_neg2147483648_int64}, + {idx: 3, exp: ge, fn: ge_neg2147483648_int64}, + {idx: 3, exp: eq, fn: eq_neg2147483648_int64}, + {idx: 3, exp: ne, fn: ne_neg2147483648_int64}, + {idx: 4, exp: lt, fn: lt_neg2147483647_int64}, + {idx: 4, exp: le, fn: le_neg2147483647_int64}, + {idx: 4, exp: gt, fn: gt_neg2147483647_int64}, + {idx: 4, exp: ge, fn: ge_neg2147483647_int64}, + {idx: 4, exp: eq, fn: eq_neg2147483647_int64}, + {idx: 4, exp: ne, fn: ne_neg2147483647_int64}, + {idx: 5, exp: lt, fn: lt_neg32769_int64}, + {idx: 5, exp: le, fn: le_neg32769_int64}, + {idx: 5, exp: gt, fn: gt_neg32769_int64}, + {idx: 5, exp: ge, fn: ge_neg32769_int64}, + {idx: 5, exp: eq, fn: eq_neg32769_int64}, + {idx: 5, exp: ne, fn: ne_neg32769_int64}, + {idx: 6, exp: lt, fn: lt_neg32768_int64}, + {idx: 6, exp: le, fn: le_neg32768_int64}, + {idx: 6, exp: gt, fn: gt_neg32768_int64}, + {idx: 6, exp: ge, fn: ge_neg32768_int64}, + {idx: 6, exp: eq, fn: eq_neg32768_int64}, + {idx: 6, exp: ne, fn: ne_neg32768_int64}, + {idx: 7, exp: lt, fn: lt_neg32767_int64}, + {idx: 7, exp: le, fn: le_neg32767_int64}, + {idx: 7, exp: gt, fn: gt_neg32767_int64}, + {idx: 7, exp: ge, fn: ge_neg32767_int64}, + {idx: 7, exp: eq, fn: eq_neg32767_int64}, + {idx: 7, exp: ne, fn: ne_neg32767_int64}, + {idx: 8, exp: lt, fn: lt_neg129_int64}, + {idx: 8, exp: le, fn: le_neg129_int64}, + {idx: 8, exp: gt, fn: gt_neg129_int64}, + {idx: 8, exp: ge, fn: ge_neg129_int64}, + {idx: 8, exp: eq, fn: eq_neg129_int64}, + {idx: 8, exp: ne, fn: ne_neg129_int64}, + {idx: 9, exp: lt, fn: lt_neg128_int64}, + {idx: 9, exp: le, fn: le_neg128_int64}, + {idx: 9, exp: gt, fn: gt_neg128_int64}, + {idx: 9, exp: ge, fn: ge_neg128_int64}, + {idx: 9, exp: eq, fn: eq_neg128_int64}, + {idx: 9, exp: ne, fn: ne_neg128_int64}, + {idx: 10, exp: lt, fn: lt_neg127_int64}, + {idx: 10, exp: le, fn: le_neg127_int64}, + {idx: 10, exp: gt, fn: gt_neg127_int64}, + {idx: 10, exp: ge, fn: ge_neg127_int64}, + {idx: 10, exp: eq, fn: eq_neg127_int64}, + {idx: 10, exp: ne, fn: ne_neg127_int64}, + {idx: 11, exp: lt, fn: lt_neg1_int64}, + {idx: 11, exp: le, fn: le_neg1_int64}, + {idx: 11, exp: gt, fn: gt_neg1_int64}, + {idx: 11, exp: ge, fn: ge_neg1_int64}, + {idx: 11, exp: eq, fn: eq_neg1_int64}, + {idx: 11, exp: ne, fn: ne_neg1_int64}, + {idx: 12, exp: lt, fn: lt_0_int64}, + {idx: 12, exp: le, fn: le_0_int64}, + {idx: 12, exp: gt, fn: gt_0_int64}, + {idx: 12, exp: ge, fn: ge_0_int64}, + {idx: 12, exp: eq, fn: eq_0_int64}, + {idx: 12, exp: ne, fn: ne_0_int64}, + {idx: 13, exp: lt, fn: lt_1_int64}, + {idx: 13, exp: le, fn: le_1_int64}, + {idx: 13, exp: gt, fn: gt_1_int64}, + {idx: 13, exp: ge, fn: ge_1_int64}, + {idx: 13, exp: eq, fn: eq_1_int64}, + {idx: 13, exp: ne, fn: ne_1_int64}, + {idx: 14, exp: lt, fn: lt_126_int64}, + {idx: 14, exp: le, fn: le_126_int64}, + {idx: 14, exp: gt, fn: gt_126_int64}, + {idx: 14, exp: ge, fn: ge_126_int64}, + {idx: 14, exp: eq, fn: eq_126_int64}, + {idx: 14, exp: ne, fn: ne_126_int64}, + {idx: 15, exp: lt, fn: lt_127_int64}, + {idx: 15, exp: le, fn: le_127_int64}, + {idx: 15, exp: gt, fn: gt_127_int64}, + {idx: 15, exp: ge, fn: ge_127_int64}, + {idx: 15, exp: eq, fn: eq_127_int64}, + {idx: 15, exp: ne, fn: ne_127_int64}, + {idx: 16, exp: lt, fn: lt_128_int64}, + {idx: 16, exp: le, fn: le_128_int64}, + {idx: 16, exp: gt, fn: gt_128_int64}, + {idx: 16, exp: ge, fn: ge_128_int64}, + {idx: 16, exp: eq, fn: eq_128_int64}, + {idx: 16, exp: ne, fn: ne_128_int64}, + {idx: 17, exp: lt, fn: lt_254_int64}, + {idx: 17, exp: le, fn: le_254_int64}, + {idx: 17, exp: gt, fn: gt_254_int64}, + {idx: 17, exp: ge, fn: ge_254_int64}, + {idx: 17, exp: eq, fn: eq_254_int64}, + {idx: 17, exp: ne, fn: ne_254_int64}, + {idx: 18, exp: lt, fn: lt_255_int64}, + {idx: 18, exp: le, fn: le_255_int64}, + {idx: 18, exp: gt, fn: gt_255_int64}, + {idx: 18, exp: ge, fn: ge_255_int64}, + {idx: 18, exp: eq, fn: eq_255_int64}, + {idx: 18, exp: ne, fn: ne_255_int64}, + {idx: 19, exp: lt, fn: lt_256_int64}, + {idx: 19, exp: le, fn: le_256_int64}, + {idx: 19, exp: gt, fn: gt_256_int64}, + {idx: 19, exp: ge, fn: ge_256_int64}, + {idx: 19, exp: eq, fn: eq_256_int64}, + {idx: 19, exp: ne, fn: ne_256_int64}, + {idx: 20, exp: lt, fn: lt_32766_int64}, + {idx: 20, exp: le, fn: le_32766_int64}, + {idx: 20, exp: gt, fn: gt_32766_int64}, + {idx: 20, exp: ge, fn: ge_32766_int64}, + {idx: 20, exp: eq, fn: eq_32766_int64}, + {idx: 20, exp: ne, fn: ne_32766_int64}, + {idx: 21, exp: lt, fn: lt_32767_int64}, + {idx: 21, exp: le, fn: le_32767_int64}, + {idx: 21, exp: gt, fn: gt_32767_int64}, + {idx: 21, exp: ge, fn: ge_32767_int64}, + {idx: 21, exp: eq, fn: eq_32767_int64}, + {idx: 21, exp: ne, fn: ne_32767_int64}, + {idx: 22, exp: lt, fn: lt_32768_int64}, + {idx: 22, exp: le, fn: le_32768_int64}, + {idx: 22, exp: gt, fn: gt_32768_int64}, + {idx: 22, exp: ge, fn: ge_32768_int64}, + {idx: 22, exp: eq, fn: eq_32768_int64}, + {idx: 22, exp: ne, fn: ne_32768_int64}, + {idx: 23, exp: lt, fn: lt_65534_int64}, + {idx: 23, exp: le, fn: le_65534_int64}, + {idx: 23, exp: gt, fn: gt_65534_int64}, + {idx: 23, exp: ge, fn: ge_65534_int64}, + {idx: 23, exp: eq, fn: eq_65534_int64}, + {idx: 23, exp: ne, fn: ne_65534_int64}, + {idx: 24, exp: lt, fn: lt_65535_int64}, + {idx: 24, exp: le, fn: le_65535_int64}, + {idx: 24, exp: gt, fn: gt_65535_int64}, + {idx: 24, exp: ge, fn: ge_65535_int64}, + {idx: 24, exp: eq, fn: eq_65535_int64}, + {idx: 24, exp: ne, fn: ne_65535_int64}, + {idx: 25, exp: lt, fn: lt_65536_int64}, + {idx: 25, exp: le, fn: le_65536_int64}, + {idx: 25, exp: gt, fn: gt_65536_int64}, + {idx: 25, exp: ge, fn: ge_65536_int64}, + {idx: 25, exp: eq, fn: eq_65536_int64}, + {idx: 25, exp: ne, fn: ne_65536_int64}, + {idx: 26, exp: lt, fn: lt_2147483646_int64}, + {idx: 26, exp: le, fn: le_2147483646_int64}, + {idx: 26, exp: gt, fn: gt_2147483646_int64}, + {idx: 26, exp: ge, fn: ge_2147483646_int64}, + {idx: 26, exp: eq, fn: eq_2147483646_int64}, + {idx: 26, exp: ne, fn: ne_2147483646_int64}, + {idx: 27, exp: lt, fn: lt_2147483647_int64}, + {idx: 27, exp: le, fn: le_2147483647_int64}, + {idx: 27, exp: gt, fn: gt_2147483647_int64}, + {idx: 27, exp: ge, fn: ge_2147483647_int64}, + {idx: 27, exp: eq, fn: eq_2147483647_int64}, + {idx: 27, exp: ne, fn: ne_2147483647_int64}, + {idx: 28, exp: lt, fn: lt_2147483648_int64}, + {idx: 28, exp: le, fn: le_2147483648_int64}, + {idx: 28, exp: gt, fn: gt_2147483648_int64}, + {idx: 28, exp: ge, fn: ge_2147483648_int64}, + {idx: 28, exp: eq, fn: eq_2147483648_int64}, + {idx: 28, exp: ne, fn: ne_2147483648_int64}, + {idx: 29, exp: lt, fn: lt_4278190080_int64}, + {idx: 29, exp: le, fn: le_4278190080_int64}, + {idx: 29, exp: gt, fn: gt_4278190080_int64}, + {idx: 29, exp: ge, fn: ge_4278190080_int64}, + {idx: 29, exp: eq, fn: eq_4278190080_int64}, + {idx: 29, exp: ne, fn: ne_4278190080_int64}, + {idx: 30, exp: lt, fn: lt_4294967294_int64}, + {idx: 30, exp: le, fn: le_4294967294_int64}, + {idx: 30, exp: gt, fn: gt_4294967294_int64}, + {idx: 30, exp: ge, fn: ge_4294967294_int64}, + {idx: 30, exp: eq, fn: eq_4294967294_int64}, + {idx: 30, exp: ne, fn: ne_4294967294_int64}, + {idx: 31, exp: lt, fn: lt_4294967295_int64}, + {idx: 31, exp: le, fn: le_4294967295_int64}, + {idx: 31, exp: gt, fn: gt_4294967295_int64}, + {idx: 31, exp: ge, fn: ge_4294967295_int64}, + {idx: 31, exp: eq, fn: eq_4294967295_int64}, + {idx: 31, exp: ne, fn: ne_4294967295_int64}, + {idx: 32, exp: lt, fn: lt_4294967296_int64}, + {idx: 32, exp: le, fn: le_4294967296_int64}, + {idx: 32, exp: gt, fn: gt_4294967296_int64}, + {idx: 32, exp: ge, fn: ge_4294967296_int64}, + {idx: 32, exp: eq, fn: eq_4294967296_int64}, + {idx: 32, exp: ne, fn: ne_4294967296_int64}, + {idx: 33, exp: lt, fn: lt_1095216660480_int64}, + {idx: 33, exp: le, fn: le_1095216660480_int64}, + {idx: 33, exp: gt, fn: gt_1095216660480_int64}, + {idx: 33, exp: ge, fn: ge_1095216660480_int64}, + {idx: 33, exp: eq, fn: eq_1095216660480_int64}, + {idx: 33, exp: ne, fn: ne_1095216660480_int64}, + {idx: 34, exp: lt, fn: lt_9223372036854775806_int64}, + {idx: 34, exp: le, fn: le_9223372036854775806_int64}, + {idx: 34, exp: gt, fn: gt_9223372036854775806_int64}, + {idx: 34, exp: ge, fn: ge_9223372036854775806_int64}, + {idx: 34, exp: eq, fn: eq_9223372036854775806_int64}, + {idx: 34, exp: ne, fn: ne_9223372036854775806_int64}, + {idx: 35, exp: lt, fn: lt_9223372036854775807_int64}, + {idx: 35, exp: le, fn: le_9223372036854775807_int64}, + {idx: 35, exp: gt, fn: gt_9223372036854775807_int64}, + {idx: 35, exp: ge, fn: ge_9223372036854775807_int64}, + {idx: 35, exp: eq, fn: eq_9223372036854775807_int64}, + {idx: 35, exp: ne, fn: ne_9223372036854775807_int64}, +} + +// int32 tests +var int32_vals = []int32{ + -2147483648, + -2147483647, + -32769, + -32768, + -32767, + -129, + -128, + -127, + -1, + 0, + 1, + 126, + 127, + 128, + 254, + 255, + 256, + 32766, + 32767, + 32768, + 65534, + 65535, + 65536, + 2147483646, + 2147483647, +} + +func lt_neg2147483648_int32(x int32) bool { return x < -2147483648 } +func le_neg2147483648_int32(x int32) bool { return x <= -2147483648 } +func gt_neg2147483648_int32(x int32) bool { return x > -2147483648 } +func ge_neg2147483648_int32(x int32) bool { return x >= -2147483648 } +func eq_neg2147483648_int32(x int32) bool { return x == -2147483648 } +func ne_neg2147483648_int32(x int32) bool { return x != -2147483648 } +func lt_neg2147483647_int32(x int32) bool { return x < -2147483647 } +func le_neg2147483647_int32(x int32) bool { return x <= -2147483647 } +func gt_neg2147483647_int32(x int32) bool { return x > -2147483647 } +func ge_neg2147483647_int32(x int32) bool { return x >= -2147483647 } +func eq_neg2147483647_int32(x int32) bool { return x == -2147483647 } +func ne_neg2147483647_int32(x int32) bool { return x != -2147483647 } +func lt_neg32769_int32(x int32) bool { return x < -32769 } +func le_neg32769_int32(x int32) bool { return x <= -32769 } +func gt_neg32769_int32(x int32) bool { return x > -32769 } +func ge_neg32769_int32(x int32) bool { return x >= -32769 } +func eq_neg32769_int32(x int32) bool { return x == -32769 } +func ne_neg32769_int32(x int32) bool { return x != -32769 } +func lt_neg32768_int32(x int32) bool { return x < -32768 } +func le_neg32768_int32(x int32) bool { return x <= -32768 } +func gt_neg32768_int32(x int32) bool { return x > -32768 } +func ge_neg32768_int32(x int32) bool { return x >= -32768 } +func eq_neg32768_int32(x int32) bool { return x == -32768 } +func ne_neg32768_int32(x int32) bool { return x != -32768 } +func lt_neg32767_int32(x int32) bool { return x < -32767 } +func le_neg32767_int32(x int32) bool { return x <= -32767 } +func gt_neg32767_int32(x int32) bool { return x > -32767 } +func ge_neg32767_int32(x int32) bool { return x >= -32767 } +func eq_neg32767_int32(x int32) bool { return x == -32767 } +func ne_neg32767_int32(x int32) bool { return x != -32767 } +func lt_neg129_int32(x int32) bool { return x < -129 } +func le_neg129_int32(x int32) bool { return x <= -129 } +func gt_neg129_int32(x int32) bool { return x > -129 } +func ge_neg129_int32(x int32) bool { return x >= -129 } +func eq_neg129_int32(x int32) bool { return x == -129 } +func ne_neg129_int32(x int32) bool { return x != -129 } +func lt_neg128_int32(x int32) bool { return x < -128 } +func le_neg128_int32(x int32) bool { return x <= -128 } +func gt_neg128_int32(x int32) bool { return x > -128 } +func ge_neg128_int32(x int32) bool { return x >= -128 } +func eq_neg128_int32(x int32) bool { return x == -128 } +func ne_neg128_int32(x int32) bool { return x != -128 } +func lt_neg127_int32(x int32) bool { return x < -127 } +func le_neg127_int32(x int32) bool { return x <= -127 } +func gt_neg127_int32(x int32) bool { return x > -127 } +func ge_neg127_int32(x int32) bool { return x >= -127 } +func eq_neg127_int32(x int32) bool { return x == -127 } +func ne_neg127_int32(x int32) bool { return x != -127 } +func lt_neg1_int32(x int32) bool { return x < -1 } +func le_neg1_int32(x int32) bool { return x <= -1 } +func gt_neg1_int32(x int32) bool { return x > -1 } +func ge_neg1_int32(x int32) bool { return x >= -1 } +func eq_neg1_int32(x int32) bool { return x == -1 } +func ne_neg1_int32(x int32) bool { return x != -1 } +func lt_0_int32(x int32) bool { return x < 0 } +func le_0_int32(x int32) bool { return x <= 0 } +func gt_0_int32(x int32) bool { return x > 0 } +func ge_0_int32(x int32) bool { return x >= 0 } +func eq_0_int32(x int32) bool { return x == 0 } +func ne_0_int32(x int32) bool { return x != 0 } +func lt_1_int32(x int32) bool { return x < 1 } +func le_1_int32(x int32) bool { return x <= 1 } +func gt_1_int32(x int32) bool { return x > 1 } +func ge_1_int32(x int32) bool { return x >= 1 } +func eq_1_int32(x int32) bool { return x == 1 } +func ne_1_int32(x int32) bool { return x != 1 } +func lt_126_int32(x int32) bool { return x < 126 } +func le_126_int32(x int32) bool { return x <= 126 } +func gt_126_int32(x int32) bool { return x > 126 } +func ge_126_int32(x int32) bool { return x >= 126 } +func eq_126_int32(x int32) bool { return x == 126 } +func ne_126_int32(x int32) bool { return x != 126 } +func lt_127_int32(x int32) bool { return x < 127 } +func le_127_int32(x int32) bool { return x <= 127 } +func gt_127_int32(x int32) bool { return x > 127 } +func ge_127_int32(x int32) bool { return x >= 127 } +func eq_127_int32(x int32) bool { return x == 127 } +func ne_127_int32(x int32) bool { return x != 127 } +func lt_128_int32(x int32) bool { return x < 128 } +func le_128_int32(x int32) bool { return x <= 128 } +func gt_128_int32(x int32) bool { return x > 128 } +func ge_128_int32(x int32) bool { return x >= 128 } +func eq_128_int32(x int32) bool { return x == 128 } +func ne_128_int32(x int32) bool { return x != 128 } +func lt_254_int32(x int32) bool { return x < 254 } +func le_254_int32(x int32) bool { return x <= 254 } +func gt_254_int32(x int32) bool { return x > 254 } +func ge_254_int32(x int32) bool { return x >= 254 } +func eq_254_int32(x int32) bool { return x == 254 } +func ne_254_int32(x int32) bool { return x != 254 } +func lt_255_int32(x int32) bool { return x < 255 } +func le_255_int32(x int32) bool { return x <= 255 } +func gt_255_int32(x int32) bool { return x > 255 } +func ge_255_int32(x int32) bool { return x >= 255 } +func eq_255_int32(x int32) bool { return x == 255 } +func ne_255_int32(x int32) bool { return x != 255 } +func lt_256_int32(x int32) bool { return x < 256 } +func le_256_int32(x int32) bool { return x <= 256 } +func gt_256_int32(x int32) bool { return x > 256 } +func ge_256_int32(x int32) bool { return x >= 256 } +func eq_256_int32(x int32) bool { return x == 256 } +func ne_256_int32(x int32) bool { return x != 256 } +func lt_32766_int32(x int32) bool { return x < 32766 } +func le_32766_int32(x int32) bool { return x <= 32766 } +func gt_32766_int32(x int32) bool { return x > 32766 } +func ge_32766_int32(x int32) bool { return x >= 32766 } +func eq_32766_int32(x int32) bool { return x == 32766 } +func ne_32766_int32(x int32) bool { return x != 32766 } +func lt_32767_int32(x int32) bool { return x < 32767 } +func le_32767_int32(x int32) bool { return x <= 32767 } +func gt_32767_int32(x int32) bool { return x > 32767 } +func ge_32767_int32(x int32) bool { return x >= 32767 } +func eq_32767_int32(x int32) bool { return x == 32767 } +func ne_32767_int32(x int32) bool { return x != 32767 } +func lt_32768_int32(x int32) bool { return x < 32768 } +func le_32768_int32(x int32) bool { return x <= 32768 } +func gt_32768_int32(x int32) bool { return x > 32768 } +func ge_32768_int32(x int32) bool { return x >= 32768 } +func eq_32768_int32(x int32) bool { return x == 32768 } +func ne_32768_int32(x int32) bool { return x != 32768 } +func lt_65534_int32(x int32) bool { return x < 65534 } +func le_65534_int32(x int32) bool { return x <= 65534 } +func gt_65534_int32(x int32) bool { return x > 65534 } +func ge_65534_int32(x int32) bool { return x >= 65534 } +func eq_65534_int32(x int32) bool { return x == 65534 } +func ne_65534_int32(x int32) bool { return x != 65534 } +func lt_65535_int32(x int32) bool { return x < 65535 } +func le_65535_int32(x int32) bool { return x <= 65535 } +func gt_65535_int32(x int32) bool { return x > 65535 } +func ge_65535_int32(x int32) bool { return x >= 65535 } +func eq_65535_int32(x int32) bool { return x == 65535 } +func ne_65535_int32(x int32) bool { return x != 65535 } +func lt_65536_int32(x int32) bool { return x < 65536 } +func le_65536_int32(x int32) bool { return x <= 65536 } +func gt_65536_int32(x int32) bool { return x > 65536 } +func ge_65536_int32(x int32) bool { return x >= 65536 } +func eq_65536_int32(x int32) bool { return x == 65536 } +func ne_65536_int32(x int32) bool { return x != 65536 } +func lt_2147483646_int32(x int32) bool { return x < 2147483646 } +func le_2147483646_int32(x int32) bool { return x <= 2147483646 } +func gt_2147483646_int32(x int32) bool { return x > 2147483646 } +func ge_2147483646_int32(x int32) bool { return x >= 2147483646 } +func eq_2147483646_int32(x int32) bool { return x == 2147483646 } +func ne_2147483646_int32(x int32) bool { return x != 2147483646 } +func lt_2147483647_int32(x int32) bool { return x < 2147483647 } +func le_2147483647_int32(x int32) bool { return x <= 2147483647 } +func gt_2147483647_int32(x int32) bool { return x > 2147483647 } +func ge_2147483647_int32(x int32) bool { return x >= 2147483647 } +func eq_2147483647_int32(x int32) bool { return x == 2147483647 } +func ne_2147483647_int32(x int32) bool { return x != 2147483647 } + +var int32_tests = []struct { + idx int // index of the constant used + exp result // expected results + fn func(int32) bool +}{ + {idx: 0, exp: lt, fn: lt_neg2147483648_int32}, + {idx: 0, exp: le, fn: le_neg2147483648_int32}, + {idx: 0, exp: gt, fn: gt_neg2147483648_int32}, + {idx: 0, exp: ge, fn: ge_neg2147483648_int32}, + {idx: 0, exp: eq, fn: eq_neg2147483648_int32}, + {idx: 0, exp: ne, fn: ne_neg2147483648_int32}, + {idx: 1, exp: lt, fn: lt_neg2147483647_int32}, + {idx: 1, exp: le, fn: le_neg2147483647_int32}, + {idx: 1, exp: gt, fn: gt_neg2147483647_int32}, + {idx: 1, exp: ge, fn: ge_neg2147483647_int32}, + {idx: 1, exp: eq, fn: eq_neg2147483647_int32}, + {idx: 1, exp: ne, fn: ne_neg2147483647_int32}, + {idx: 2, exp: lt, fn: lt_neg32769_int32}, + {idx: 2, exp: le, fn: le_neg32769_int32}, + {idx: 2, exp: gt, fn: gt_neg32769_int32}, + {idx: 2, exp: ge, fn: ge_neg32769_int32}, + {idx: 2, exp: eq, fn: eq_neg32769_int32}, + {idx: 2, exp: ne, fn: ne_neg32769_int32}, + {idx: 3, exp: lt, fn: lt_neg32768_int32}, + {idx: 3, exp: le, fn: le_neg32768_int32}, + {idx: 3, exp: gt, fn: gt_neg32768_int32}, + {idx: 3, exp: ge, fn: ge_neg32768_int32}, + {idx: 3, exp: eq, fn: eq_neg32768_int32}, + {idx: 3, exp: ne, fn: ne_neg32768_int32}, + {idx: 4, exp: lt, fn: lt_neg32767_int32}, + {idx: 4, exp: le, fn: le_neg32767_int32}, + {idx: 4, exp: gt, fn: gt_neg32767_int32}, + {idx: 4, exp: ge, fn: ge_neg32767_int32}, + {idx: 4, exp: eq, fn: eq_neg32767_int32}, + {idx: 4, exp: ne, fn: ne_neg32767_int32}, + {idx: 5, exp: lt, fn: lt_neg129_int32}, + {idx: 5, exp: le, fn: le_neg129_int32}, + {idx: 5, exp: gt, fn: gt_neg129_int32}, + {idx: 5, exp: ge, fn: ge_neg129_int32}, + {idx: 5, exp: eq, fn: eq_neg129_int32}, + {idx: 5, exp: ne, fn: ne_neg129_int32}, + {idx: 6, exp: lt, fn: lt_neg128_int32}, + {idx: 6, exp: le, fn: le_neg128_int32}, + {idx: 6, exp: gt, fn: gt_neg128_int32}, + {idx: 6, exp: ge, fn: ge_neg128_int32}, + {idx: 6, exp: eq, fn: eq_neg128_int32}, + {idx: 6, exp: ne, fn: ne_neg128_int32}, + {idx: 7, exp: lt, fn: lt_neg127_int32}, + {idx: 7, exp: le, fn: le_neg127_int32}, + {idx: 7, exp: gt, fn: gt_neg127_int32}, + {idx: 7, exp: ge, fn: ge_neg127_int32}, + {idx: 7, exp: eq, fn: eq_neg127_int32}, + {idx: 7, exp: ne, fn: ne_neg127_int32}, + {idx: 8, exp: lt, fn: lt_neg1_int32}, + {idx: 8, exp: le, fn: le_neg1_int32}, + {idx: 8, exp: gt, fn: gt_neg1_int32}, + {idx: 8, exp: ge, fn: ge_neg1_int32}, + {idx: 8, exp: eq, fn: eq_neg1_int32}, + {idx: 8, exp: ne, fn: ne_neg1_int32}, + {idx: 9, exp: lt, fn: lt_0_int32}, + {idx: 9, exp: le, fn: le_0_int32}, + {idx: 9, exp: gt, fn: gt_0_int32}, + {idx: 9, exp: ge, fn: ge_0_int32}, + {idx: 9, exp: eq, fn: eq_0_int32}, + {idx: 9, exp: ne, fn: ne_0_int32}, + {idx: 10, exp: lt, fn: lt_1_int32}, + {idx: 10, exp: le, fn: le_1_int32}, + {idx: 10, exp: gt, fn: gt_1_int32}, + {idx: 10, exp: ge, fn: ge_1_int32}, + {idx: 10, exp: eq, fn: eq_1_int32}, + {idx: 10, exp: ne, fn: ne_1_int32}, + {idx: 11, exp: lt, fn: lt_126_int32}, + {idx: 11, exp: le, fn: le_126_int32}, + {idx: 11, exp: gt, fn: gt_126_int32}, + {idx: 11, exp: ge, fn: ge_126_int32}, + {idx: 11, exp: eq, fn: eq_126_int32}, + {idx: 11, exp: ne, fn: ne_126_int32}, + {idx: 12, exp: lt, fn: lt_127_int32}, + {idx: 12, exp: le, fn: le_127_int32}, + {idx: 12, exp: gt, fn: gt_127_int32}, + {idx: 12, exp: ge, fn: ge_127_int32}, + {idx: 12, exp: eq, fn: eq_127_int32}, + {idx: 12, exp: ne, fn: ne_127_int32}, + {idx: 13, exp: lt, fn: lt_128_int32}, + {idx: 13, exp: le, fn: le_128_int32}, + {idx: 13, exp: gt, fn: gt_128_int32}, + {idx: 13, exp: ge, fn: ge_128_int32}, + {idx: 13, exp: eq, fn: eq_128_int32}, + {idx: 13, exp: ne, fn: ne_128_int32}, + {idx: 14, exp: lt, fn: lt_254_int32}, + {idx: 14, exp: le, fn: le_254_int32}, + {idx: 14, exp: gt, fn: gt_254_int32}, + {idx: 14, exp: ge, fn: ge_254_int32}, + {idx: 14, exp: eq, fn: eq_254_int32}, + {idx: 14, exp: ne, fn: ne_254_int32}, + {idx: 15, exp: lt, fn: lt_255_int32}, + {idx: 15, exp: le, fn: le_255_int32}, + {idx: 15, exp: gt, fn: gt_255_int32}, + {idx: 15, exp: ge, fn: ge_255_int32}, + {idx: 15, exp: eq, fn: eq_255_int32}, + {idx: 15, exp: ne, fn: ne_255_int32}, + {idx: 16, exp: lt, fn: lt_256_int32}, + {idx: 16, exp: le, fn: le_256_int32}, + {idx: 16, exp: gt, fn: gt_256_int32}, + {idx: 16, exp: ge, fn: ge_256_int32}, + {idx: 16, exp: eq, fn: eq_256_int32}, + {idx: 16, exp: ne, fn: ne_256_int32}, + {idx: 17, exp: lt, fn: lt_32766_int32}, + {idx: 17, exp: le, fn: le_32766_int32}, + {idx: 17, exp: gt, fn: gt_32766_int32}, + {idx: 17, exp: ge, fn: ge_32766_int32}, + {idx: 17, exp: eq, fn: eq_32766_int32}, + {idx: 17, exp: ne, fn: ne_32766_int32}, + {idx: 18, exp: lt, fn: lt_32767_int32}, + {idx: 18, exp: le, fn: le_32767_int32}, + {idx: 18, exp: gt, fn: gt_32767_int32}, + {idx: 18, exp: ge, fn: ge_32767_int32}, + {idx: 18, exp: eq, fn: eq_32767_int32}, + {idx: 18, exp: ne, fn: ne_32767_int32}, + {idx: 19, exp: lt, fn: lt_32768_int32}, + {idx: 19, exp: le, fn: le_32768_int32}, + {idx: 19, exp: gt, fn: gt_32768_int32}, + {idx: 19, exp: ge, fn: ge_32768_int32}, + {idx: 19, exp: eq, fn: eq_32768_int32}, + {idx: 19, exp: ne, fn: ne_32768_int32}, + {idx: 20, exp: lt, fn: lt_65534_int32}, + {idx: 20, exp: le, fn: le_65534_int32}, + {idx: 20, exp: gt, fn: gt_65534_int32}, + {idx: 20, exp: ge, fn: ge_65534_int32}, + {idx: 20, exp: eq, fn: eq_65534_int32}, + {idx: 20, exp: ne, fn: ne_65534_int32}, + {idx: 21, exp: lt, fn: lt_65535_int32}, + {idx: 21, exp: le, fn: le_65535_int32}, + {idx: 21, exp: gt, fn: gt_65535_int32}, + {idx: 21, exp: ge, fn: ge_65535_int32}, + {idx: 21, exp: eq, fn: eq_65535_int32}, + {idx: 21, exp: ne, fn: ne_65535_int32}, + {idx: 22, exp: lt, fn: lt_65536_int32}, + {idx: 22, exp: le, fn: le_65536_int32}, + {idx: 22, exp: gt, fn: gt_65536_int32}, + {idx: 22, exp: ge, fn: ge_65536_int32}, + {idx: 22, exp: eq, fn: eq_65536_int32}, + {idx: 22, exp: ne, fn: ne_65536_int32}, + {idx: 23, exp: lt, fn: lt_2147483646_int32}, + {idx: 23, exp: le, fn: le_2147483646_int32}, + {idx: 23, exp: gt, fn: gt_2147483646_int32}, + {idx: 23, exp: ge, fn: ge_2147483646_int32}, + {idx: 23, exp: eq, fn: eq_2147483646_int32}, + {idx: 23, exp: ne, fn: ne_2147483646_int32}, + {idx: 24, exp: lt, fn: lt_2147483647_int32}, + {idx: 24, exp: le, fn: le_2147483647_int32}, + {idx: 24, exp: gt, fn: gt_2147483647_int32}, + {idx: 24, exp: ge, fn: ge_2147483647_int32}, + {idx: 24, exp: eq, fn: eq_2147483647_int32}, + {idx: 24, exp: ne, fn: ne_2147483647_int32}, +} + +// int16 tests +var int16_vals = []int16{ + -32768, + -32767, + -129, + -128, + -127, + -1, + 0, + 1, + 126, + 127, + 128, + 254, + 255, + 256, + 32766, + 32767, +} + +func lt_neg32768_int16(x int16) bool { return x < -32768 } +func le_neg32768_int16(x int16) bool { return x <= -32768 } +func gt_neg32768_int16(x int16) bool { return x > -32768 } +func ge_neg32768_int16(x int16) bool { return x >= -32768 } +func eq_neg32768_int16(x int16) bool { return x == -32768 } +func ne_neg32768_int16(x int16) bool { return x != -32768 } +func lt_neg32767_int16(x int16) bool { return x < -32767 } +func le_neg32767_int16(x int16) bool { return x <= -32767 } +func gt_neg32767_int16(x int16) bool { return x > -32767 } +func ge_neg32767_int16(x int16) bool { return x >= -32767 } +func eq_neg32767_int16(x int16) bool { return x == -32767 } +func ne_neg32767_int16(x int16) bool { return x != -32767 } +func lt_neg129_int16(x int16) bool { return x < -129 } +func le_neg129_int16(x int16) bool { return x <= -129 } +func gt_neg129_int16(x int16) bool { return x > -129 } +func ge_neg129_int16(x int16) bool { return x >= -129 } +func eq_neg129_int16(x int16) bool { return x == -129 } +func ne_neg129_int16(x int16) bool { return x != -129 } +func lt_neg128_int16(x int16) bool { return x < -128 } +func le_neg128_int16(x int16) bool { return x <= -128 } +func gt_neg128_int16(x int16) bool { return x > -128 } +func ge_neg128_int16(x int16) bool { return x >= -128 } +func eq_neg128_int16(x int16) bool { return x == -128 } +func ne_neg128_int16(x int16) bool { return x != -128 } +func lt_neg127_int16(x int16) bool { return x < -127 } +func le_neg127_int16(x int16) bool { return x <= -127 } +func gt_neg127_int16(x int16) bool { return x > -127 } +func ge_neg127_int16(x int16) bool { return x >= -127 } +func eq_neg127_int16(x int16) bool { return x == -127 } +func ne_neg127_int16(x int16) bool { return x != -127 } +func lt_neg1_int16(x int16) bool { return x < -1 } +func le_neg1_int16(x int16) bool { return x <= -1 } +func gt_neg1_int16(x int16) bool { return x > -1 } +func ge_neg1_int16(x int16) bool { return x >= -1 } +func eq_neg1_int16(x int16) bool { return x == -1 } +func ne_neg1_int16(x int16) bool { return x != -1 } +func lt_0_int16(x int16) bool { return x < 0 } +func le_0_int16(x int16) bool { return x <= 0 } +func gt_0_int16(x int16) bool { return x > 0 } +func ge_0_int16(x int16) bool { return x >= 0 } +func eq_0_int16(x int16) bool { return x == 0 } +func ne_0_int16(x int16) bool { return x != 0 } +func lt_1_int16(x int16) bool { return x < 1 } +func le_1_int16(x int16) bool { return x <= 1 } +func gt_1_int16(x int16) bool { return x > 1 } +func ge_1_int16(x int16) bool { return x >= 1 } +func eq_1_int16(x int16) bool { return x == 1 } +func ne_1_int16(x int16) bool { return x != 1 } +func lt_126_int16(x int16) bool { return x < 126 } +func le_126_int16(x int16) bool { return x <= 126 } +func gt_126_int16(x int16) bool { return x > 126 } +func ge_126_int16(x int16) bool { return x >= 126 } +func eq_126_int16(x int16) bool { return x == 126 } +func ne_126_int16(x int16) bool { return x != 126 } +func lt_127_int16(x int16) bool { return x < 127 } +func le_127_int16(x int16) bool { return x <= 127 } +func gt_127_int16(x int16) bool { return x > 127 } +func ge_127_int16(x int16) bool { return x >= 127 } +func eq_127_int16(x int16) bool { return x == 127 } +func ne_127_int16(x int16) bool { return x != 127 } +func lt_128_int16(x int16) bool { return x < 128 } +func le_128_int16(x int16) bool { return x <= 128 } +func gt_128_int16(x int16) bool { return x > 128 } +func ge_128_int16(x int16) bool { return x >= 128 } +func eq_128_int16(x int16) bool { return x == 128 } +func ne_128_int16(x int16) bool { return x != 128 } +func lt_254_int16(x int16) bool { return x < 254 } +func le_254_int16(x int16) bool { return x <= 254 } +func gt_254_int16(x int16) bool { return x > 254 } +func ge_254_int16(x int16) bool { return x >= 254 } +func eq_254_int16(x int16) bool { return x == 254 } +func ne_254_int16(x int16) bool { return x != 254 } +func lt_255_int16(x int16) bool { return x < 255 } +func le_255_int16(x int16) bool { return x <= 255 } +func gt_255_int16(x int16) bool { return x > 255 } +func ge_255_int16(x int16) bool { return x >= 255 } +func eq_255_int16(x int16) bool { return x == 255 } +func ne_255_int16(x int16) bool { return x != 255 } +func lt_256_int16(x int16) bool { return x < 256 } +func le_256_int16(x int16) bool { return x <= 256 } +func gt_256_int16(x int16) bool { return x > 256 } +func ge_256_int16(x int16) bool { return x >= 256 } +func eq_256_int16(x int16) bool { return x == 256 } +func ne_256_int16(x int16) bool { return x != 256 } +func lt_32766_int16(x int16) bool { return x < 32766 } +func le_32766_int16(x int16) bool { return x <= 32766 } +func gt_32766_int16(x int16) bool { return x > 32766 } +func ge_32766_int16(x int16) bool { return x >= 32766 } +func eq_32766_int16(x int16) bool { return x == 32766 } +func ne_32766_int16(x int16) bool { return x != 32766 } +func lt_32767_int16(x int16) bool { return x < 32767 } +func le_32767_int16(x int16) bool { return x <= 32767 } +func gt_32767_int16(x int16) bool { return x > 32767 } +func ge_32767_int16(x int16) bool { return x >= 32767 } +func eq_32767_int16(x int16) bool { return x == 32767 } +func ne_32767_int16(x int16) bool { return x != 32767 } + +var int16_tests = []struct { + idx int // index of the constant used + exp result // expected results + fn func(int16) bool +}{ + {idx: 0, exp: lt, fn: lt_neg32768_int16}, + {idx: 0, exp: le, fn: le_neg32768_int16}, + {idx: 0, exp: gt, fn: gt_neg32768_int16}, + {idx: 0, exp: ge, fn: ge_neg32768_int16}, + {idx: 0, exp: eq, fn: eq_neg32768_int16}, + {idx: 0, exp: ne, fn: ne_neg32768_int16}, + {idx: 1, exp: lt, fn: lt_neg32767_int16}, + {idx: 1, exp: le, fn: le_neg32767_int16}, + {idx: 1, exp: gt, fn: gt_neg32767_int16}, + {idx: 1, exp: ge, fn: ge_neg32767_int16}, + {idx: 1, exp: eq, fn: eq_neg32767_int16}, + {idx: 1, exp: ne, fn: ne_neg32767_int16}, + {idx: 2, exp: lt, fn: lt_neg129_int16}, + {idx: 2, exp: le, fn: le_neg129_int16}, + {idx: 2, exp: gt, fn: gt_neg129_int16}, + {idx: 2, exp: ge, fn: ge_neg129_int16}, + {idx: 2, exp: eq, fn: eq_neg129_int16}, + {idx: 2, exp: ne, fn: ne_neg129_int16}, + {idx: 3, exp: lt, fn: lt_neg128_int16}, + {idx: 3, exp: le, fn: le_neg128_int16}, + {idx: 3, exp: gt, fn: gt_neg128_int16}, + {idx: 3, exp: ge, fn: ge_neg128_int16}, + {idx: 3, exp: eq, fn: eq_neg128_int16}, + {idx: 3, exp: ne, fn: ne_neg128_int16}, + {idx: 4, exp: lt, fn: lt_neg127_int16}, + {idx: 4, exp: le, fn: le_neg127_int16}, + {idx: 4, exp: gt, fn: gt_neg127_int16}, + {idx: 4, exp: ge, fn: ge_neg127_int16}, + {idx: 4, exp: eq, fn: eq_neg127_int16}, + {idx: 4, exp: ne, fn: ne_neg127_int16}, + {idx: 5, exp: lt, fn: lt_neg1_int16}, + {idx: 5, exp: le, fn: le_neg1_int16}, + {idx: 5, exp: gt, fn: gt_neg1_int16}, + {idx: 5, exp: ge, fn: ge_neg1_int16}, + {idx: 5, exp: eq, fn: eq_neg1_int16}, + {idx: 5, exp: ne, fn: ne_neg1_int16}, + {idx: 6, exp: lt, fn: lt_0_int16}, + {idx: 6, exp: le, fn: le_0_int16}, + {idx: 6, exp: gt, fn: gt_0_int16}, + {idx: 6, exp: ge, fn: ge_0_int16}, + {idx: 6, exp: eq, fn: eq_0_int16}, + {idx: 6, exp: ne, fn: ne_0_int16}, + {idx: 7, exp: lt, fn: lt_1_int16}, + {idx: 7, exp: le, fn: le_1_int16}, + {idx: 7, exp: gt, fn: gt_1_int16}, + {idx: 7, exp: ge, fn: ge_1_int16}, + {idx: 7, exp: eq, fn: eq_1_int16}, + {idx: 7, exp: ne, fn: ne_1_int16}, + {idx: 8, exp: lt, fn: lt_126_int16}, + {idx: 8, exp: le, fn: le_126_int16}, + {idx: 8, exp: gt, fn: gt_126_int16}, + {idx: 8, exp: ge, fn: ge_126_int16}, + {idx: 8, exp: eq, fn: eq_126_int16}, + {idx: 8, exp: ne, fn: ne_126_int16}, + {idx: 9, exp: lt, fn: lt_127_int16}, + {idx: 9, exp: le, fn: le_127_int16}, + {idx: 9, exp: gt, fn: gt_127_int16}, + {idx: 9, exp: ge, fn: ge_127_int16}, + {idx: 9, exp: eq, fn: eq_127_int16}, + {idx: 9, exp: ne, fn: ne_127_int16}, + {idx: 10, exp: lt, fn: lt_128_int16}, + {idx: 10, exp: le, fn: le_128_int16}, + {idx: 10, exp: gt, fn: gt_128_int16}, + {idx: 10, exp: ge, fn: ge_128_int16}, + {idx: 10, exp: eq, fn: eq_128_int16}, + {idx: 10, exp: ne, fn: ne_128_int16}, + {idx: 11, exp: lt, fn: lt_254_int16}, + {idx: 11, exp: le, fn: le_254_int16}, + {idx: 11, exp: gt, fn: gt_254_int16}, + {idx: 11, exp: ge, fn: ge_254_int16}, + {idx: 11, exp: eq, fn: eq_254_int16}, + {idx: 11, exp: ne, fn: ne_254_int16}, + {idx: 12, exp: lt, fn: lt_255_int16}, + {idx: 12, exp: le, fn: le_255_int16}, + {idx: 12, exp: gt, fn: gt_255_int16}, + {idx: 12, exp: ge, fn: ge_255_int16}, + {idx: 12, exp: eq, fn: eq_255_int16}, + {idx: 12, exp: ne, fn: ne_255_int16}, + {idx: 13, exp: lt, fn: lt_256_int16}, + {idx: 13, exp: le, fn: le_256_int16}, + {idx: 13, exp: gt, fn: gt_256_int16}, + {idx: 13, exp: ge, fn: ge_256_int16}, + {idx: 13, exp: eq, fn: eq_256_int16}, + {idx: 13, exp: ne, fn: ne_256_int16}, + {idx: 14, exp: lt, fn: lt_32766_int16}, + {idx: 14, exp: le, fn: le_32766_int16}, + {idx: 14, exp: gt, fn: gt_32766_int16}, + {idx: 14, exp: ge, fn: ge_32766_int16}, + {idx: 14, exp: eq, fn: eq_32766_int16}, + {idx: 14, exp: ne, fn: ne_32766_int16}, + {idx: 15, exp: lt, fn: lt_32767_int16}, + {idx: 15, exp: le, fn: le_32767_int16}, + {idx: 15, exp: gt, fn: gt_32767_int16}, + {idx: 15, exp: ge, fn: ge_32767_int16}, + {idx: 15, exp: eq, fn: eq_32767_int16}, + {idx: 15, exp: ne, fn: ne_32767_int16}, +} + +// int8 tests +var int8_vals = []int8{ + -128, + -127, + -1, + 0, + 1, + 126, + 127, +} + +func lt_neg128_int8(x int8) bool { return x < -128 } +func le_neg128_int8(x int8) bool { return x <= -128 } +func gt_neg128_int8(x int8) bool { return x > -128 } +func ge_neg128_int8(x int8) bool { return x >= -128 } +func eq_neg128_int8(x int8) bool { return x == -128 } +func ne_neg128_int8(x int8) bool { return x != -128 } +func lt_neg127_int8(x int8) bool { return x < -127 } +func le_neg127_int8(x int8) bool { return x <= -127 } +func gt_neg127_int8(x int8) bool { return x > -127 } +func ge_neg127_int8(x int8) bool { return x >= -127 } +func eq_neg127_int8(x int8) bool { return x == -127 } +func ne_neg127_int8(x int8) bool { return x != -127 } +func lt_neg1_int8(x int8) bool { return x < -1 } +func le_neg1_int8(x int8) bool { return x <= -1 } +func gt_neg1_int8(x int8) bool { return x > -1 } +func ge_neg1_int8(x int8) bool { return x >= -1 } +func eq_neg1_int8(x int8) bool { return x == -1 } +func ne_neg1_int8(x int8) bool { return x != -1 } +func lt_0_int8(x int8) bool { return x < 0 } +func le_0_int8(x int8) bool { return x <= 0 } +func gt_0_int8(x int8) bool { return x > 0 } +func ge_0_int8(x int8) bool { return x >= 0 } +func eq_0_int8(x int8) bool { return x == 0 } +func ne_0_int8(x int8) bool { return x != 0 } +func lt_1_int8(x int8) bool { return x < 1 } +func le_1_int8(x int8) bool { return x <= 1 } +func gt_1_int8(x int8) bool { return x > 1 } +func ge_1_int8(x int8) bool { return x >= 1 } +func eq_1_int8(x int8) bool { return x == 1 } +func ne_1_int8(x int8) bool { return x != 1 } +func lt_126_int8(x int8) bool { return x < 126 } +func le_126_int8(x int8) bool { return x <= 126 } +func gt_126_int8(x int8) bool { return x > 126 } +func ge_126_int8(x int8) bool { return x >= 126 } +func eq_126_int8(x int8) bool { return x == 126 } +func ne_126_int8(x int8) bool { return x != 126 } +func lt_127_int8(x int8) bool { return x < 127 } +func le_127_int8(x int8) bool { return x <= 127 } +func gt_127_int8(x int8) bool { return x > 127 } +func ge_127_int8(x int8) bool { return x >= 127 } +func eq_127_int8(x int8) bool { return x == 127 } +func ne_127_int8(x int8) bool { return x != 127 } + +var int8_tests = []struct { + idx int // index of the constant used + exp result // expected results + fn func(int8) bool +}{ + {idx: 0, exp: lt, fn: lt_neg128_int8}, + {idx: 0, exp: le, fn: le_neg128_int8}, + {idx: 0, exp: gt, fn: gt_neg128_int8}, + {idx: 0, exp: ge, fn: ge_neg128_int8}, + {idx: 0, exp: eq, fn: eq_neg128_int8}, + {idx: 0, exp: ne, fn: ne_neg128_int8}, + {idx: 1, exp: lt, fn: lt_neg127_int8}, + {idx: 1, exp: le, fn: le_neg127_int8}, + {idx: 1, exp: gt, fn: gt_neg127_int8}, + {idx: 1, exp: ge, fn: ge_neg127_int8}, + {idx: 1, exp: eq, fn: eq_neg127_int8}, + {idx: 1, exp: ne, fn: ne_neg127_int8}, + {idx: 2, exp: lt, fn: lt_neg1_int8}, + {idx: 2, exp: le, fn: le_neg1_int8}, + {idx: 2, exp: gt, fn: gt_neg1_int8}, + {idx: 2, exp: ge, fn: ge_neg1_int8}, + {idx: 2, exp: eq, fn: eq_neg1_int8}, + {idx: 2, exp: ne, fn: ne_neg1_int8}, + {idx: 3, exp: lt, fn: lt_0_int8}, + {idx: 3, exp: le, fn: le_0_int8}, + {idx: 3, exp: gt, fn: gt_0_int8}, + {idx: 3, exp: ge, fn: ge_0_int8}, + {idx: 3, exp: eq, fn: eq_0_int8}, + {idx: 3, exp: ne, fn: ne_0_int8}, + {idx: 4, exp: lt, fn: lt_1_int8}, + {idx: 4, exp: le, fn: le_1_int8}, + {idx: 4, exp: gt, fn: gt_1_int8}, + {idx: 4, exp: ge, fn: ge_1_int8}, + {idx: 4, exp: eq, fn: eq_1_int8}, + {idx: 4, exp: ne, fn: ne_1_int8}, + {idx: 5, exp: lt, fn: lt_126_int8}, + {idx: 5, exp: le, fn: le_126_int8}, + {idx: 5, exp: gt, fn: gt_126_int8}, + {idx: 5, exp: ge, fn: ge_126_int8}, + {idx: 5, exp: eq, fn: eq_126_int8}, + {idx: 5, exp: ne, fn: ne_126_int8}, + {idx: 6, exp: lt, fn: lt_127_int8}, + {idx: 6, exp: le, fn: le_127_int8}, + {idx: 6, exp: gt, fn: gt_127_int8}, + {idx: 6, exp: ge, fn: ge_127_int8}, + {idx: 6, exp: eq, fn: eq_127_int8}, + {idx: 6, exp: ne, fn: ne_127_int8}, +} + +func main() { + for i, test := range uint64_tests { + for j, x := range uint64_vals { + want := test.exp.l + if j == test.idx { + want = test.exp.e + } else if j > test.idx { + want = test.exp.r + } + if test.fn(x) != want { + fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name() + msg := fmt.Sprintf("test failed: %v(%v) != %v [type=uint64 i=%v j=%v idx=%v]", fn, x, want, i, j, test.idx) + panic(msg) + } + } + } + for i, test := range uint32_tests { + for j, x := range uint32_vals { + want := test.exp.l + if j == test.idx { + want = test.exp.e + } else if j > test.idx { + want = test.exp.r + } + if test.fn(x) != want { + fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name() + msg := fmt.Sprintf("test failed: %v(%v) != %v [type=uint32 i=%v j=%v idx=%v]", fn, x, want, i, j, test.idx) + panic(msg) + } + } + } + for i, test := range uint16_tests { + for j, x := range uint16_vals { + want := test.exp.l + if j == test.idx { + want = test.exp.e + } else if j > test.idx { + want = test.exp.r + } + if test.fn(x) != want { + fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name() + msg := fmt.Sprintf("test failed: %v(%v) != %v [type=uint16 i=%v j=%v idx=%v]", fn, x, want, i, j, test.idx) + panic(msg) + } + } + } + for i, test := range uint8_tests { + for j, x := range uint8_vals { + want := test.exp.l + if j == test.idx { + want = test.exp.e + } else if j > test.idx { + want = test.exp.r + } + if test.fn(x) != want { + fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name() + msg := fmt.Sprintf("test failed: %v(%v) != %v [type=uint8 i=%v j=%v idx=%v]", fn, x, want, i, j, test.idx) + panic(msg) + } + } + } + for i, test := range int64_tests { + for j, x := range int64_vals { + want := test.exp.l + if j == test.idx { + want = test.exp.e + } else if j > test.idx { + want = test.exp.r + } + if test.fn(x) != want { + fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name() + msg := fmt.Sprintf("test failed: %v(%v) != %v [type=int64 i=%v j=%v idx=%v]", fn, x, want, i, j, test.idx) + panic(msg) + } + } + } + for i, test := range int32_tests { + for j, x := range int32_vals { + want := test.exp.l + if j == test.idx { + want = test.exp.e + } else if j > test.idx { + want = test.exp.r + } + if test.fn(x) != want { + fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name() + msg := fmt.Sprintf("test failed: %v(%v) != %v [type=int32 i=%v j=%v idx=%v]", fn, x, want, i, j, test.idx) + panic(msg) + } + } + } + for i, test := range int16_tests { + for j, x := range int16_vals { + want := test.exp.l + if j == test.idx { + want = test.exp.e + } else if j > test.idx { + want = test.exp.r + } + if test.fn(x) != want { + fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name() + msg := fmt.Sprintf("test failed: %v(%v) != %v [type=int16 i=%v j=%v idx=%v]", fn, x, want, i, j, test.idx) + panic(msg) + } + } + } + for i, test := range int8_tests { + for j, x := range int8_vals { + want := test.exp.l + if j == test.idx { + want = test.exp.e + } else if j > test.idx { + want = test.exp.r + } + if test.fn(x) != want { + fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name() + msg := fmt.Sprintf("test failed: %v(%v) != %v [type=int8 i=%v j=%v idx=%v]", fn, x, want, i, j, test.idx) + panic(msg) + } + } + } +} diff --git a/src/cmd/compile/internal/gc/testdata/gen/cmpConstGen.go b/src/cmd/compile/internal/gc/testdata/gen/cmpConstGen.go new file mode 100644 index 0000000000..defa4a9f7b --- /dev/null +++ b/src/cmd/compile/internal/gc/testdata/gen/cmpConstGen.go @@ -0,0 +1,248 @@ +// Copyright 2017 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. + +// This program generates a test to verify that the standard comparison +// operators properly handle one const operand. The test file should be +// generated with a known working version of go. +// launch with `go run cmpConstGen.go` a file called cmpConst.go +// will be written into the parent directory containing the tests + +package main + +import ( + "bytes" + "fmt" + "go/format" + "io/ioutil" + "log" + "math/big" + "sort" +) + +const ( + maxU64 = (1 << 64) - 1 + maxU32 = (1 << 32) - 1 + maxU16 = (1 << 16) - 1 + maxU8 = (1 << 8) - 1 + + maxI64 = (1 << 63) - 1 + maxI32 = (1 << 31) - 1 + maxI16 = (1 << 15) - 1 + maxI8 = (1 << 7) - 1 + + minI64 = -(1 << 63) + minI32 = -(1 << 31) + minI16 = -(1 << 15) + minI8 = -(1 << 7) +) + +func cmp(left *big.Int, op string, right *big.Int) bool { + switch left.Cmp(right) { + case -1: // less than + return op == "<" || op == "<=" || op == "!=" + case 0: // equal + return op == "==" || op == "<=" || op == ">=" + case 1: // greater than + return op == ">" || op == ">=" || op == "!=" + } + panic("unexpected comparison value") +} + +func inRange(typ string, val *big.Int) bool { + min, max := &big.Int{}, &big.Int{} + switch typ { + case "uint64": + max = max.SetUint64(maxU64) + case "uint32": + max = max.SetUint64(maxU32) + case "uint16": + max = max.SetUint64(maxU16) + case "uint8": + max = max.SetUint64(maxU8) + case "int64": + min = min.SetInt64(minI64) + max = max.SetInt64(maxI64) + case "int32": + min = min.SetInt64(minI32) + max = max.SetInt64(maxI32) + case "int16": + min = min.SetInt64(minI16) + max = max.SetInt64(maxI16) + case "int8": + min = min.SetInt64(minI8) + max = max.SetInt64(maxI8) + default: + panic("unexpected type") + } + return cmp(min, "<=", val) && cmp(val, "<=", max) +} + +func getValues(typ string) []*big.Int { + Uint := func(v uint64) *big.Int { return big.NewInt(0).SetUint64(v) } + Int := func(v int64) *big.Int { return big.NewInt(0).SetInt64(v) } + values := []*big.Int{ + // limits + Uint(maxU64), + Uint(maxU64 - 1), + Uint(maxI64 + 1), + Uint(maxI64), + Uint(maxI64 - 1), + Uint(maxU32 + 1), + Uint(maxU32), + Uint(maxU32 - 1), + Uint(maxI32 + 1), + Uint(maxI32), + Uint(maxI32 - 1), + Uint(maxU16 + 1), + Uint(maxU16), + Uint(maxU16 - 1), + Uint(maxI16 + 1), + Uint(maxI16), + Uint(maxI16 - 1), + Uint(maxU8 + 1), + Uint(maxU8), + Uint(maxU8 - 1), + Uint(maxI8 + 1), + Uint(maxI8), + Uint(maxI8 - 1), + Uint(0), + Int(minI8 + 1), + Int(minI8), + Int(minI8 - 1), + Int(minI16 + 1), + Int(minI16), + Int(minI16 - 1), + Int(minI32 + 1), + Int(minI32), + Int(minI32 - 1), + Int(minI64 + 1), + Int(minI64), + + // other possibly interesting values + Uint(1), + Int(-1), + Uint(0xff << 56), + Uint(0xff << 32), + Uint(0xff << 24), + } + sort.Slice(values, func(i, j int) bool { return values[i].Cmp(values[j]) == -1 }) + var ret []*big.Int + for _, val := range values { + if !inRange(typ, val) { + continue + } + ret = append(ret, val) + } + return ret +} + +func sigString(v *big.Int) string { + var t big.Int + t.Abs(v) + if v.Sign() == -1 { + return "neg" + t.String() + } + return t.String() +} + +func main() { + types := []string{ + "uint64", "uint32", "uint16", "uint8", + "int64", "int32", "int16", "int8", + } + + w := new(bytes.Buffer) + fmt.Fprintf(w, "// run\n") + fmt.Fprintf(w, "// Code generated by gen/cmpConstGen.go. DO NOT EDIT.\n\n") + fmt.Fprintf(w, "package main;\n") + fmt.Fprintf(w, "import (\"fmt\"; \"reflect\"; \"runtime\";)\n") + fmt.Fprintf(w, "// results show the expected result for the elements left of, equal to and right of the index.\n") + fmt.Fprintf(w, "type result struct{l, e, r bool}\n") + fmt.Fprintf(w, "var (\n") + fmt.Fprintf(w, " eq = result{l: false, e: true, r: false}\n") + fmt.Fprintf(w, " ne = result{l: true, e: false, r: true}\n") + fmt.Fprintf(w, " lt = result{l: true, e: false, r: false}\n") + fmt.Fprintf(w, " le = result{l: true, e: true, r: false}\n") + fmt.Fprintf(w, " gt = result{l: false, e: false, r: true}\n") + fmt.Fprintf(w, " ge = result{l: false, e: true, r: true}\n") + fmt.Fprintf(w, ")\n") + + operators := []struct{ op, name string }{ + {"<", "lt"}, + {"<=", "le"}, + {">", "gt"}, + {">=", "ge"}, + {"==", "eq"}, + {"!=", "ne"}, + } + + for _, typ := range types { + // generate a slice containing valid values for this type + fmt.Fprintf(w, "\n// %v tests\n", typ) + values := getValues(typ) + fmt.Fprintf(w, "var %v_vals = []%v{\n", typ, typ) + for _, val := range values { + fmt.Fprintf(w, "%v,\n", val.String()) + } + fmt.Fprintf(w, "}\n") + + // generate test functions + for _, r := range values { + // TODO: could also test constant on lhs. + sig := sigString(r) + for _, op := range operators { + // no need for go:noinline because the function is called indirectly + fmt.Fprintf(w, "func %v_%v_%v(x %v) bool { return x %v %v; }\n", op.name, sig, typ, typ, op.op, r.String()) + } + } + + // generate a table of test cases + fmt.Fprintf(w, "var %v_tests = []struct{\n", typ) + fmt.Fprintf(w, " idx int // index of the constant used\n") + fmt.Fprintf(w, " exp result // expected results\n") + fmt.Fprintf(w, " fn func(%v) bool\n", typ) + fmt.Fprintf(w, "}{\n") + for i, r := range values { + sig := sigString(r) + for _, op := range operators { + fmt.Fprintf(w, "{idx: %v,", i) + fmt.Fprintf(w, "exp: %v,", op.name) + fmt.Fprintf(w, "fn: %v_%v_%v},\n", op.name, sig, typ) + } + } + fmt.Fprintf(w, "}\n") + } + + // emit the main function, looping over all test cases + fmt.Fprintf(w, "func main() {\n") + for _, typ := range types { + fmt.Fprintf(w, "for i, test := range %v_tests {\n", typ) + fmt.Fprintf(w, " for j, x := range %v_vals {\n", typ) + fmt.Fprintf(w, " want := test.exp.l\n") + fmt.Fprintf(w, " if j == test.idx {\nwant = test.exp.e\n}") + fmt.Fprintf(w, " else if j > test.idx {\nwant = test.exp.r\n}\n") + fmt.Fprintf(w, " if test.fn(x) != want {\n") + fmt.Fprintf(w, " fn := runtime.FuncForPC(reflect.ValueOf(test.fn).Pointer()).Name()\n") + fmt.Fprintf(w, " msg := fmt.Sprintf(\"test failed: %%v(%%v) != %%v [type=%v i=%%v j=%%v idx=%%v]\", fn, x, want, i, j, test.idx)\n", typ) + fmt.Fprintf(w, " panic(msg)\n") + fmt.Fprintf(w, " }\n") + fmt.Fprintf(w, " }\n") + fmt.Fprintf(w, "}\n") + } + fmt.Fprintf(w, "}\n") + + // gofmt result + b := w.Bytes() + src, err := format.Source(b) + if err != nil { + fmt.Printf("%s\n", b) + panic(err) + } + + // write to file + err = ioutil.WriteFile("../cmpConst.go", src, 0666) + if err != nil { + log.Fatalf("can't write output: %v\n", err) + } +} diff --git a/src/cmd/compile/internal/ssa/gen/S390X.rules b/src/cmd/compile/internal/ssa/gen/S390X.rules index 7ecea02dae..caea0506fa 100644 --- a/src/cmd/compile/internal/ssa/gen/S390X.rules +++ b/src/cmd/compile/internal/ssa/gen/S390X.rules @@ -537,8 +537,8 @@ (CMP (MOVDconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPconst x [c])) (CMPW x (MOVDconst [c])) -> (CMPWconst x [c]) (CMPW (MOVDconst [c]) x) -> (InvertFlags (CMPWconst x [c])) -(CMPU x (MOVDconst [c])) && is32Bit(c) -> (CMPUconst x [int64(uint32(c))]) -(CMPU (MOVDconst [c]) x) && is32Bit(c) -> (InvertFlags (CMPUconst x [int64(uint32(c))])) +(CMPU x (MOVDconst [c])) && isU32Bit(c) -> (CMPUconst x [int64(uint32(c))]) +(CMPU (MOVDconst [c]) x) && isU32Bit(c) -> (InvertFlags (CMPUconst x [int64(uint32(c))])) (CMPWU x (MOVDconst [c])) -> (CMPWUconst x [int64(uint32(c))]) (CMPWU (MOVDconst [c]) x) -> (InvertFlags (CMPWUconst x [int64(uint32(c))])) diff --git a/src/cmd/compile/internal/ssa/rewriteS390X.go b/src/cmd/compile/internal/ssa/rewriteS390X.go index 866cf50041..af8fd1d456 100644 --- a/src/cmd/compile/internal/ssa/rewriteS390X.go +++ b/src/cmd/compile/internal/ssa/rewriteS390X.go @@ -6784,7 +6784,7 @@ func rewriteValueS390X_OpS390XCMPU(v *Value, config *Config) bool { b := v.Block _ = b // match: (CMPU x (MOVDconst [c])) - // cond: is32Bit(c) + // cond: isU32Bit(c) // result: (CMPUconst x [int64(uint32(c))]) for { x := v.Args[0] @@ -6793,7 +6793,7 @@ func rewriteValueS390X_OpS390XCMPU(v *Value, config *Config) bool { break } c := v_1.AuxInt - if !(is32Bit(c)) { + if !(isU32Bit(c)) { break } v.reset(OpS390XCMPUconst) @@ -6802,7 +6802,7 @@ func rewriteValueS390X_OpS390XCMPU(v *Value, config *Config) bool { return true } // match: (CMPU (MOVDconst [c]) x) - // cond: is32Bit(c) + // cond: isU32Bit(c) // result: (InvertFlags (CMPUconst x [int64(uint32(c))])) for { v_0 := v.Args[0] @@ -6811,7 +6811,7 @@ func rewriteValueS390X_OpS390XCMPU(v *Value, config *Config) bool { } c := v_0.AuxInt x := v.Args[1] - if !(is32Bit(c)) { + if !(isU32Bit(c)) { break } v.reset(OpS390XInvertFlags) -- cgit v1.2.3-54-g00ecf From f55bc1c4ebea3feffed484b7fa8cddb4cd07c1c3 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Tue, 23 May 2017 20:12:26 +0000 Subject: [release-branch.go1.8] net/http: update bundled http2 for gracefulShutdownCh lock contention slowdown This updates the bundled x/net/http2 repo to git rev 186fd3fc (from the net repo's release-branch.go1.8) for: [release-branch.go1.8] http2: fix lock contention slowdown due to gracefulShutdownCh https://golang.org/cl/43459 Fixes #20302 Change-Id: Ia01a44c6749292de9c16ca330bdebe1e52458b18 Reviewed-on: https://go-review.googlesource.com/43996 Run-TryBot: Brad Fitzpatrick Reviewed-by: Chris Broadfoot TryBot-Result: Gobot Gobot --- src/net/http/h2_bundle.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index 4536b2ff5d..e473bb2a13 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -1,4 +1,4 @@ -// Code generated by golang.org/x/tools/cmd/bundle. +// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT. //go:generate bundle -o h2_bundle.go -prefix http2 -underscore golang.org/x/net/http2 // Package http2 implements the HTTP/2 protocol. @@ -3536,9 +3536,13 @@ func (sc *http2serverConn) serve() { sc.idleTimerCh = sc.idleTimer.C } - var gracefulShutdownCh <-chan struct{} + var gracefulShutdownCh chan struct{} if sc.hs != nil { - gracefulShutdownCh = http2h1ServerShutdownChan(sc.hs) + ch := http2h1ServerShutdownChan(sc.hs) + if ch != nil { + gracefulShutdownCh = make(chan struct{}) + go sc.awaitGracefulShutdown(ch, gracefulShutdownCh) + } } go sc.readFrames() @@ -3587,6 +3591,14 @@ func (sc *http2serverConn) serve() { } } +func (sc *http2serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) { + select { + case <-sc.doneServing: + case <-sharedCh: + close(privateCh) + } +} + // readPreface reads the ClientPreface greeting from the peer // or returns an error on timeout or an invalid greeting. func (sc *http2serverConn) readPreface() error { @@ -6003,7 +6015,6 @@ func http2commaSeparatedTrailers(req *Request) (string, error) { } if len(keys) > 0 { sort.Strings(keys) - return strings.Join(keys, ","), nil } return "", nil -- cgit v1.2.3-54-g00ecf From 195e20a9768468d580231e62e37e6fb0525ed20e Mon Sep 17 00:00:00 2001 From: Todd Neal Date: Mon, 24 Apr 2017 11:20:09 -0400 Subject: [release-branch.go1.8] cmd/compile: ignore types when considering tuple select for CSE Fixes #20097 Change-Id: I3c9626ccc8cd0c46a7081ea8650b2ff07a5d4fcd Reviewed-on: https://go-review.googlesource.com/41505 Run-TryBot: Todd Neal TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall Reviewed-on: https://go-review.googlesource.com/43997 Run-TryBot: Chris Broadfoot Reviewed-by: Brad Fitzpatrick --- src/cmd/compile/internal/ssa/cse.go | 10 +++++++--- test/fixedbugs/issue20097.go | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 test/fixedbugs/issue20097.go diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go index 4e07c89b88..9ab18d89e9 100644 --- a/src/cmd/compile/internal/ssa/cse.go +++ b/src/cmd/compile/internal/ssa/cse.go @@ -313,9 +313,13 @@ func cmpVal(v, w *Value, auxIDs auxmap) Cmp { // that generate memory. return lt2Cmp(v.ID < w.ID) } - - if tc := v.Type.Compare(w.Type); tc != CMPeq { - return tc + // OpSelect is a pseudo-op. We need to be more agressive + // regarding CSE to keep multiple OpSelect's of the same + // argument from existing. + if v.Op != OpSelect0 && v.Op != OpSelect1 { + if tc := v.Type.Compare(w.Type); tc != CMPeq { + return tc + } } if v.Aux != w.Aux { diff --git a/test/fixedbugs/issue20097.go b/test/fixedbugs/issue20097.go new file mode 100644 index 0000000000..236a1bd40a --- /dev/null +++ b/test/fixedbugs/issue20097.go @@ -0,0 +1,18 @@ +// compile + +// Copyright 2017 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. + +// Issue 20097: ensure that we CSE multiple Select ops with +// the same underlying type + +package main + +type T int64 + +func f(x, y int64) (int64, T) { + a := x / y + b := T(x) / T(y) + return a, b +} -- cgit v1.2.3-54-g00ecf From 958c64bbabfea5888913a5e3fdb371f79f45d2b9 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 18 May 2017 16:56:48 -0400 Subject: [release-branch.go1.8] runtime: use pselect6 for usleep on linux/amd64 and linux/arm Android O black-lists the select system call because its libc, Bionic, does not use this system call. Replace our use of select with pselect6 (which is allowed) on the platforms that support targeting Android. linux/arm64 already uses pselect6 because there is no select on arm64, so only linux/amd64 and linux/arm need changing. pselect6 has been available since Linux 2.6.16, which is before Go's minimum requirement. Fixes #20409. Change-Id: Ic526b5b259a9e01d2f145a1f4d2e76e8c49ce809 Reviewed-on: https://go-review.googlesource.com/43641 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick Reviewed-by: Ian Lance Taylor (cherry picked from commit 4dcba023c62d7f7968abc54fa5d38d2bf11412ba) Reviewed-on: https://go-review.googlesource.com/44001 Run-TryBot: Brad Fitzpatrick Reviewed-by: Chris Broadfoot --- src/runtime/sys_linux_amd64.s | 9 ++++++--- src/runtime/sys_linux_arm.s | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s index 6ddcb30ae2..8ab8d12d0f 100644 --- a/src/runtime/sys_linux_amd64.s +++ b/src/runtime/sys_linux_amd64.s @@ -82,15 +82,18 @@ TEXT runtime·usleep(SB),NOSPLIT,$16 MOVL $1000000, CX DIVL CX MOVQ AX, 0(SP) - MOVQ DX, 8(SP) + MOVL $1000, AX // usec to nsec + MULL DX + MOVQ AX, 8(SP) - // select(0, 0, 0, 0, &tv) + // pselect6(0, 0, 0, 0, &ts, 0) MOVL $0, DI MOVL $0, SI MOVL $0, DX MOVL $0, R10 MOVQ SP, R8 - MOVL $23, AX + MOVL $0, R9 + MOVL $270, AX SYSCALL RET diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s index 666b879f02..f21a351c05 100644 --- a/src/runtime/sys_linux_arm.s +++ b/src/runtime/sys_linux_arm.s @@ -36,7 +36,7 @@ #define SYS_gettid (SYS_BASE + 224) #define SYS_tkill (SYS_BASE + 238) #define SYS_sched_yield (SYS_BASE + 158) -#define SYS_select (SYS_BASE + 142) // newselect +#define SYS_pselect6 (SYS_BASE + 335) #define SYS_ugetrlimit (SYS_BASE + 191) #define SYS_sched_getaffinity (SYS_BASE + 242) #define SYS_clock_gettime (SYS_BASE + 263) @@ -387,13 +387,16 @@ TEXT runtime·usleep(SB),NOSPLIT,$12 MOVW usec+0(FP), R0 CALL runtime·usplitR0(SB) MOVW R0, 4(R13) + MOVW $1000, R0 // usec to nsec + MUL R0, R1 MOVW R1, 8(R13) MOVW $0, R0 MOVW $0, R1 MOVW $0, R2 MOVW $0, R3 MOVW $4(R13), R4 - MOVW $SYS_select, R7 + MOVW $0, R5 + MOVW $SYS_pselect6, R7 SWI $0 RET -- cgit v1.2.3-54-g00ecf From daf6706f374f7895bbabf812c1ffa08516cadf82 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Tue, 23 May 2017 17:54:24 -0400 Subject: [release-branch.go1.8] runtime: use pselect6 for usleep on linux/386 Commit 4dcba023c6 replaced select with pselect6 on linux/amd64 and linux/arm, but it turns out the Android emulator uses linux/386. This makes the equivalent change there, too. Fixes #20409 more. Change-Id: If542d6ade06309aab8758d5f5f6edec201ca7670 Reviewed-on: https://go-review.googlesource.com/44011 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick Reviewed-by: Ian Lance Taylor (cherry picked from commit ecad34a40ea390ddf5ba2da8f3c3f2c5f15297c8) Reviewed-on: https://go-review.googlesource.com/44002 Run-TryBot: Brad Fitzpatrick Reviewed-by: Chris Broadfoot --- src/runtime/sys_linux_386.s | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s index 45320c068a..ba6f7cc8dd 100644 --- a/src/runtime/sys_linux_386.s +++ b/src/runtime/sys_linux_386.s @@ -98,15 +98,18 @@ TEXT runtime·usleep(SB),NOSPLIT,$8 MOVL $1000000, CX DIVL CX MOVL AX, 0(SP) + MOVL $1000, AX // usec to nsec + MULL DX MOVL DX, 4(SP) - // select(0, 0, 0, 0, &tv) - MOVL $142, AX + // pselect6(0, 0, 0, 0, &ts, 0) + MOVL $308, AX MOVL $0, BX MOVL $0, CX MOVL $0, DX MOVL $0, SI LEAL 0(SP), DI + MOVL $0, BP INVOKE_SYSCALL RET -- cgit v1.2.3-54-g00ecf From e396667ba31b971a892bf48229071aed93da1499 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 23 May 2017 15:19:27 -0700 Subject: [release-branch.go1.8] cmd/compile: zero ambiguously live variables at VARKILLs This is a redo of CL 41076 backported to the 1.8 release branch. There were major conflicts, so I had to basically rewrite it again from scratch. The way Progs are allocated changed. Liveness analysis and Prog generation got reordered. Liveness analysis changed from running on gc.BasicBlock to ssa.Block. All that makes the logic quite a bit different. Please review carefully. From CL 41076: At VARKILLs, zero a variable if it is ambiguously live. After the VARKILL anything this variable references might be collected. If it were to become live again later, the GC will see references to already-collected objects. We don't know a variable is ambiguously live until very late in compilation (after lowering, register allocation, ...), so it is hard to generate the code in an arch-independent way. We also have to be careful not to clobber any registers. Fortunately, this almost never happens so performance is ~irrelevant. There are only 2 instances where this triggers in the stdlib. Fixes #20029 Change-Id: Ibb757eec58ee07f40df5e561b19d315684dc4bda Reviewed-on: https://go-review.googlesource.com/43998 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/amd64/galign.go | 1 + src/cmd/compile/internal/amd64/ggen.go | 21 ++++++++++++++++++++ src/cmd/compile/internal/arm/galign.go | 1 + src/cmd/compile/internal/arm/ggen.go | 21 ++++++++++++++++++++ src/cmd/compile/internal/arm64/galign.go | 1 + src/cmd/compile/internal/arm64/ggen.go | 17 ++++++++++++++++ src/cmd/compile/internal/gc/go.go | 6 ++++++ src/cmd/compile/internal/gc/gsubr.go | 9 +++++++++ src/cmd/compile/internal/gc/pgen.go | 23 ++++++++++++++++++++++ src/cmd/compile/internal/mips/galign.go | 1 + src/cmd/compile/internal/mips/ggen.go | 17 ++++++++++++++++ src/cmd/compile/internal/mips64/galign.go | 1 + src/cmd/compile/internal/mips64/ggen.go | 17 ++++++++++++++++ src/cmd/compile/internal/ppc64/galign.go | 1 + src/cmd/compile/internal/ppc64/ggen.go | 17 ++++++++++++++++ src/cmd/compile/internal/s390x/galign.go | 1 + src/cmd/compile/internal/s390x/ggen.go | 13 +++++++++++++ src/cmd/compile/internal/x86/galign.go | 1 + src/cmd/compile/internal/x86/ggen.go | 17 ++++++++++++++++ test/fixedbugs/issue20029.go | 32 +++++++++++++++++++++++++++++++ 20 files changed, 218 insertions(+) create mode 100644 test/fixedbugs/issue20029.go diff --git a/src/cmd/compile/internal/amd64/galign.go b/src/cmd/compile/internal/amd64/galign.go index bb3830bca5..6fd7f31617 100644 --- a/src/cmd/compile/internal/amd64/galign.go +++ b/src/cmd/compile/internal/amd64/galign.go @@ -27,4 +27,5 @@ func Init() { gc.Thearch.SSAMarkMoves = ssaMarkMoves gc.Thearch.SSAGenValue = ssaGenValue gc.Thearch.SSAGenBlock = ssaGenBlock + gc.Thearch.ZeroAuto = zeroAuto } diff --git a/src/cmd/compile/internal/amd64/ggen.go b/src/cmd/compile/internal/amd64/ggen.go index c137b52d80..d12153383e 100644 --- a/src/cmd/compile/internal/amd64/ggen.go +++ b/src/cmd/compile/internal/amd64/ggen.go @@ -166,6 +166,27 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32, x0 *uin return p } +func zeroAuto(n *gc.Node, pp *obj.Prog) { + // Note: this code must not clobber any registers. + op := x86.AMOVQ + if gc.Widthptr == 4 { + op = x86.AMOVL + } + sym := gc.Linksym(n.Sym) + size := n.Type.Size() + for i := int64(0); i < size; i += int64(gc.Widthptr) { + p := gc.AddAsmAfter(op, pp) + pp = p + p.From.Type = obj.TYPE_CONST + p.From.Offset = 0 + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_AUTO + p.To.Reg = x86.REG_SP + p.To.Offset = n.Xoffset + i + p.To.Sym = sym + } +} + func ginsnop() { // This is actually not the x86 NOP anymore, // but at the point where it gets used, AX is dead diff --git a/src/cmd/compile/internal/arm/galign.go b/src/cmd/compile/internal/arm/galign.go index 308b016026..53f57cd978 100644 --- a/src/cmd/compile/internal/arm/galign.go +++ b/src/cmd/compile/internal/arm/galign.go @@ -21,4 +21,5 @@ func Init() { gc.Thearch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {} gc.Thearch.SSAGenValue = ssaGenValue gc.Thearch.SSAGenBlock = ssaGenBlock + gc.Thearch.ZeroAuto = zeroAuto } diff --git a/src/cmd/compile/internal/arm/ggen.go b/src/cmd/compile/internal/arm/ggen.go index 6dce0a4e80..1b97a4d0c9 100644 --- a/src/cmd/compile/internal/arm/ggen.go +++ b/src/cmd/compile/internal/arm/ggen.go @@ -92,6 +92,27 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, r0 *uint32) *obj.Pr return p } +func zeroAuto(n *gc.Node, pp *obj.Prog) { + // Note: this code must not clobber any registers. + sym := gc.Linksym(n.Sym) + size := n.Type.Size() + p := gc.Prog(arm.AMOVW) + p.From.Type = obj.TYPE_CONST + p.From.Offset = 0 + p.To.Type = obj.TYPE_REG + p.To.Reg = arm.REGTMP + for i := int64(0); i < size; i += 4 { + p := gc.AddAsmAfter(arm.AMOVW, pp) + pp = p + p.From.Type = obj.TYPE_REG + p.From.Reg = arm.REGTMP + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_AUTO + p.To.Reg = arm.REGSP + p.To.Offset = n.Xoffset + i + p.To.Sym = sym + } +} func ginsnop() { p := gc.Prog(arm.AAND) diff --git a/src/cmd/compile/internal/arm64/galign.go b/src/cmd/compile/internal/arm64/galign.go index 20a67e398d..15680dd168 100644 --- a/src/cmd/compile/internal/arm64/galign.go +++ b/src/cmd/compile/internal/arm64/galign.go @@ -21,4 +21,5 @@ func Init() { gc.Thearch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {} gc.Thearch.SSAGenValue = ssaGenValue gc.Thearch.SSAGenBlock = ssaGenBlock + gc.Thearch.ZeroAuto = zeroAuto } diff --git a/src/cmd/compile/internal/arm64/ggen.go b/src/cmd/compile/internal/arm64/ggen.go index 16813b642a..83966a4933 100644 --- a/src/cmd/compile/internal/arm64/ggen.go +++ b/src/cmd/compile/internal/arm64/ggen.go @@ -103,6 +103,23 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { return p } +func zeroAuto(n *gc.Node, pp *obj.Prog) { + // Note: this code must not clobber any registers. + sym := gc.Linksym(n.Sym) + size := n.Type.Size() + for i := int64(0); i < size; i += 8 { + p := gc.AddAsmAfter(arm64.AMOVD, pp) + pp = p + p.From.Type = obj.TYPE_REG + p.From.Reg = arm64.REGZERO + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_AUTO + p.To.Reg = arm64.REGSP + p.To.Offset = n.Xoffset + i + p.To.Sym = sym + } +} + func ginsnop() { p := gc.Prog(arm64.AHINT) p.From.Type = obj.TYPE_CONST diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go index ff33e9c1c4..a529ca40f7 100644 --- a/src/cmd/compile/internal/gc/go.go +++ b/src/cmd/compile/internal/gc/go.go @@ -361,6 +361,12 @@ type Arch struct { // SSAGenBlock emits end-of-block Progs. SSAGenValue should be called // for all values in the block before SSAGenBlock. SSAGenBlock func(s *SSAGenState, b, next *ssa.Block) + + // ZeroAuto emits code to zero the given auto stack variable. + // Code is added immediately after pp. + // ZeroAuto must not use any non-temporary registers. + // ZeroAuto will only be called for variables which contain a pointer. + ZeroAuto func(n *Node, pp *obj.Prog) } var pcloc int32 diff --git a/src/cmd/compile/internal/gc/gsubr.go b/src/cmd/compile/internal/gc/gsubr.go index 1e8636347a..2a8bedff96 100644 --- a/src/cmd/compile/internal/gc/gsubr.go +++ b/src/cmd/compile/internal/gc/gsubr.go @@ -72,6 +72,15 @@ func Appendpp(p *obj.Prog, as obj.As, ftype obj.AddrType, freg int16, foffset in return q } +func AddAsmAfter(as obj.As, p *obj.Prog) *obj.Prog { + q := Ctxt.NewProg() + Clearp(q) + q.As = as + q.Link = p.Link + p.Link = q + return q +} + func ggloblnod(nam *Node) { s := Linksym(nam.Sym) s.Gotype = Linksym(ngotype(nam)) diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 643ba79d63..dde28f670b 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -120,7 +120,30 @@ func Gvarlive(n *Node) { } func removevardef(firstp *obj.Prog) { + // At VARKILLs, zero variable if it is ambiguously live. + // After the VARKILL anything this variable references + // might be collected. If it were to become live again later, + // the GC will see references to already-collected objects. + // See issue 20029. for p := firstp; p != nil; p = p.Link { + if p.As != obj.AVARKILL { + continue + } + n := p.To.Node.(*Node) + if !n.Name.Needzero { + continue + } + if n.Class != PAUTO { + Fatalf("zero of variable which isn't PAUTO %v", n) + } + if n.Type.Size()%int64(Widthptr) != 0 { + Fatalf("zero of variable not a multiple of ptr size %v", n) + } + Thearch.ZeroAuto(n, p) + } + + for p := firstp; p != nil; p = p.Link { + for p.Link != nil && (p.Link.As == obj.AVARDEF || p.Link.As == obj.AVARKILL || p.Link.As == obj.AVARLIVE) { p.Link = p.Link.Link } diff --git a/src/cmd/compile/internal/mips/galign.go b/src/cmd/compile/internal/mips/galign.go index 39f5d2bf64..e6d117a806 100644 --- a/src/cmd/compile/internal/mips/galign.go +++ b/src/cmd/compile/internal/mips/galign.go @@ -23,4 +23,5 @@ func Init() { gc.Thearch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {} gc.Thearch.SSAGenValue = ssaGenValue gc.Thearch.SSAGenBlock = ssaGenBlock + gc.Thearch.ZeroAuto = zeroAuto } diff --git a/src/cmd/compile/internal/mips/ggen.go b/src/cmd/compile/internal/mips/ggen.go index ec540f8102..a95db57ffe 100644 --- a/src/cmd/compile/internal/mips/ggen.go +++ b/src/cmd/compile/internal/mips/ggen.go @@ -92,6 +92,23 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { return p } +func zeroAuto(n *gc.Node, pp *obj.Prog) { + // Note: this code must not clobber any registers. + sym := gc.Linksym(n.Sym) + size := n.Type.Size() + for i := int64(0); i < size; i += 4 { + p := gc.AddAsmAfter(mips.AMOVW, pp) + pp = p + p.From.Type = obj.TYPE_REG + p.From.Reg = mips.REGZERO + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_AUTO + p.To.Reg = mips.REGSP + p.To.Offset = n.Xoffset + i + p.To.Sym = sym + } +} + func ginsnop() { p := gc.Prog(mips.ANOR) p.From.Type = obj.TYPE_REG diff --git a/src/cmd/compile/internal/mips64/galign.go b/src/cmd/compile/internal/mips64/galign.go index 4a36a4ce5b..e8ea073057 100644 --- a/src/cmd/compile/internal/mips64/galign.go +++ b/src/cmd/compile/internal/mips64/galign.go @@ -25,4 +25,5 @@ func Init() { gc.Thearch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {} gc.Thearch.SSAGenValue = ssaGenValue gc.Thearch.SSAGenBlock = ssaGenBlock + gc.Thearch.ZeroAuto = zeroAuto } diff --git a/src/cmd/compile/internal/mips64/ggen.go b/src/cmd/compile/internal/mips64/ggen.go index 2af4a8b1ce..eb48e2b261 100644 --- a/src/cmd/compile/internal/mips64/ggen.go +++ b/src/cmd/compile/internal/mips64/ggen.go @@ -95,6 +95,23 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { return p } +func zeroAuto(n *gc.Node, pp *obj.Prog) { + // Note: this code must not clobber any registers. + sym := gc.Linksym(n.Sym) + size := n.Type.Size() + for i := int64(0); i < size; i += 8 { + p := gc.AddAsmAfter(mips.AMOVV, pp) + pp = p + p.From.Type = obj.TYPE_REG + p.From.Reg = mips.REGZERO + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_AUTO + p.To.Reg = mips.REGSP + p.To.Offset = n.Xoffset + i + p.To.Sym = sym + } +} + func ginsnop() { p := gc.Prog(mips.ANOR) p.From.Type = obj.TYPE_REG diff --git a/src/cmd/compile/internal/ppc64/galign.go b/src/cmd/compile/internal/ppc64/galign.go index 186aa2946a..3780247731 100644 --- a/src/cmd/compile/internal/ppc64/galign.go +++ b/src/cmd/compile/internal/ppc64/galign.go @@ -24,6 +24,7 @@ func Init() { gc.Thearch.SSAMarkMoves = ssaMarkMoves gc.Thearch.SSAGenValue = ssaGenValue gc.Thearch.SSAGenBlock = ssaGenBlock + gc.Thearch.ZeroAuto = zeroAuto initvariants() initproginfo() diff --git a/src/cmd/compile/internal/ppc64/ggen.go b/src/cmd/compile/internal/ppc64/ggen.go index b3ce968567..4abd18dc3d 100644 --- a/src/cmd/compile/internal/ppc64/ggen.go +++ b/src/cmd/compile/internal/ppc64/ggen.go @@ -90,6 +90,23 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { return p } +func zeroAuto(n *gc.Node, pp *obj.Prog) { + // Note: this code must not clobber any registers. + sym := gc.Linksym(n.Sym) + size := n.Type.Size() + for i := int64(0); i < size; i += 8 { + p := gc.AddAsmAfter(ppc64.AMOVD, pp) + pp = p + p.From.Type = obj.TYPE_REG + p.From.Reg = ppc64.REGZERO + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_AUTO + p.To.Reg = ppc64.REGSP + p.To.Offset = n.Xoffset + i + p.To.Sym = sym + } +} + func ginsnop() { p := gc.Prog(ppc64.AOR) p.From.Type = obj.TYPE_REG diff --git a/src/cmd/compile/internal/s390x/galign.go b/src/cmd/compile/internal/s390x/galign.go index 91b9ed0777..9424d204fa 100644 --- a/src/cmd/compile/internal/s390x/galign.go +++ b/src/cmd/compile/internal/s390x/galign.go @@ -20,4 +20,5 @@ func Init() { gc.Thearch.SSAMarkMoves = ssaMarkMoves gc.Thearch.SSAGenValue = ssaGenValue gc.Thearch.SSAGenBlock = ssaGenBlock + gc.Thearch.ZeroAuto = zeroAuto } diff --git a/src/cmd/compile/internal/s390x/ggen.go b/src/cmd/compile/internal/s390x/ggen.go index 15c65546d6..5ecfaa5177 100644 --- a/src/cmd/compile/internal/s390x/ggen.go +++ b/src/cmd/compile/internal/s390x/ggen.go @@ -143,6 +143,19 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64) *obj.Prog { return p } +func zeroAuto(n *gc.Node, pp *obj.Prog) { + // Note: this code must not clobber any registers. + p := gc.AddAsmAfter(s390x.ACLEAR, pp) + pp = p + p.From.Type = obj.TYPE_CONST + p.From.Offset = n.Type.Size() + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_AUTO + p.To.Reg = s390x.REGSP + p.To.Offset = n.Xoffset + p.To.Sym = gc.Linksym(n.Sym) +} + func ginsnop() { p := gc.Prog(s390x.AOR) p.From.Type = obj.TYPE_REG diff --git a/src/cmd/compile/internal/x86/galign.go b/src/cmd/compile/internal/x86/galign.go index edac6a002a..bb29d2a02f 100644 --- a/src/cmd/compile/internal/x86/galign.go +++ b/src/cmd/compile/internal/x86/galign.go @@ -31,4 +31,5 @@ func Init() { gc.Thearch.SSAMarkMoves = ssaMarkMoves gc.Thearch.SSAGenValue = ssaGenValue gc.Thearch.SSAGenBlock = ssaGenBlock + gc.Thearch.ZeroAuto = zeroAuto } diff --git a/src/cmd/compile/internal/x86/ggen.go b/src/cmd/compile/internal/x86/ggen.go index 25769b4de0..33ffc5f534 100644 --- a/src/cmd/compile/internal/x86/ggen.go +++ b/src/cmd/compile/internal/x86/ggen.go @@ -84,6 +84,23 @@ func zerorange(p *obj.Prog, frame int64, lo int64, hi int64, ax *uint32) *obj.Pr return p } +func zeroAuto(n *gc.Node, pp *obj.Prog) { + // Note: this code must not clobber any registers. + sym := gc.Linksym(n.Sym) + size := n.Type.Size() + for i := int64(0); i < size; i += 4 { + p := gc.AddAsmAfter(x86.AMOVL, pp) + pp = p + p.From.Type = obj.TYPE_CONST + p.From.Offset = 0 + p.To.Type = obj.TYPE_MEM + p.To.Name = obj.NAME_AUTO + p.To.Reg = x86.REG_SP + p.To.Offset = n.Xoffset + i + p.To.Sym = sym + } +} + func ginsnop() { p := gc.Prog(x86.AXCHGL) p.From.Type = obj.TYPE_REG diff --git a/test/fixedbugs/issue20029.go b/test/fixedbugs/issue20029.go new file mode 100644 index 0000000000..db3f8aa5dd --- /dev/null +++ b/test/fixedbugs/issue20029.go @@ -0,0 +1,32 @@ +// run + +// Copyright 2017 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. + +// Issue 20029: make sure we zero at VARKILLs of +// ambiguously live variables. +// The ambiguously live variable here is the hiter +// for the inner range loop. + +package main + +import "runtime" + +func f(m map[int]int) { +outer: + for i := 0; i < 10; i++ { + for k := range m { + if k == 5 { + continue outer + } + } + runtime.GC() + break + } + runtime.GC() +} +func main() { + m := map[int]int{1: 2, 2: 3, 3: 4} + f(m) +} -- cgit v1.2.3-54-g00ecf From 439c0c8be85f93306460d82ad12b47c56ee53420 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 23 May 2017 22:55:59 -0700 Subject: [release-branch.go1.8] cmd/compile: don't move spills to loop exits where the spill is dead We shouldn't move a spill to a loop exit where the spill itself is dead. The stack location assigned to the spill might already be reused by another spill at this point. The case we previously handled incorrectly is the one where the value being spilled is still live, but the spill itself is dead. Fixes #20472 Patching directly on the release branch because the spill moving code has already been rewritten for 1.9. (And it doesn't have this bug.) Change-Id: I26c5273dafd98d66ec448750073c2b354ef89ad6 Reviewed-on: https://go-review.googlesource.com/44033 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang --- src/cmd/compile/internal/ssa/export_test.go | 16 ++++++- src/cmd/compile/internal/ssa/regalloc.go | 18 ++++++++ src/cmd/compile/internal/ssa/regalloc_test.go | 65 +++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/cmd/compile/internal/ssa/export_test.go b/src/cmd/compile/internal/ssa/export_test.go index ee6ed51d73..80fa92d94b 100644 --- a/src/cmd/compile/internal/ssa/export_test.go +++ b/src/cmd/compile/internal/ssa/export_test.go @@ -35,8 +35,20 @@ type DummyFrontend struct { func (DummyFrontend) StringData(s string) interface{} { return nil } -func (DummyFrontend) Auto(t Type) GCNode { - return nil + +type dummyGCNode struct { + typ Type + name string +} + +func (d *dummyGCNode) Typ() Type { + return d.typ +} +func (d *dummyGCNode) String() string { + return d.name +} +func (d DummyFrontend) Auto(t Type) GCNode { + return &dummyGCNode{typ: t, name: "dummy"} } func (d DummyFrontend) SplitString(s LocalSlot) (LocalSlot, LocalSlot) { return LocalSlot{s.N, d.TypeBytePtr(), s.Off}, LocalSlot{s.N, d.TypeInt(), s.Off + 8} diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index 7bf778609e..90b5947f1c 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -1699,6 +1699,24 @@ sinking: } p := d.Preds[0].b // block in loop exiting to d. + // Check that the spill value is still live at the start of d. + // If it isn't, we can't move the spill here because some other value + // may be using the same stack slot. See issue 20472. + // The spill value can't be defined in d, so that makes our lives easier. + for _, x := range stacklive[d.ID] { + if x == vsp.ID { + goto stillLive + } + } + for _, v := range d.Values { + if v.Op == OpLoadReg && v.Args[0] == vsp { + goto stillLive + } + } + // Spill is not live - abort sinking this spill. + continue sinking + stillLive: + endregs := s.endRegs[p.ID] for _, regrec := range endregs { if regrec.v == e && regrec.r != noRegister && regrec.c == e { // TODO: regrec.c != e implies different spill possible. diff --git a/src/cmd/compile/internal/ssa/regalloc_test.go b/src/cmd/compile/internal/ssa/regalloc_test.go index cf8f452d12..d3d1891bcd 100644 --- a/src/cmd/compile/internal/ssa/regalloc_test.go +++ b/src/cmd/compile/internal/ssa/regalloc_test.go @@ -31,3 +31,68 @@ func TestLiveControlOps(t *testing.T) { regalloc(f.f) checkFunc(f.f) } + +func TestSpillMove(t *testing.T) { + // Test for issue 20472. We shouldn't move a spill out to exit blocks + // if there is an exit block where the spill is dead but the pre-spill + // value is live. + c := testConfig(t) + ptrType := &TypeImpl{Size_: 8, Ptr: true, Name: "testptr"} // dummy for testing + arg1Aux := c.fe.Auto(TypeInt64) + arg2Aux := c.fe.Auto(ptrType) + f := Fun(c, "entry", + Bloc("entry", + Valu("mem", OpInitMem, TypeMem, 0, nil), + Valu("x", OpArg, TypeInt64, 0, arg1Aux), + Valu("p", OpArg, ptrType, 0, arg2Aux), + Valu("a", OpAMD64TESTQ, TypeFlags, 0, nil, "x", "x"), + Goto("loop1"), + ), + Bloc("loop1", + Valu("y", OpAMD64MULQ, TypeInt64, 0, nil, "x", "x"), + Eq("a", "loop2", "exit1"), + ), + Bloc("loop2", + Eq("a", "loop1", "exit2"), + ), + Bloc("exit1", + // store before call, y is available in a register + Valu("mem2", OpAMD64MOVQstore, TypeMem, 0, nil, "p", "y", "mem"), + Valu("mem3", OpAMD64CALLstatic, TypeMem, 0, nil, "mem2"), + Exit("mem3"), + ), + Bloc("exit2", + // store after call, y must be loaded from a spill location + Valu("mem4", OpAMD64CALLstatic, TypeMem, 0, nil, "mem"), + Valu("mem5", OpAMD64MOVQstore, TypeMem, 0, nil, "p", "y", "mem4"), + Exit("mem5"), + ), + ) + flagalloc(f.f) + regalloc(f.f) + checkFunc(f.f) + // There should still be a spill in Loop1, and nowhere else. + if numSpills(f.blocks["loop1"]) != 1 { + t.Errorf("spill missing from loop1") + } + if numSpills(f.blocks["loop2"]) != 0 { + t.Errorf("spill present in loop2") + } + if numSpills(f.blocks["exit1"]) != 0 { + t.Errorf("spill present in exit1") + } + if numSpills(f.blocks["exit2"]) != 0 { + t.Errorf("spill present in exit2") + } + +} + +func numSpills(b *Block) int { + n := 0 + for _, v := range b.Values { + if v.Op == OpStoreReg { + n++ + } + } + return n +} -- cgit v1.2.3-54-g00ecf From bb5055d6f17709e1d3679eba99138c2f53637cb2 Mon Sep 17 00:00:00 2001 From: Chris Broadfoot Date: Wed, 24 May 2017 11:05:04 -0700 Subject: [release-branch.go1.8] doc: document go1.8.3 Change-Id: I5d55c3b1011dd10552d8e740fb65886306d91b5c Reviewed-on: https://go-review.googlesource.com/44035 Reviewed-by: Brad Fitzpatrick Reviewed-on: https://go-review.googlesource.com/44036 --- doc/devel/release.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/devel/release.html b/doc/devel/release.html index 0be3dbbbd9..8999a8f4fd 100644 --- a/doc/devel/release.html +++ b/doc/devel/release.html @@ -56,6 +56,13 @@ See the Go 1.8.2 milestone on our issue tracker for details.

+

+go1.8.3 (released 2017/05/24) includes fixes to the compiler, runtime, +documentation, and the database/sql package. +See the Go +1.8.3 milestone on our issue tracker for details. +

+

go1.7 (released 2016/08/15)

-- cgit v1.2.3-54-g00ecf From 352996a381701cfa0c16e8de29cbde8f3922182f Mon Sep 17 00:00:00 2001 From: Chris Broadfoot Date: Wed, 24 May 2017 11:13:24 -0700 Subject: [release-branch.go1.8] go1.8.3 Change-Id: I048f21f8ca68758fdd7ac875f7db5e4ed1930f3b Reviewed-on: https://go-review.googlesource.com/44037 Reviewed-by: Brad Fitzpatrick --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 68ae0a04eb..3e144cd980 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.8.2 \ No newline at end of file +go1.8.3 \ No newline at end of file -- cgit v1.2.3-54-g00ecf