From 65717b2dca2d927a2210696c1fe22c0952f9c139 Mon Sep 17 00:00:00 2001
From: pvoicu
Date: Fri, 18 Aug 2017 03:32:49 -0700
Subject: [PATCH 01/11] [release-branch.go1.9] runtime: fix usleep by correctly
setting nanoseconds parameter for pselect6
Fixes #21518
Change-Id: Idd67e3f0410d0ce991b34dcc0c8f15e0d5c529c9
Reviewed-on: https://go-review.googlesource.com/56891
Run-TryBot: Austin Clements
Reviewed-by: Petrica Voicu
Reviewed-by: Ian Lance Taylor
TryBot-Result: Gobot Gobot
---
src/runtime/sys_linux_386.s | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s
index 60618337dc..a3baebae4a 100644
--- a/src/runtime/sys_linux_386.s
+++ b/src/runtime/sys_linux_386.s
@@ -100,7 +100,7 @@ TEXT runtimeĀ·usleep(SB),NOSPLIT,$8
MOVL AX, 0(SP)
MOVL $1000, AX // usec to nsec
MULL DX
- MOVL DX, 4(SP)
+ MOVL AX, 4(SP)
// pselect6(0, 0, 0, 0, &ts, 0)
MOVL $308, AX
From 5927854f7d2bf10704d80cf28fed2385fc0a7b42 Mon Sep 17 00:00:00 2001
From: Cherry Zhang
Date: Fri, 18 Aug 2017 08:37:58 -0400
Subject: [PATCH 02/11] [release-branch.go1.9] cmd/compile: add rules handling
unsigned div/mod by constant 1<<63
Cherry-pick CL 56890.
Normally 64-bit div/mod is turned into runtime calls on 32-bit
arch, but the front end leaves power-of-two constant division
and hopes the SSA backend turns into a shift or AND. The SSA rule is
(Mod64u n (Const64 [c])) && isPowerOfTwo(c) -> (And64 n (Const64 [c-1]))
But isPowerOfTwo returns true only for positive int64, which leaves
out 1<<63 unhandled. Add a special case for 1<<63.
Fixes #21517.
Change-Id: Ic91f86fd5e035a8bb64b937c15cb1c38fec917d6
Reviewed-on: https://go-review.googlesource.com/57070
Run-TryBot: Cherry Zhang
Reviewed-by: Keith Randall
TryBot-Result: Gobot Gobot
---
.../internal/gc/testdata/arithConst.go | 680 ++++++++++++++++++
.../internal/gc/testdata/gen/arithConstGen.go | 2 +-
.../compile/internal/ssa/gen/generic.rules | 2 +
.../compile/internal/ssa/rewritegeneric.go | 41 ++
4 files changed, 724 insertions(+), 1 deletion(-)
diff --git a/src/cmd/compile/internal/gc/testdata/arithConst.go b/src/cmd/compile/internal/gc/testdata/arithConst.go
index cadea7b3bc..ef42359c4b 100644
--- a/src/cmd/compile/internal/gc/testdata/arithConst.go
+++ b/src/cmd/compile/internal/gc/testdata/arithConst.go
@@ -35,6 +35,16 @@ func add_4294967296_uint64_ssa(a uint64) uint64 {
return 4294967296 + a
}
+//go:noinline
+func add_uint64_9223372036854775808_ssa(a uint64) uint64 {
+ return a + 9223372036854775808
+}
+
+//go:noinline
+func add_9223372036854775808_uint64_ssa(a uint64) uint64 {
+ return 9223372036854775808 + a
+}
+
//go:noinline
func add_uint64_18446744073709551615_ssa(a uint64) uint64 {
return a + 18446744073709551615
@@ -75,6 +85,16 @@ func sub_4294967296_uint64_ssa(a uint64) uint64 {
return 4294967296 - a
}
+//go:noinline
+func sub_uint64_9223372036854775808_ssa(a uint64) uint64 {
+ return a - 9223372036854775808
+}
+
+//go:noinline
+func sub_9223372036854775808_uint64_ssa(a uint64) uint64 {
+ return 9223372036854775808 - a
+}
+
//go:noinline
func sub_uint64_18446744073709551615_ssa(a uint64) uint64 {
return a - 18446744073709551615
@@ -110,6 +130,16 @@ func div_4294967296_uint64_ssa(a uint64) uint64 {
return 4294967296 / a
}
+//go:noinline
+func div_uint64_9223372036854775808_ssa(a uint64) uint64 {
+ return a / 9223372036854775808
+}
+
+//go:noinline
+func div_9223372036854775808_uint64_ssa(a uint64) uint64 {
+ return 9223372036854775808 / a
+}
+
//go:noinline
func div_uint64_18446744073709551615_ssa(a uint64) uint64 {
return a / 18446744073709551615
@@ -150,6 +180,16 @@ func mul_4294967296_uint64_ssa(a uint64) uint64 {
return 4294967296 * a
}
+//go:noinline
+func mul_uint64_9223372036854775808_ssa(a uint64) uint64 {
+ return a * 9223372036854775808
+}
+
+//go:noinline
+func mul_9223372036854775808_uint64_ssa(a uint64) uint64 {
+ return 9223372036854775808 * a
+}
+
//go:noinline
func mul_uint64_18446744073709551615_ssa(a uint64) uint64 {
return a * 18446744073709551615
@@ -190,6 +230,16 @@ func lsh_4294967296_uint64_ssa(a uint64) uint64 {
return 4294967296 << a
}
+//go:noinline
+func lsh_uint64_9223372036854775808_ssa(a uint64) uint64 {
+ return a << uint64(9223372036854775808)
+}
+
+//go:noinline
+func lsh_9223372036854775808_uint64_ssa(a uint64) uint64 {
+ return 9223372036854775808 << a
+}
+
//go:noinline
func lsh_uint64_18446744073709551615_ssa(a uint64) uint64 {
return a << uint64(18446744073709551615)
@@ -230,6 +280,16 @@ func rsh_4294967296_uint64_ssa(a uint64) uint64 {
return 4294967296 >> a
}
+//go:noinline
+func rsh_uint64_9223372036854775808_ssa(a uint64) uint64 {
+ return a >> uint64(9223372036854775808)
+}
+
+//go:noinline
+func rsh_9223372036854775808_uint64_ssa(a uint64) uint64 {
+ return 9223372036854775808 >> a
+}
+
//go:noinline
func rsh_uint64_18446744073709551615_ssa(a uint64) uint64 {
return a >> uint64(18446744073709551615)
@@ -265,6 +325,16 @@ func mod_4294967296_uint64_ssa(a uint64) uint64 {
return 4294967296 % a
}
+//go:noinline
+func mod_uint64_9223372036854775808_ssa(a uint64) uint64 {
+ return a % 9223372036854775808
+}
+
+//go:noinline
+func mod_9223372036854775808_uint64_ssa(a uint64) uint64 {
+ return 9223372036854775808 % a
+}
+
//go:noinline
func mod_uint64_18446744073709551615_ssa(a uint64) uint64 {
return a % 18446744073709551615
@@ -2319,6 +2389,16 @@ func main() {
failed = true
}
+ if got := add_0_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("add_uint64 0%s9223372036854775808 = %d, wanted 9223372036854775808\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_0_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("add_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `+`, got)
+ failed = true
+ }
+
if got := add_0_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
fmt.Printf("add_uint64 0%s18446744073709551615 = %d, wanted 18446744073709551615\n", `+`, got)
failed = true
@@ -2359,6 +2439,16 @@ func main() {
failed = true
}
+ if got := add_1_uint64_ssa(9223372036854775808); got != 9223372036854775809 {
+ fmt.Printf("add_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775809\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_1_ssa(9223372036854775808); got != 9223372036854775809 {
+ fmt.Printf("add_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775809\n", `+`, got)
+ failed = true
+ }
+
if got := add_1_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("add_uint64 1%s18446744073709551615 = %d, wanted 0\n", `+`, got)
failed = true
@@ -2399,6 +2489,16 @@ func main() {
failed = true
}
+ if got := add_4294967296_uint64_ssa(9223372036854775808); got != 9223372041149743104 {
+ fmt.Printf("add_uint64 4294967296%s9223372036854775808 = %d, wanted 9223372041149743104\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_4294967296_ssa(9223372036854775808); got != 9223372041149743104 {
+ fmt.Printf("add_uint64 9223372036854775808%s4294967296 = %d, wanted 9223372041149743104\n", `+`, got)
+ failed = true
+ }
+
if got := add_4294967296_uint64_ssa(18446744073709551615); got != 4294967295 {
fmt.Printf("add_uint64 4294967296%s18446744073709551615 = %d, wanted 4294967295\n", `+`, got)
failed = true
@@ -2409,6 +2509,56 @@ func main() {
failed = true
}
+ if got := add_9223372036854775808_uint64_ssa(0); got != 9223372036854775808 {
+ fmt.Printf("add_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_9223372036854775808_ssa(0); got != 9223372036854775808 {
+ fmt.Printf("add_uint64 0%s9223372036854775808 = %d, wanted 9223372036854775808\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_9223372036854775808_uint64_ssa(1); got != 9223372036854775809 {
+ fmt.Printf("add_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775809\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_9223372036854775808_ssa(1); got != 9223372036854775809 {
+ fmt.Printf("add_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775809\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_9223372036854775808_uint64_ssa(4294967296); got != 9223372041149743104 {
+ fmt.Printf("add_uint64 9223372036854775808%s4294967296 = %d, wanted 9223372041149743104\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_9223372036854775808_ssa(4294967296); got != 9223372041149743104 {
+ fmt.Printf("add_uint64 4294967296%s9223372036854775808 = %d, wanted 9223372041149743104\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_9223372036854775808_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("add_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_9223372036854775808_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("add_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_9223372036854775808_uint64_ssa(18446744073709551615); got != 9223372036854775807 {
+ fmt.Printf("add_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775807\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_9223372036854775808_ssa(18446744073709551615); got != 9223372036854775807 {
+ fmt.Printf("add_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775807\n", `+`, got)
+ failed = true
+ }
+
if got := add_18446744073709551615_uint64_ssa(0); got != 18446744073709551615 {
fmt.Printf("add_uint64 18446744073709551615%s0 = %d, wanted 18446744073709551615\n", `+`, got)
failed = true
@@ -2439,6 +2589,16 @@ func main() {
failed = true
}
+ if got := add_18446744073709551615_uint64_ssa(9223372036854775808); got != 9223372036854775807 {
+ fmt.Printf("add_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775807\n", `+`, got)
+ failed = true
+ }
+
+ if got := add_uint64_18446744073709551615_ssa(9223372036854775808); got != 9223372036854775807 {
+ fmt.Printf("add_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775807\n", `+`, got)
+ failed = true
+ }
+
if got := add_18446744073709551615_uint64_ssa(18446744073709551615); got != 18446744073709551614 {
fmt.Printf("add_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 18446744073709551614\n", `+`, got)
failed = true
@@ -2479,6 +2639,16 @@ func main() {
failed = true
}
+ if got := sub_0_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("sub_uint64 0%s9223372036854775808 = %d, wanted 9223372036854775808\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_0_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("sub_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `-`, got)
+ failed = true
+ }
+
if got := sub_0_uint64_ssa(18446744073709551615); got != 1 {
fmt.Printf("sub_uint64 0%s18446744073709551615 = %d, wanted 1\n", `-`, got)
failed = true
@@ -2519,6 +2689,16 @@ func main() {
failed = true
}
+ if got := sub_1_uint64_ssa(9223372036854775808); got != 9223372036854775809 {
+ fmt.Printf("sub_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775809\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_1_ssa(9223372036854775808); got != 9223372036854775807 {
+ fmt.Printf("sub_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775807\n", `-`, got)
+ failed = true
+ }
+
if got := sub_1_uint64_ssa(18446744073709551615); got != 2 {
fmt.Printf("sub_uint64 1%s18446744073709551615 = %d, wanted 2\n", `-`, got)
failed = true
@@ -2559,6 +2739,16 @@ func main() {
failed = true
}
+ if got := sub_4294967296_uint64_ssa(9223372036854775808); got != 9223372041149743104 {
+ fmt.Printf("sub_uint64 4294967296%s9223372036854775808 = %d, wanted 9223372041149743104\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_4294967296_ssa(9223372036854775808); got != 9223372032559808512 {
+ fmt.Printf("sub_uint64 9223372036854775808%s4294967296 = %d, wanted 9223372032559808512\n", `-`, got)
+ failed = true
+ }
+
if got := sub_4294967296_uint64_ssa(18446744073709551615); got != 4294967297 {
fmt.Printf("sub_uint64 4294967296%s18446744073709551615 = %d, wanted 4294967297\n", `-`, got)
failed = true
@@ -2569,6 +2759,56 @@ func main() {
failed = true
}
+ if got := sub_9223372036854775808_uint64_ssa(0); got != 9223372036854775808 {
+ fmt.Printf("sub_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_9223372036854775808_ssa(0); got != 9223372036854775808 {
+ fmt.Printf("sub_uint64 0%s9223372036854775808 = %d, wanted 9223372036854775808\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_9223372036854775808_uint64_ssa(1); got != 9223372036854775807 {
+ fmt.Printf("sub_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775807\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_9223372036854775808_ssa(1); got != 9223372036854775809 {
+ fmt.Printf("sub_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775809\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_9223372036854775808_uint64_ssa(4294967296); got != 9223372032559808512 {
+ fmt.Printf("sub_uint64 9223372036854775808%s4294967296 = %d, wanted 9223372032559808512\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_9223372036854775808_ssa(4294967296); got != 9223372041149743104 {
+ fmt.Printf("sub_uint64 4294967296%s9223372036854775808 = %d, wanted 9223372041149743104\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_9223372036854775808_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("sub_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_9223372036854775808_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("sub_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_9223372036854775808_uint64_ssa(18446744073709551615); got != 9223372036854775809 {
+ fmt.Printf("sub_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775809\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_9223372036854775808_ssa(18446744073709551615); got != 9223372036854775807 {
+ fmt.Printf("sub_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775807\n", `-`, got)
+ failed = true
+ }
+
if got := sub_18446744073709551615_uint64_ssa(0); got != 18446744073709551615 {
fmt.Printf("sub_uint64 18446744073709551615%s0 = %d, wanted 18446744073709551615\n", `-`, got)
failed = true
@@ -2599,6 +2839,16 @@ func main() {
failed = true
}
+ if got := sub_18446744073709551615_uint64_ssa(9223372036854775808); got != 9223372036854775807 {
+ fmt.Printf("sub_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775807\n", `-`, got)
+ failed = true
+ }
+
+ if got := sub_uint64_18446744073709551615_ssa(9223372036854775808); got != 9223372036854775809 {
+ fmt.Printf("sub_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775809\n", `-`, got)
+ failed = true
+ }
+
if got := sub_18446744073709551615_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("sub_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 0\n", `-`, got)
failed = true
@@ -2619,6 +2869,11 @@ func main() {
failed = true
}
+ if got := div_0_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("div_uint64 0%s9223372036854775808 = %d, wanted 0\n", `/`, got)
+ failed = true
+ }
+
if got := div_0_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("div_uint64 0%s18446744073709551615 = %d, wanted 0\n", `/`, got)
failed = true
@@ -2649,6 +2904,16 @@ func main() {
failed = true
}
+ if got := div_1_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("div_uint64 1%s9223372036854775808 = %d, wanted 0\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_uint64_1_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("div_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775808\n", `/`, got)
+ failed = true
+ }
+
if got := div_1_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("div_uint64 1%s18446744073709551615 = %d, wanted 0\n", `/`, got)
failed = true
@@ -2684,6 +2949,16 @@ func main() {
failed = true
}
+ if got := div_4294967296_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("div_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_uint64_4294967296_ssa(9223372036854775808); got != 2147483648 {
+ fmt.Printf("div_uint64 9223372036854775808%s4294967296 = %d, wanted 2147483648\n", `/`, got)
+ failed = true
+ }
+
if got := div_4294967296_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("div_uint64 4294967296%s18446744073709551615 = %d, wanted 0\n", `/`, got)
failed = true
@@ -2694,6 +2969,51 @@ func main() {
failed = true
}
+ if got := div_uint64_9223372036854775808_ssa(0); got != 0 {
+ fmt.Printf("div_uint64 0%s9223372036854775808 = %d, wanted 0\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_9223372036854775808_uint64_ssa(1); got != 9223372036854775808 {
+ fmt.Printf("div_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775808\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_uint64_9223372036854775808_ssa(1); got != 0 {
+ fmt.Printf("div_uint64 1%s9223372036854775808 = %d, wanted 0\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_9223372036854775808_uint64_ssa(4294967296); got != 2147483648 {
+ fmt.Printf("div_uint64 9223372036854775808%s4294967296 = %d, wanted 2147483648\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_uint64_9223372036854775808_ssa(4294967296); got != 0 {
+ fmt.Printf("div_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_9223372036854775808_uint64_ssa(9223372036854775808); got != 1 {
+ fmt.Printf("div_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 1\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_uint64_9223372036854775808_ssa(9223372036854775808); got != 1 {
+ fmt.Printf("div_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 1\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_9223372036854775808_uint64_ssa(18446744073709551615); got != 0 {
+ fmt.Printf("div_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 0\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_uint64_9223372036854775808_ssa(18446744073709551615); got != 1 {
+ fmt.Printf("div_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 1\n", `/`, got)
+ failed = true
+ }
+
if got := div_uint64_18446744073709551615_ssa(0); got != 0 {
fmt.Printf("div_uint64 0%s18446744073709551615 = %d, wanted 0\n", `/`, got)
failed = true
@@ -2719,6 +3039,16 @@ func main() {
failed = true
}
+ if got := div_18446744073709551615_uint64_ssa(9223372036854775808); got != 1 {
+ fmt.Printf("div_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 1\n", `/`, got)
+ failed = true
+ }
+
+ if got := div_uint64_18446744073709551615_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("div_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 0\n", `/`, got)
+ failed = true
+ }
+
if got := div_18446744073709551615_uint64_ssa(18446744073709551615); got != 1 {
fmt.Printf("div_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 1\n", `/`, got)
failed = true
@@ -2759,6 +3089,16 @@ func main() {
failed = true
}
+ if got := mul_0_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mul_uint64 0%s9223372036854775808 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_0_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mul_uint64 9223372036854775808%s0 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
if got := mul_0_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("mul_uint64 0%s18446744073709551615 = %d, wanted 0\n", `*`, got)
failed = true
@@ -2799,6 +3139,16 @@ func main() {
failed = true
}
+ if got := mul_1_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("mul_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775808\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_1_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("mul_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775808\n", `*`, got)
+ failed = true
+ }
+
if got := mul_1_uint64_ssa(18446744073709551615); got != 18446744073709551615 {
fmt.Printf("mul_uint64 1%s18446744073709551615 = %d, wanted 18446744073709551615\n", `*`, got)
failed = true
@@ -2839,6 +3189,16 @@ func main() {
failed = true
}
+ if got := mul_4294967296_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mul_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_4294967296_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mul_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
if got := mul_4294967296_uint64_ssa(18446744073709551615); got != 18446744069414584320 {
fmt.Printf("mul_uint64 4294967296%s18446744073709551615 = %d, wanted 18446744069414584320\n", `*`, got)
failed = true
@@ -2849,6 +3209,56 @@ func main() {
failed = true
}
+ if got := mul_9223372036854775808_uint64_ssa(0); got != 0 {
+ fmt.Printf("mul_uint64 9223372036854775808%s0 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_9223372036854775808_ssa(0); got != 0 {
+ fmt.Printf("mul_uint64 0%s9223372036854775808 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_9223372036854775808_uint64_ssa(1); got != 9223372036854775808 {
+ fmt.Printf("mul_uint64 9223372036854775808%s1 = %d, wanted 9223372036854775808\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_9223372036854775808_ssa(1); got != 9223372036854775808 {
+ fmt.Printf("mul_uint64 1%s9223372036854775808 = %d, wanted 9223372036854775808\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_9223372036854775808_uint64_ssa(4294967296); got != 0 {
+ fmt.Printf("mul_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_9223372036854775808_ssa(4294967296); got != 0 {
+ fmt.Printf("mul_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_9223372036854775808_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mul_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_9223372036854775808_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mul_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_9223372036854775808_uint64_ssa(18446744073709551615); got != 9223372036854775808 {
+ fmt.Printf("mul_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775808\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_9223372036854775808_ssa(18446744073709551615); got != 9223372036854775808 {
+ fmt.Printf("mul_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775808\n", `*`, got)
+ failed = true
+ }
+
if got := mul_18446744073709551615_uint64_ssa(0); got != 0 {
fmt.Printf("mul_uint64 18446744073709551615%s0 = %d, wanted 0\n", `*`, got)
failed = true
@@ -2879,6 +3289,16 @@ func main() {
failed = true
}
+ if got := mul_18446744073709551615_uint64_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("mul_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775808\n", `*`, got)
+ failed = true
+ }
+
+ if got := mul_uint64_18446744073709551615_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("mul_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775808\n", `*`, got)
+ failed = true
+ }
+
if got := mul_18446744073709551615_uint64_ssa(18446744073709551615); got != 1 {
fmt.Printf("mul_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 1\n", `*`, got)
failed = true
@@ -2919,6 +3339,16 @@ func main() {
failed = true
}
+ if got := lsh_0_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 0%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_0_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `<<`, got)
+ failed = true
+ }
+
if got := lsh_0_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("lsh_uint64 0%s18446744073709551615 = %d, wanted 0\n", `<<`, got)
failed = true
@@ -2959,6 +3389,16 @@ func main() {
failed = true
}
+ if got := lsh_1_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 1%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_1_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s1 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
if got := lsh_1_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("lsh_uint64 1%s18446744073709551615 = %d, wanted 0\n", `<<`, got)
failed = true
@@ -2999,6 +3439,16 @@ func main() {
failed = true
}
+ if got := lsh_4294967296_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_4294967296_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
if got := lsh_4294967296_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("lsh_uint64 4294967296%s18446744073709551615 = %d, wanted 0\n", `<<`, got)
failed = true
@@ -3009,6 +3459,56 @@ func main() {
failed = true
}
+ if got := lsh_9223372036854775808_uint64_ssa(0); got != 9223372036854775808 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_9223372036854775808_ssa(0); got != 0 {
+ fmt.Printf("lsh_uint64 0%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_9223372036854775808_uint64_ssa(1); got != 0 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s1 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_9223372036854775808_ssa(1); got != 0 {
+ fmt.Printf("lsh_uint64 1%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_9223372036854775808_uint64_ssa(4294967296); got != 0 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_9223372036854775808_ssa(4294967296); got != 0 {
+ fmt.Printf("lsh_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_9223372036854775808_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_9223372036854775808_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_9223372036854775808_uint64_ssa(18446744073709551615); got != 0 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_9223372036854775808_ssa(18446744073709551615); got != 0 {
+ fmt.Printf("lsh_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
if got := lsh_18446744073709551615_uint64_ssa(0); got != 18446744073709551615 {
fmt.Printf("lsh_uint64 18446744073709551615%s0 = %d, wanted 18446744073709551615\n", `<<`, got)
failed = true
@@ -3039,6 +3539,16 @@ func main() {
failed = true
}
+ if got := lsh_18446744073709551615_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
+ if got := lsh_uint64_18446744073709551615_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("lsh_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 0\n", `<<`, got)
+ failed = true
+ }
+
if got := lsh_18446744073709551615_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("lsh_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 0\n", `<<`, got)
failed = true
@@ -3079,6 +3589,16 @@ func main() {
failed = true
}
+ if got := rsh_0_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("rsh_uint64 0%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_0_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `>>`, got)
+ failed = true
+ }
+
if got := rsh_0_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("rsh_uint64 0%s18446744073709551615 = %d, wanted 0\n", `>>`, got)
failed = true
@@ -3119,6 +3639,16 @@ func main() {
failed = true
}
+ if got := rsh_1_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("rsh_uint64 1%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_1_ssa(9223372036854775808); got != 4611686018427387904 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s1 = %d, wanted 4611686018427387904\n", `>>`, got)
+ failed = true
+ }
+
if got := rsh_1_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("rsh_uint64 1%s18446744073709551615 = %d, wanted 0\n", `>>`, got)
failed = true
@@ -3159,6 +3689,16 @@ func main() {
failed = true
}
+ if got := rsh_4294967296_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("rsh_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_4294967296_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
if got := rsh_4294967296_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("rsh_uint64 4294967296%s18446744073709551615 = %d, wanted 0\n", `>>`, got)
failed = true
@@ -3169,6 +3709,56 @@ func main() {
failed = true
}
+ if got := rsh_9223372036854775808_uint64_ssa(0); got != 9223372036854775808 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s0 = %d, wanted 9223372036854775808\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_9223372036854775808_ssa(0); got != 0 {
+ fmt.Printf("rsh_uint64 0%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_9223372036854775808_uint64_ssa(1); got != 4611686018427387904 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s1 = %d, wanted 4611686018427387904\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_9223372036854775808_ssa(1); got != 0 {
+ fmt.Printf("rsh_uint64 1%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_9223372036854775808_uint64_ssa(4294967296); got != 0 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_9223372036854775808_ssa(4294967296); got != 0 {
+ fmt.Printf("rsh_uint64 4294967296%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_9223372036854775808_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_9223372036854775808_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_9223372036854775808_uint64_ssa(18446744073709551615); got != 0 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_9223372036854775808_ssa(18446744073709551615); got != 0 {
+ fmt.Printf("rsh_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
if got := rsh_18446744073709551615_uint64_ssa(0); got != 18446744073709551615 {
fmt.Printf("rsh_uint64 18446744073709551615%s0 = %d, wanted 18446744073709551615\n", `>>`, got)
failed = true
@@ -3199,6 +3789,16 @@ func main() {
failed = true
}
+ if got := rsh_18446744073709551615_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("rsh_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
+ if got := rsh_uint64_18446744073709551615_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("rsh_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 0\n", `>>`, got)
+ failed = true
+ }
+
if got := rsh_18446744073709551615_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("rsh_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 0\n", `>>`, got)
failed = true
@@ -3219,6 +3819,11 @@ func main() {
failed = true
}
+ if got := mod_0_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mod_uint64 0%s9223372036854775808 = %d, wanted 0\n", `%`, got)
+ failed = true
+ }
+
if got := mod_0_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("mod_uint64 0%s18446744073709551615 = %d, wanted 0\n", `%`, got)
failed = true
@@ -3249,6 +3854,16 @@ func main() {
failed = true
}
+ if got := mod_1_uint64_ssa(9223372036854775808); got != 1 {
+ fmt.Printf("mod_uint64 1%s9223372036854775808 = %d, wanted 1\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_uint64_1_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mod_uint64 9223372036854775808%s1 = %d, wanted 0\n", `%`, got)
+ failed = true
+ }
+
if got := mod_1_uint64_ssa(18446744073709551615); got != 1 {
fmt.Printf("mod_uint64 1%s18446744073709551615 = %d, wanted 1\n", `%`, got)
failed = true
@@ -3284,6 +3899,16 @@ func main() {
failed = true
}
+ if got := mod_4294967296_uint64_ssa(9223372036854775808); got != 4294967296 {
+ fmt.Printf("mod_uint64 4294967296%s9223372036854775808 = %d, wanted 4294967296\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_uint64_4294967296_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mod_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `%`, got)
+ failed = true
+ }
+
if got := mod_4294967296_uint64_ssa(18446744073709551615); got != 4294967296 {
fmt.Printf("mod_uint64 4294967296%s18446744073709551615 = %d, wanted 4294967296\n", `%`, got)
failed = true
@@ -3294,6 +3919,51 @@ func main() {
failed = true
}
+ if got := mod_uint64_9223372036854775808_ssa(0); got != 0 {
+ fmt.Printf("mod_uint64 0%s9223372036854775808 = %d, wanted 0\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_9223372036854775808_uint64_ssa(1); got != 0 {
+ fmt.Printf("mod_uint64 9223372036854775808%s1 = %d, wanted 0\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_uint64_9223372036854775808_ssa(1); got != 1 {
+ fmt.Printf("mod_uint64 1%s9223372036854775808 = %d, wanted 1\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_9223372036854775808_uint64_ssa(4294967296); got != 0 {
+ fmt.Printf("mod_uint64 9223372036854775808%s4294967296 = %d, wanted 0\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_uint64_9223372036854775808_ssa(4294967296); got != 4294967296 {
+ fmt.Printf("mod_uint64 4294967296%s9223372036854775808 = %d, wanted 4294967296\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_9223372036854775808_uint64_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mod_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_uint64_9223372036854775808_ssa(9223372036854775808); got != 0 {
+ fmt.Printf("mod_uint64 9223372036854775808%s9223372036854775808 = %d, wanted 0\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_9223372036854775808_uint64_ssa(18446744073709551615); got != 9223372036854775808 {
+ fmt.Printf("mod_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775808\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_uint64_9223372036854775808_ssa(18446744073709551615); got != 9223372036854775807 {
+ fmt.Printf("mod_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775807\n", `%`, got)
+ failed = true
+ }
+
if got := mod_uint64_18446744073709551615_ssa(0); got != 0 {
fmt.Printf("mod_uint64 0%s18446744073709551615 = %d, wanted 0\n", `%`, got)
failed = true
@@ -3319,6 +3989,16 @@ func main() {
failed = true
}
+ if got := mod_18446744073709551615_uint64_ssa(9223372036854775808); got != 9223372036854775807 {
+ fmt.Printf("mod_uint64 18446744073709551615%s9223372036854775808 = %d, wanted 9223372036854775807\n", `%`, got)
+ failed = true
+ }
+
+ if got := mod_uint64_18446744073709551615_ssa(9223372036854775808); got != 9223372036854775808 {
+ fmt.Printf("mod_uint64 9223372036854775808%s18446744073709551615 = %d, wanted 9223372036854775808\n", `%`, got)
+ failed = true
+ }
+
if got := mod_18446744073709551615_uint64_ssa(18446744073709551615); got != 0 {
fmt.Printf("mod_uint64 18446744073709551615%s18446744073709551615 = %d, wanted 0\n", `%`, got)
failed = true
diff --git a/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go b/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go
index 07a3749b16..ac1c8d93e8 100644
--- a/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go
+++ b/src/cmd/compile/internal/gc/testdata/gen/arithConstGen.go
@@ -31,7 +31,7 @@ type szD struct {
}
var szs = []szD{
- {name: "uint64", sn: "64", u: []uint64{0, 1, 4294967296, 0xffffFFFFffffFFFF}},
+ {name: "uint64", sn: "64", u: []uint64{0, 1, 4294967296, 0x8000000000000000, 0xffffFFFFffffFFFF}},
{name: "int64", sn: "64", i: []int64{-0x8000000000000000, -0x7FFFFFFFFFFFFFFF,
-4294967296, -1, 0, 1, 4294967296, 0x7FFFFFFFFFFFFFFE, 0x7FFFFFFFFFFFFFFF}},
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index b8d7381420..944a84df85 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -945,6 +945,7 @@
(Div16u n (Const16 [c])) && isPowerOfTwo(c&0xffff) -> (Rsh16Ux64 n (Const64 [log2(c&0xffff)]))
(Div32u n (Const32 [c])) && isPowerOfTwo(c&0xffffffff) -> (Rsh32Ux64 n (Const64 [log2(c&0xffffffff)]))
(Div64u n (Const64 [c])) && isPowerOfTwo(c) -> (Rsh64Ux64 n (Const64 [log2(c)]))
+(Div64u n (Const64 [-1<<63])) -> (Rsh64Ux64 n (Const64 [63]))
// Unsigned divide, not a power of 2. Strength reduce to a multiply.
// For 8-bit divides, we just do a direct 9-bit by 8-bit multiply.
@@ -1177,6 +1178,7 @@
(Mod16u n (Const16 [c])) && isPowerOfTwo(c&0xffff) -> (And16 n (Const16 [(c&0xffff)-1]))
(Mod32u n (Const32 [c])) && isPowerOfTwo(c&0xffffffff) -> (And32 n (Const32 [(c&0xffffffff)-1]))
(Mod64u n (Const64 [c])) && isPowerOfTwo(c) -> (And64 n (Const64 [c-1]))
+(Mod64u n (Const64 [-1<<63])) -> (And64 n (Const64 [1<<63-1]))
// Signed mod by negative constant.
(Mod8 n (Const8 [c])) && c < 0 && c != -1<<7 -> (Mod8 n (Const8 [-c]))
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index 95b2c62f07..c67e4f90eb 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -7240,6 +7240,26 @@ func rewriteValuegeneric_OpDiv64u_0(v *Value) bool {
v.AddArg(v0)
return true
}
+ // match: (Div64u n (Const64 [-1<<63]))
+ // cond:
+ // result: (Rsh64Ux64 n (Const64 [63]))
+ for {
+ _ = v.Args[1]
+ n := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
+ break
+ }
+ if v_1.AuxInt != -1<<63 {
+ break
+ }
+ v.reset(OpRsh64Ux64)
+ v.AddArg(n)
+ v0 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
+ v0.AuxInt = 63
+ v.AddArg(v0)
+ return true
+ }
// match: (Div64u x (Const64 [c]))
// cond: umagicOK(64, c) && config.RegSize == 8 && umagic(64,c).m&1 == 0
// result: (Rsh64Ux64 (Hmul64u (Const64 [int64(1<<63+umagic(64,c).m/2)]) x) (Const64 [umagic(64,c).s-1]))
@@ -12061,6 +12081,27 @@ func rewriteValuegeneric_OpMod64u_0(v *Value) bool {
v.AddArg(v0)
return true
}
+ // match: (Mod64u n (Const64 [-1<<63]))
+ // cond:
+ // result: (And64 n (Const64 [1<<63-1]))
+ for {
+ t := v.Type
+ _ = v.Args[1]
+ n := v.Args[0]
+ v_1 := v.Args[1]
+ if v_1.Op != OpConst64 {
+ break
+ }
+ if v_1.AuxInt != -1<<63 {
+ break
+ }
+ v.reset(OpAnd64)
+ v.AddArg(n)
+ v0 := b.NewValue0(v.Pos, OpConst64, t)
+ v0.AuxInt = 1<<63 - 1
+ v.AddArg(v0)
+ return true
+ }
// match: (Mod64u x (Const64 [c]))
// cond: x.Op != OpConst64 && c > 0 && umagicOK(64,c)
// result: (Sub64 x (Mul64 (Div64u x (Const64 [c])) (Const64 [c])))
From 21312a4b5ef42670dfb1d5d38d8a9e4e97cf13a8 Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Fri, 18 Aug 2017 13:26:52 -0700
Subject: [PATCH 03/11] [release-branch.go1.9] cmd/dist: update deps.go for
current dependencies
Fixes #21456
Change-Id: I7841d816e8c1c581e61db4f24124f99f5184fead
Reviewed-on: https://go-review.googlesource.com/57170
Run-TryBot: Ian Lance Taylor
Reviewed-by: Brad Fitzpatrick
---
src/cmd/dist/deps.go | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/cmd/dist/deps.go b/src/cmd/dist/deps.go
index 51dca05685..6e2169d6b6 100644
--- a/src/cmd/dist/deps.go
+++ b/src/cmd/dist/deps.go
@@ -31,8 +31,8 @@ var builddeps = map[string][]string{
"cmd/internal/objabi": {"errors", "flag", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "log", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"compress/flate": {"bufio", "bytes", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "math/bits", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"compress/zlib": {"bufio", "bytes", "compress/flate", "errors", "fmt", "hash", "hash/adler32", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "math/bits", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
- "container/heap": {"errors", "internal/cpu", "internal/race", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "unicode/utf8"},
- "context": {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
+ "container/heap": {"errors", "internal/cpu", "internal/race", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8"},
+ "context": {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"crypto": {"errors", "hash", "internal/cpu", "internal/race", "io", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
"crypto/sha1": {"crypto", "errors", "hash", "internal/cpu", "internal/race", "io", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
"debug/dwarf": {"encoding/binary", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
@@ -40,18 +40,18 @@ var builddeps = map[string][]string{
"debug/macho": {"bytes", "debug/dwarf", "encoding/binary", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"encoding": {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
"encoding/base64": {"errors", "internal/cpu", "internal/race", "io", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
- "encoding/binary": {"errors", "internal/cpu", "internal/race", "io", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
+ "encoding/binary": {"errors", "internal/cpu", "internal/race", "io", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8"},
"encoding/json": {"bytes", "encoding", "encoding/base64", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"encoding/xml": {"bufio", "bytes", "encoding", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"errors": {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
- "flag": {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
- "fmt": {"errors", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
+ "flag": {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
+ "fmt": {"errors", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"go/ast": {"bytes", "errors", "fmt", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"go/build": {"bufio", "bytes", "errors", "fmt", "go/ast", "go/doc", "go/parser", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "log", "math", "net/url", "os", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"go/doc": {"bytes", "errors", "fmt", "go/ast", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "math", "net/url", "os", "path", "path/filepath", "reflect", "regexp", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "text/template", "text/template/parse", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"go/parser": {"bytes", "errors", "fmt", "go/ast", "go/scanner", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "io/ioutil", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"go/scanner": {"bytes", "errors", "fmt", "go/token", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
- "go/token": {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
+ "go/token": {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"hash": {"errors", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic"},
"hash/adler32": {"errors", "hash", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic"},
"internal/cpu": {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
@@ -63,7 +63,7 @@ var builddeps = map[string][]string{
"internal/syscall/windows/sysdll": {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
"io": {"errors", "internal/race", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic"},
"io/ioutil": {"bytes", "errors", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "path/filepath", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
- "log": {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
+ "log": {"errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
"math": {"internal/cpu", "runtime", "runtime/internal/atomic", "runtime/internal/sys"},
"math/bits": {"runtime", "runtime/internal/atomic", "runtime/internal/sys"},
"net/url": {"bytes", "errors", "fmt", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
@@ -72,13 +72,13 @@ var builddeps = map[string][]string{
"os/signal": {"errors", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "os", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "syscall", "time", "unicode/utf16", "unicode/utf8"},
"path": {"errors", "internal/cpu", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strings", "sync", "sync/atomic", "unicode", "unicode/utf8"},
"path/filepath": {"errors", "internal/cpu", "internal/poll", "internal/race", "internal/syscall/windows", "internal/syscall/windows/registry", "internal/syscall/windows/sysdll", "io", "math", "os", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "syscall", "time", "unicode", "unicode/utf16", "unicode/utf8"},
- "reflect": {"errors", "internal/cpu", "internal/race", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
+ "reflect": {"errors", "internal/cpu", "internal/race", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8"},
"regexp": {"bytes", "errors", "internal/cpu", "internal/race", "io", "math", "reflect", "regexp/syntax", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "unicode", "unicode/utf8"},
"regexp/syntax": {"bytes", "errors", "internal/cpu", "internal/race", "io", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sort", "strconv", "strings", "sync", "sync/atomic", "unicode", "unicode/utf8"},
"runtime": {"runtime/internal/atomic", "runtime/internal/sys"},
"runtime/internal/atomic": {"runtime/internal/sys"},
"runtime/internal/sys": {},
- "sort": {"errors", "internal/cpu", "internal/race", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode/utf8"},
+ "sort": {"errors", "internal/cpu", "internal/race", "math", "reflect", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "strconv", "sync", "sync/atomic", "unicode", "unicode/utf8"},
"strconv": {"errors", "internal/cpu", "math", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "unicode/utf8"},
"strings": {"errors", "internal/cpu", "internal/race", "io", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync", "sync/atomic", "unicode", "unicode/utf8"},
"sync": {"internal/race", "runtime", "runtime/internal/atomic", "runtime/internal/sys", "sync/atomic"},
From fbf7e1f2952fba64af0fae32c760cf5011eca53e Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Fri, 18 Aug 2017 12:58:08 -0700
Subject: [PATCH 04/11] [release-branch.go1.9] testing: don't fail all tests
after racy test failure
The code was adding race.Errors to t.raceErrors before checking
Failed, but Failed was using t.raceErrors+race.Errors. We don't want
to change Failed, since that would affect tests themselves, so modify
the harness to not unnecessarily change t.raceErrors.
Updates #19851
Fixes #21338
Change-Id: I483f27c68c340928f1cbdef160abc0a5716efb5d
Reviewed-on: https://go-review.googlesource.com/57151
Run-TryBot: Ian Lance Taylor
TryBot-Result: Gobot Gobot
Reviewed-by: Brad Fitzpatrick
---
src/runtime/race/output_test.go | 21 +++++++++++++++++++++
src/testing/testing.go | 3 +--
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/runtime/race/output_test.go b/src/runtime/race/output_test.go
index e73e6b3bfc..13dfc33b47 100644
--- a/src/runtime/race/output_test.go
+++ b/src/runtime/race/output_test.go
@@ -259,4 +259,25 @@ Goroutine [0-9] \(running\) created at:
runtime\.newextram\(\)
.*/runtime/proc.go:[0-9]+ \+0x[0-9,a-f]+
==================`},
+ {"second_test_passes", "test", "", "atexit_sleep_ms=0", `
+package main_test
+import "testing"
+func TestFail(t *testing.T) {
+ done := make(chan bool)
+ x := 0
+ go func() {
+ x = 42
+ done <- true
+ }()
+ x = 43
+ <-done
+}
+
+func TestPass(t *testing.T) {
+}
+`, `
+==================
+--- FAIL: TestFail \(0...s\)
+.*testing.go:.*: race detected during execution of test
+FAIL`},
}
diff --git a/src/testing/testing.go b/src/testing/testing.go
index 11af926c80..3585af3fc4 100644
--- a/src/testing/testing.go
+++ b/src/testing/testing.go
@@ -695,8 +695,7 @@ func tRunner(t *T, fn func(t *T)) {
// a call to runtime.Goexit, record the duration and send
// a signal saying that the test is done.
defer func() {
- t.raceErrors += race.Errors()
- if t.raceErrors > 0 {
+ if t.raceErrors+race.Errors() > 0 {
t.Errorf("race detected during execution of test")
}
From 42046e89890acf9feb53fa818f293e0b21c20feb Mon Sep 17 00:00:00 2001
From: Austin Clements
Date: Thu, 17 Aug 2017 18:40:07 -0400
Subject: [PATCH 05/11] [release-branch.go1.9] runtime: fix false positive race
in profile label reading
Because profile labels are copied from the goroutine into the tag
buffer by the signal handler, there's a carefully-crafted set of race
detector annotations to create the necessary happens-before edges
between setting a goroutine's profile label and retrieving it from the
profile tag buffer.
Given the constraints of the signal handler, we have to approximate
the true synchronization behavior. Currently, that approximation is
too weak.
Ideally, runtime_setProfLabel would perform a store-release on
&getg().labels and copying each label into the profile would perform a
load-acquire on &getg().labels. This would create the necessary
happens-before edges through each individual g.labels object.
Since we can't do this in the signal handler, we instead synchronize
on a "labelSync" global. The problem occurs with the following
sequence:
1. Goroutine 1 calls setProfLabel, which does a store-release on
labelSync.
2. Goroutine 2 calls setProfLabel, which does a store-release on
labelSync.
3. Goroutine 3 reads the profile, which does a load-acquire on
labelSync.
The problem is that the load-acquire only synchronizes with the *most
recent* store-release to labelSync, and the two store-releases don't
synchronize with each other. So, once goroutine 3 touches the label
set by goroutine 1, we report a race.
The solution is to use racereleasemerge. This is like a
read-modify-write, rather than just a store-release. Each RMW of
labelSync in runtime_setProfLabel synchronizes with the previous RMW
of labelSync, and this ultimately carries forward to the load-acquire,
so it synchronizes with *all* setProfLabel operations, not just the
most recent.
Change-Id: Iab58329b156122002fff12cfe64fbeacb31c9613
Reviewed-on: https://go-review.googlesource.com/57190
Run-TryBot: Austin Clements
Reviewed-by: Ian Lance Taylor
---
src/runtime/pprof/pprof_test.go | 35 +++++++++++++++++++++++++++------
src/runtime/profbuf.go | 2 +-
src/runtime/proflabel.go | 17 +++++++++++++++-
3 files changed, 46 insertions(+), 8 deletions(-)
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
index 992d2abb6a..955964c721 100644
--- a/src/runtime/pprof/pprof_test.go
+++ b/src/runtime/pprof/pprof_test.go
@@ -26,7 +26,7 @@ import (
"time"
)
-func cpuHogger(f func(), dur time.Duration) {
+func cpuHogger(f func() int, dur time.Duration) {
// We only need to get one 100 Hz clock tick, so we've got
// a large safety buffer.
// But do at least 500 iterations (which should take about 100ms),
@@ -46,7 +46,7 @@ var (
// The actual CPU hogging function.
// Must not call other functions nor access heap/globals in the loop,
// otherwise under race detector the samples will be in the race runtime.
-func cpuHog1() {
+func cpuHog1() int {
foo := salt1
for i := 0; i < 1e5; i++ {
if foo > 0 {
@@ -55,10 +55,10 @@ func cpuHog1() {
foo *= foo + 1
}
}
- salt1 = foo
+ return foo
}
-func cpuHog2() {
+func cpuHog2() int {
foo := salt2
for i := 0; i < 1e5; i++ {
if foo > 0 {
@@ -67,7 +67,7 @@ func cpuHog2() {
foo *= foo + 2
}
}
- salt2 = foo
+ return foo
}
func TestCPUProfile(t *testing.T) {
@@ -95,8 +95,9 @@ func TestCPUProfileInlining(t *testing.T) {
})
}
-func inlinedCaller() {
+func inlinedCaller() int {
inlinedCallee()
+ return 0
}
func inlinedCallee() {
@@ -716,6 +717,28 @@ func TestCPUProfileLabel(t *testing.T) {
})
}
+func TestLabelRace(t *testing.T) {
+ // Test the race detector annotations for synchronization
+ // between settings labels and consuming them from the
+ // profile.
+ testCPUProfile(t, []string{"runtime/pprof.cpuHogger;key=value"}, func(dur time.Duration) {
+ start := time.Now()
+ var wg sync.WaitGroup
+ for time.Since(start) < dur {
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ Do(context.Background(), Labels("key", "value"), func(context.Context) {
+ cpuHogger(cpuHog1, time.Millisecond)
+ })
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+ }
+ })
+}
+
// Check that there is no deadlock when the program receives SIGPROF while in
// 64bit atomics' critical section. Used to happen on mips{,le}. See #20146.
func TestAtomicLoadStore64(t *testing.T) {
diff --git a/src/runtime/profbuf.go b/src/runtime/profbuf.go
index 2719238bc1..f40881aed5 100644
--- a/src/runtime/profbuf.go
+++ b/src/runtime/profbuf.go
@@ -545,7 +545,7 @@ Read:
b.rNext = br.addCountsAndClearFlags(skip+di, ti)
if raceenabled {
- // Match racewritepc in runtime_setProfLabel,
+ // Match racereleasemerge in runtime_setProfLabel,
// so that the setting of the labels in runtime_setProfLabel
// is treated as happening before any use of the labels
// by our caller. The synchronization on labelSync itself is a fiction
diff --git a/src/runtime/proflabel.go b/src/runtime/proflabel.go
index 1b41a8a16e..b2a161729e 100644
--- a/src/runtime/proflabel.go
+++ b/src/runtime/proflabel.go
@@ -13,8 +13,23 @@ func runtime_setProfLabel(labels unsafe.Pointer) {
// Introduce race edge for read-back via profile.
// This would more properly use &getg().labels as the sync address,
// but we do the read in a signal handler and can't call the race runtime then.
+ //
+ // This uses racereleasemerge rather than just racerelease so
+ // the acquire in profBuf.read synchronizes with *all* prior
+ // setProfLabel operations, not just the most recent one. This
+ // is important because profBuf.read will observe different
+ // labels set by different setProfLabel operations on
+ // different goroutines, so it needs to synchronize with all
+ // of them (this wouldn't be an issue if we could synchronize
+ // on &getg().labels since we would synchronize with each
+ // most-recent labels write separately.)
+ //
+ // racereleasemerge is like a full read-modify-write on
+ // labelSync, rather than just a store-release, so it carries
+ // a dependency on the previous racereleasemerge, which
+ // ultimately carries forward to the acquire in profBuf.read.
if raceenabled {
- racerelease(unsafe.Pointer(&labelSync))
+ racereleasemerge(unsafe.Pointer(&labelSync))
}
getg().labels = labels
}
From ff38035a62a9cf9e8222016ae15ee52a7ce260dc Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
Date: Sun, 20 Aug 2017 21:29:18 -0700
Subject: [PATCH 06/11] [release-branch.go1.9] doc/go1.9: fix typo in
crypto/x509 of "Minor changes to the library".
Backport of https://golang.org/cl/57390 to 1.9 release branch.
Change-Id: Ieea5a048732db7ee5dc5cf13f06e11ca4f5313cc
Reviewed-on: https://go-review.googlesource.com/57450
Reviewed-by: Keith Randall
---
doc/go1.9.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/go1.9.html b/doc/go1.9.html
index 7cee379c45..3f8d20760e 100644
--- a/doc/go1.9.html
+++ b/doc/go1.9.html
@@ -490,7 +490,7 @@ version of gccgo.
- If any SAN extension, including with no DSN names, is present
+ If any SAN extension, including with no DNS names, is present
in the certificate, then the Common Name from
Subject is ignored.
In previous releases, the code tested only whether DNS-name SANs were
From 9a4e7942ea93d432e29d2567aefccb6acc78ab43 Mon Sep 17 00:00:00 2001
From: Josh Bleecher Snyder
Date: Tue, 8 Aug 2017 16:38:25 -0700
Subject: [PATCH 07/11] [release-branch.go1.9] cmd/compile: remove gc.Sysfunc
calls from 387 backend
[This is a cherry-pick of CL 54090 to the 1.9 release branch.]
gc.Sysfunc must not be called concurrently.
We set up runtime routines used by the backend
prior to doing any backend compilation.
I missed the 387 ones; fix that.
Sysfunc should have been unexported during 1.9.
I will rectify that in a subsequent CL.
Fixes #21352
Change-Id: I485bb1867b46d8e5cf64bc820b8963576dc16174
Reviewed-on: https://go-review.googlesource.com/55970
Run-TryBot: Josh Bleecher Snyder
TryBot-Result: Gobot Gobot
Reviewed-by: Keith Randall
---
src/cmd/compile/internal/gc/go.go | 4 ++++
src/cmd/compile/internal/gc/ssa.go | 4 ++++
src/cmd/compile/internal/x86/387.go | 4 ++--
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 65d8946849..b1ead93c34 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -293,4 +293,8 @@ var (
typedmemmove,
typedmemclr,
Udiv *obj.LSym
+
+ // GO386=387
+ ControlWord64trunc,
+ ControlWord32 *obj.LSym
)
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 1497c5c2f5..9c1b3ca69f 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -92,6 +92,10 @@ func initssaconfig() {
typedmemmove = Sysfunc("typedmemmove")
typedmemclr = Sysfunc("typedmemclr")
Udiv = Sysfunc("udiv")
+
+ // GO386=387 runtime functions
+ ControlWord64trunc = Sysfunc("controlWord64trunc")
+ ControlWord32 = Sysfunc("controlWord32")
}
// buildssa builds an SSA function for fn.
diff --git a/src/cmd/compile/internal/x86/387.go b/src/cmd/compile/internal/x86/387.go
index 5bf14109b2..cdac000648 100644
--- a/src/cmd/compile/internal/x86/387.go
+++ b/src/cmd/compile/internal/x86/387.go
@@ -120,7 +120,7 @@ func ssaGenValue387(s *gc.SSAGenState, v *ssa.Value) {
p = s.Prog(x86.AFLDCW)
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
- p.From.Sym = gc.Sysfunc("controlWord32")
+ p.From.Sym = gc.ControlWord32
}
var op obj.As
@@ -210,7 +210,7 @@ func ssaGenValue387(s *gc.SSAGenState, v *ssa.Value) {
p = s.Prog(x86.AFLDCW)
p.From.Type = obj.TYPE_MEM
p.From.Name = obj.NAME_EXTERN
- p.From.Sym = gc.Sysfunc("controlWord64trunc")
+ p.From.Sym = gc.ControlWord64trunc
// Now do the conversion.
p = s.Prog(x86.AFMOVLP)
From 867be4c60c4468642ae44258f62dd9e2a8269ca1 Mon Sep 17 00:00:00 2001
From: Ryuji IWATA
Date: Sun, 20 Aug 2017 11:03:57 +0900
Subject: [PATCH 08/11] [release-branch.go1.9] doc/go1.9: fix typo in Moved
GOROOT
Change-Id: I71bfff6a3462e6dfd7a65ef76ec56644bae37c34
Reviewed-on: https://go-review.googlesource.com/57272
Reviewed-by: Avelino
Reviewed-by: Ian Lance Taylor
Reviewed-on: https://go-review.googlesource.com/58650
Reviewed-by: Brad Fitzpatrick
---
doc/go1.9.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/go1.9.html b/doc/go1.9.html
index 3f8d20760e..ddea168e4f 100644
--- a/doc/go1.9.html
+++ b/doc/go1.9.html
@@ -163,7 +163,7 @@ type T1 = T2
was invoked to attempt to locate the root of the Go install tree.
This means that if the entire Go installation is moved to a new
location, the go tool should continue to work as usual.
- This may be overriden by setting GOROOT in the environment,
+ This may be overridden by setting GOROOT in the environment,
which should only be done in unusual circumstances.
Note that this does not affect the result of
the runtime.GOROOT function, which
From 136f4a6b2ac2cc5a0c2b2c1ce236392f8f908620 Mon Sep 17 00:00:00 2001
From: Chris Broadfoot
Date: Thu, 24 Aug 2017 11:52:35 -0700
Subject: [PATCH 09/11] [release-branch.go1.9] doc: document go1.9
Change-Id: I97075f24319a4b96cbeb9e3ff2e7b2056ff59e32
Reviewed-on: https://go-review.googlesource.com/58651
Reviewed-by: Brad Fitzpatrick
Reviewed-on: https://go-review.googlesource.com/58710
Reviewed-by: Chris Broadfoot
---
doc/devel/release.html | 9 ++++++++-
doc/go1.9.html | 7 +------
doc/install-source.html | 4 ++--
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/doc/devel/release.html b/doc/devel/release.html
index e4821ff61c..8304522449 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -20,7 +20,14 @@ For example, Go 1.8 is supported until Go 1.10 is released,
and Go 1.9 is supported until Go 1.11 is released.
We fix critical problems, including critical security problems,
in supported releases as needed by issuing minor revisions
-(for example, Go 1.8.1, Go 1.8.2, and so on).
+(for example, Go 1.9.1, Go 1.9.2, and so on).
+
+
+go1.9 (released 2017/08/24)
+
+
+Go 1.9 is a major release of Go.
+Read the Go 1.9 Release Notes for more information.
go1.8 (released 2017/02/16)
diff --git a/doc/go1.9.html b/doc/go1.9.html
index ddea168e4f..ce103cdb9a 100644
--- a/doc/go1.9.html
+++ b/doc/go1.9.html
@@ -15,12 +15,7 @@ Do not send CLs removing the interior tags from such phrases.
ul li { margin: 0.5em 0; }
-DRAFT RELEASE NOTES - Introduction to Go 1.9
-
-
- Go 1.9 is not yet released. These are work-in-progress
- release notes. Go 1.9 is expected to be released in August 2017.
-
+Introduction to Go 1.9
The latest Go release, version 1.9, arrives six months
diff --git a/doc/install-source.html b/doc/install-source.html
index 5d732b053e..d120f7d6f2 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -221,7 +221,7 @@ To build without cgo, set the environment variable
Change to the directory that will be its parent
and make sure the go directory does not exist.
Then clone the repository and check out the latest release tag
-(go1.8.1, for example):
+(go1.9, for example):
$ git clone https://go.googlesource.com/go
@@ -409,7 +409,7 @@ New releases are announced on the
golang-announce
mailing list.
Each announcement mentions the latest release tag, for instance,
-go1.8.1.
+go1.9.
From b8c9ef9f09f213739815745b2ea52c45f2c1a6de Mon Sep 17 00:00:00 2001
From: Chris Broadfoot
Date: Mon, 31 Jul 2017 17:28:35 -0700
Subject: [PATCH 10/11] [release-branch.go1.9] doc: add go1.9 to
golang.org/project
Pre-emptive. Go 1.9 is expected to be released in August.
Change-Id: I0f58c012c4110bf490022dc2c1d69c0988d73bfa
Reviewed-on: https://go-review.googlesource.com/52351
Reviewed-by: Brad Fitzpatrick
Reviewed-on: https://go-review.googlesource.com/58730
Reviewed-by: Chris Broadfoot
---
doc/contrib.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/doc/contrib.html b/doc/contrib.html
index fd548d7c68..0290923bcd 100644
--- a/doc/contrib.html
+++ b/doc/contrib.html
@@ -34,6 +34,7 @@ We encourage all Go users to subscribe to
A summary of the changes between Go releases. Notes for the major releases:
+ - Go 1.9 (August 2017)
- Go 1.8 (February 2017)
- Go 1.7 (August 2016)
- Go 1.6 (February 2016)
From c8aec4095e089ff6ac50d18e97c3f46561f14f48 Mon Sep 17 00:00:00 2001
From: Chris Broadfoot
Date: Thu, 24 Aug 2017 12:57:28 -0700
Subject: [PATCH 11/11] [release-branch.go1.9] go1.9
Change-Id: I0899ec0150f2a051b7572879b446a8548f742ae0
Reviewed-on: https://go-review.googlesource.com/58731
Run-TryBot: Chris Broadfoot
TryBot-Result: Gobot Gobot
Reviewed-by: Brad Fitzpatrick
Reviewed-by: Ian Lance Taylor
---
VERSION | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION b/VERSION
index 0a14d06d2c..f213576692 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.9rc2
\ No newline at end of file
+go1.9
\ No newline at end of file