Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/compile: loads combining regression #18946

Closed
ALTree opened this issue Feb 5, 2017 · 11 comments
Closed

cmd/compile: loads combining regression #18946

ALTree opened this issue Feb 5, 2017 · 11 comments
Milestone

Comments

@ALTree
Copy link
Member

ALTree commented Feb 5, 2017

The following code:

package p

func Uint64(b []byte) uint64 {
	_ = b[7]
	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
		uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
}

generates a single load on go1.7.3 and on go1.8rc3:

"".Uint64 t=1 size=52 args=0x20 locals=0x8
	0x0000 00000 (prova.go:3)	TEXT	"".Uint64(SB), $8-32
	0x0000 00000 (prova.go:3)	SUBQ	$8, SP
	0x0004 00004 (prova.go:3)	MOVQ	BP, (SP)
	0x0008 00008 (prova.go:3)	LEAQ	(SP), BP
	0x000c 00012 (prova.go:3)	FUNCDATA	$0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
	0x000c 00012 (prova.go:3)	FUNCDATA	$1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
	0x000c 00012 (prova.go:4)	MOVQ	"".b+24(FP), AX
	0x0011 00017 (prova.go:4)	CMPQ	AX, $7
	0x0015 00021 (prova.go:4)	JLS	$0, 45
	0x0017 00023 (prova.go:6)	MOVQ	"".b+16(FP), AX
	0x001c 00028 (prova.go:6)	MOVQ	(AX), AX
	0x001f 00031 (prova.go:6)	MOVQ	AX, "".~r1+40(FP)
	0x0024 00036 (prova.go:6)	MOVQ	(SP), BP
	0x0028 00040 (prova.go:6)	ADDQ	$8, SP
	0x002c 00044 (prova.go:6)	RET
	0x002d 00045 (prova.go:4)	PCDATA	$0, $1
	0x002d 00045 (prova.go:4)	CALL	runtime.panicindex(SB)
	0x0032 00050 (prova.go:4)	UNDEF

but it doesn't on tip

go version devel +b53f0f8c96 Sat Feb 4 16:46:11 2017 +0000 linux/amd64
"".Uint64 t=1 size=131 args=0x20 locals=0x8
	0x0000 00000 (prova.go:3)	TEXT	"".Uint64(SB), $8-32
	0x0000 00000 (prova.go:3)	SUBQ	$8, SP
	0x0004 00004 (prova.go:3)	MOVQ	BP, (SP)
	0x0008 00008 (prova.go:3)	LEAQ	(SP), BP
	0x000c 00012 (prova.go:3)	FUNCDATA	$0, gclocals·4032f753396f2012ad1784f398b170f4(SB)
	0x000c 00012 (prova.go:3)	FUNCDATA	$1, gclocals·69c1753bd5f81501d95132d08af04464(SB)
	0x000c 00012 (prova.go:4)	MOVQ	"".b+24(FP), AX
	0x0011 00017 (prova.go:4)	CMPQ	AX, $7
	0x0015 00021 (prova.go:4)	JLS	$0, 124
	0x0017 00023 (prova.go:5)	MOVQ	"".b+16(FP), AX
	0x001c 00028 (prova.go:5)	MOVBLZX	(AX), CX
	0x001f 00031 (prova.go:5)	MOVBLZX	1(AX), DX
	0x0023 00035 (prova.go:5)	MOVBLZX	2(AX), BX
	0x0027 00039 (prova.go:5)	MOVBLZX	3(AX), SI
	0x002b 00043 (prova.go:6)	MOVBLZX	4(AX), DI
	0x002f 00047 (prova.go:6)	MOVBLZX	5(AX), R8
	0x0034 00052 (prova.go:6)	MOVBLZX	6(AX), R9
	0x0039 00057 (prova.go:6)	MOVBLZX	7(AX), AX
	0x003d 00061 (prova.go:5)	SHLQ	$8, DX
	0x0041 00065 (prova.go:5)	ORQ	CX, DX
	0x0044 00068 (prova.go:5)	SHLQ	$16, BX
	0x0048 00072 (prova.go:5)	ORQ	DX, BX
	0x004b 00075 (prova.go:5)	SHLQ	$24, SI
	0x004f 00079 (prova.go:5)	ORQ	BX, SI
	0x0052 00082 (prova.go:6)	SHLQ	$32, DI
	0x0056 00086 (prova.go:6)	ORQ	SI, DI
	0x0059 00089 (prova.go:6)	SHLQ	$40, R8
	0x005d 00093 (prova.go:6)	ORQ	DI, R8
	0x0060 00096 (prova.go:6)	SHLQ	$48, R9
	0x0064 00100 (prova.go:6)	ORQ	R8, R9
	0x0067 00103 (prova.go:6)	SHLQ	$56, AX
	0x006b 00107 (prova.go:6)	ORQ	R9, AX
	0x006e 00110 (prova.go:6)	MOVQ	AX, "".~r1+40(FP)
	0x0073 00115 (prova.go:6)	MOVQ	(SP), BP
	0x0077 00119 (prova.go:6)	ADDQ	$8, SP
	0x007b 00123 (prova.go:6)	RET
	0x007c 00124 (prova.go:4)	PCDATA	$0, $1
	0x007c 00124 (prova.go:4)	CALL	runtime.panicindex(SB)
	0x0081 00129 (prova.go:4)	UNDEF

See: #14267

@ALTree
Copy link
Member Author

ALTree commented Feb 5, 2017

For ref:

func BenchmarkUint64(b *testing.B) {
	bs := []byte{1, 2, 3, 5, 4, 1, 2, 3}
	for i := 0; i < b.N; i++ {
		sink = binary.LittleEndian.Uint64(bs)
	}
}

1.8rc3 vs tip

name      old time/op  new time/op  delta
Uint64-4  0.44ns ± 3%  2.12ns ± 1%  +386.04%  (p=0.000 n=20+20)

@rasky
Copy link
Member

rasky commented Feb 5, 2017

Well, there's also a test:
https://github.com/golang/go/blob/master/src/cmd/compile/internal/gc/asm_test.go#L131

but probably the pattern matching being performed at the ASM level is not so strict, and matches also the new slower generated code. /cc @randall77 who added the test :)

@ALTree ALTree added this to the Go1.9 milestone Feb 5, 2017
@josharian
Copy link
Contributor

Bisect to find commit that broke it?

@josharian
Copy link
Contributor

Bisected to https://go-review.googlesource.com/33632

@josharian
Copy link
Contributor

And the test was in fact failing, but it isn't run in -short mode, so no one noticed. See #17472.

TocarIP referenced this issue Feb 7, 2017
CSE opportunities were being missed for commutative ops. We used to
order the args of commutative ops (by arg ID) once at the start of CSE.
But that may not be enough.

i1 = (Load ptr mem)
i2 = (Load ptr mem)
x1 = (Add i1 j)
x2 = (Add i2 j)

Equivalent commutative ops x1 and x2 may not get their args ordered in
the same way because because at the start of CSE, we don't know that
the i values will be CSEd. If x1 and x2 get opposite orders we won't
CSE them.

Instead, (re)order the args of commutative operations by their
equivalence class IDs each time we partition an equivalence class.

Change-Id: Ic609fa83b85299782a5e85bf93dc6023fccf4b0c
Reviewed-on: https://go-review.googlesource.com/33632
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Todd Neal <todd@tneal.org>
@navytux
Copy link
Contributor

navytux commented Feb 7, 2017

Thanks for @TocarIP this was also found here: 6317f92#commitcomment-20779055

@gopherbot
Copy link
Contributor

CL https://golang.org/cl/36911 mentions this issue.

@navytux
Copy link
Contributor

navytux commented Feb 13, 2017

@randall77 thanks for your b548eee fix. It indeed fixes original problem in this issue, but not all TestAssembly failures are gone. I'm not sure whether it is 100% related here but anyway:

kirr@deco:~/src/tools/go/go/src$ go version       # = current tip
go version devel +3792db5183 Mon Feb 13 18:36:28 2017 +0000 linux/amd64
kirr@deco:~/src/tools/go/go/src$ go test ./cmd/compile/internal/...
?       cmd/compile/internal/amd64      [no test files]
?       cmd/compile/internal/arm        [no test files]
?       cmd/compile/internal/arm64      [no test files]
--- FAIL: TestAssembly (40.48s)
        asm_test.go:46: expected:       MOVWZ   \(.*\),
                go:
                import "encoding/binary"
                func f(b []byte) uint32 {
                        return binary.LittleEndian.Uint32(b)
                }

                asm:"".f t=1 size=160 args=0x20 locals=0x0
                        0x0000 00000 (/tmp/TestAssembly558089320/test.go:5)     TEXT    "".f(SB), $8-32
                        0x0000 00000 (/tmp/TestAssembly558089320/test.go:5)     MOVD    16(g), R3
                        0x0006 00006 (/tmp/TestAssembly558089320/test.go:5)     CMPUBGE R3, R15, 144
                        0x000c 00012 (/tmp/TestAssembly558089320/test.go:5)     MOVD    R14, -8(R15)
                        0x0012 00018 (/tmp/TestAssembly558089320/test.go:5)     MOVD    $-8(R15), R15
                        0x0018 00024 (/tmp/TestAssembly558089320/test.go:5)     FUNCDATA        $0, gclocals·667d18600b54358863da70f1a554069a(SB)
                        0x0018 00024 (/tmp/TestAssembly558089320/test.go:5)     FUNCDATA        $1, gclocals·7434ac78ed715a61a5258eadde9d1323(SB)
                        0x0018 00024 (/tmp/TestAssembly558089320/test.go:6)     MOVD    "".b+8(FP), R0
                        0x001e 00030 (/tmp/TestAssembly558089320/test.go:6)     CMPU    R0, $3
                        0x0024 00036 (/tmp/TestAssembly558089320/test.go:6)     MOVD    $0, R0
                        0x0028 00040 (/tmp/TestAssembly558089320/test.go:6)     MOVD    $1, R1
                        0x002c 00044 (/tmp/TestAssembly558089320/test.go:6)     MOVDGT  R1, R0
                        0x0030 00048 (/tmp/TestAssembly558089320/test.go:6)     CMPW    R0, $0
                        0x0034 00052 (/tmp/TestAssembly558089320/test.go:6)     BEQ     134
                        0x0038 00056 (/tmp/TestAssembly558089320/test.go:6)     MOVD    "".b(FP), R1
                        0x003e 00062 (/tmp/TestAssembly558089320/test.go:6)     MOVBZ   (R1), R0
                        0x0044 00068 (/tmp/TestAssembly558089320/test.go:6)     MOVBZ   1(R1), R2
                        0x004a 00074 (/tmp/TestAssembly558089320/test.go:6)     MOVBZ   2(R1), R3
                        0x0050 00080 (/tmp/TestAssembly558089320/test.go:6)     MOVBZ   3(R1), R1
                        0x0056 00086 (/tmp/TestAssembly558089320/test.go:6)     SLW     $8, R2
                        0x005c 00092 (/tmp/TestAssembly558089320/test.go:6)     ORW     R0, R2, R0
                        0x0060 00096 (/tmp/TestAssembly558089320/test.go:6)     SLW     $16, R3, R2
                        0x0066 00102 (/tmp/TestAssembly558089320/test.go:6)     ORW     R0, R2, R0
                        0x006a 00106 (/tmp/TestAssembly558089320/test.go:6)     SLW     $24, R1
                        0x0070 00112 (/tmp/TestAssembly558089320/test.go:6)     ORW     R0, R1, R0
                        0x0074 00116 (/tmp/TestAssembly558089320/test.go:6)     MOVW    R0, "".~r1+24(FP)
                        0x007a 00122 (/tmp/TestAssembly558089320/test.go:6)     MOVD    (R15), R14
                        0x0080 00128 (/tmp/TestAssembly558089320/test.go:6)     ADD     $8, R15
                        0x0084 00132 (/tmp/TestAssembly558089320/test.go:6)     JMP     R14
                        0x0086 00134 (/tmp/TestAssembly558089320/test.go:6)     PCDATA  $0, $1
                        0x0086 00134 (/tmp/TestAssembly558089320/test.go:6)     CALL    runtime.panicindex(SB)
                        0x008c 00140 (/tmp/TestAssembly558089320/test.go:6)     UNDEF
                        0x0090 00144 (/tmp/TestAssembly558089320/test.go:6)     NOP
                        0x0090 00144 (/tmp/TestAssembly558089320/test.go:5)     PCDATA  $0, $-1
                        0x0090 00144 (/tmp/TestAssembly558089320/test.go:5)     MOVD    R14, R5
                        0x0094 00148 (/tmp/TestAssembly558089320/test.go:5)     CALL    runtime.morestack_noctxt(SB)
                        0x009a 00154 (/tmp/TestAssembly558089320/test.go:5)     JMP     0
                        0x0000 e3 30 d0 10 00 04 ec 3f 00 45 a0 65 e3 e0 ff f8  .0.....?.E.e....
                        0x0010 ff 24 e3 ff 0f f8 ff 71 e3 00 f0 18 00 04 c2 0e  .$.....q........
                        0x0020 00 00 00 03 a7 09 00 00 a7 19 00 01 b9 e2 20 01  .............. .
                        0x0030 a7 0e 00 00 a7 84 00 29 e3 10 f0 10 00 04 e3 00  .......)........
                        0x0040 10 00 00 90 e3 20 10 01 00 90 e3 30 10 02 00 90  ..... .....0....
                        0x0050 e3 10 10 03 00 90 eb 22 00 08 00 df b9 f6 20 00  ......."...... .
                        0x0060 eb 23 00 10 00 df b9 f6 20 00 eb 11 00 18 00 df  .#...... .......
                        0x0070 b9 f6 10 00 e3 00 f0 28 00 50 e3 e0 f0 00 00 04  .......(.P......
                        0x0080 a7 fb 00 08 07 fe c0 e5 00 00 00 00 00 00 00 00  ................
                        0x0090 b9 04 00 5e c0 e5 00 00 00 00 a7 f4 ff b3 00 00  ...^............
                        rel 136+4 t=8 runtime.panicindex+6
                        rel 150+4 t=8 runtime.morestack_noctxt+6

        asm_test.go:46: expected:       MOVWZ   \(.*\)\(.*\*1\),
                go:
                import "encoding/binary"
                func f(b []byte, i int) uint32 {
                        return binary.LittleEndian.Uint32(b[i:])
                }

                asm:"".f t=1 size=224 args=0x28 locals=0x0
                        0x0000 00000 (/tmp/TestAssembly558089320/test.go:5)     TEXT    "".f(SB), $8-40
                        0x0000 00000 (/tmp/TestAssembly558089320/test.go:5)     MOVD    16(g), R3
                        0x0006 00006 (/tmp/TestAssembly558089320/test.go:5)     CMPUBGE R3, R15, 208
                        0x000c 00012 (/tmp/TestAssembly558089320/test.go:5)     MOVD    R14, -8(R15)
                        0x0012 00018 (/tmp/TestAssembly558089320/test.go:5)     MOVD    $-8(R15), R15
                        0x0018 00024 (/tmp/TestAssembly558089320/test.go:5)     FUNCDATA        $0, gclocals·3aaa5a9b804cea118cea44ef3a4b227b(SB)
                        0x0018 00024 (/tmp/TestAssembly558089320/test.go:5)     FUNCDATA        $1, gclocals·7434ac78ed715a61a5258eadde9d1323(SB)
                        0x0018 00024 (/tmp/TestAssembly558089320/test.go:6)     MOVD    "".i+24(FP), R0
                        0x001e 00030 (/tmp/TestAssembly558089320/test.go:6)     MOVD    "".b+8(FP), R1
                        0x0024 00036 (/tmp/TestAssembly558089320/test.go:6)     CMPU    R0, R1
                        0x0028 00040 (/tmp/TestAssembly558089320/test.go:6)     MOVD    $0, R2
                        0x002c 00044 (/tmp/TestAssembly558089320/test.go:6)     MOVD    $1, R3
                        0x0030 00048 (/tmp/TestAssembly558089320/test.go:6)     MOVDLE  R3, R2
                        0x0034 00052 (/tmp/TestAssembly558089320/test.go:6)     CMPW    R2, $0
                        0x0038 00056 (/tmp/TestAssembly558089320/test.go:6)     BEQ     198
                        0x003c 00060 (/tmp/TestAssembly558089320/test.go:6)     SUB     R0, R1
                        0x0040 00064 (/tmp/TestAssembly558089320/test.go:6)     CMPU    R1, $3
                        0x0046 00070 (/tmp/TestAssembly558089320/test.go:6)     MOVD    $0, R1
                        0x004a 00074 (/tmp/TestAssembly558089320/test.go:6)     MOVDGT  R3, R1
                        0x004e 00078 (/tmp/TestAssembly558089320/test.go:6)     MOVD    "".b+16(FP), R2
                        0x0054 00084 (/tmp/TestAssembly558089320/test.go:6)     SUB     R0, R2
                        0x0058 00088 (/tmp/TestAssembly558089320/test.go:6)     NEG     R2, R2
                        0x005c 00092 (/tmp/TestAssembly558089320/test.go:6)     SRAD    $63, R2
                        0x0062 00098 (/tmp/TestAssembly558089320/test.go:6)     AND     R2, R0
                        0x0066 00102 (/tmp/TestAssembly558089320/test.go:6)     CMPW    R1, $0
                        0x006a 00106 (/tmp/TestAssembly558089320/test.go:6)     BEQ     188
                        0x006e 00110 (/tmp/TestAssembly558089320/test.go:6)     MOVD    R0, R1
                        0x0072 00114 (/tmp/TestAssembly558089320/test.go:6)     MOVD    "".b(FP), R2
                        0x0078 00120 (/tmp/TestAssembly558089320/test.go:6)     MOVBZ   (R2)(R1*1), R3
                        0x007e 00126 (/tmp/TestAssembly558089320/test.go:6)     MOVBZ   1(R2)(R1*1), R4
                        0x0084 00132 (/tmp/TestAssembly558089320/test.go:6)     MOVBZ   2(R2)(R1*1), R5
                        0x008a 00138 (/tmp/TestAssembly558089320/test.go:6)     MOVBZ   3(R2)(R1*1), R0
                        0x0090 00144 (/tmp/TestAssembly558089320/test.go:6)     SLW     $8, R4, R1
                        0x0096 00150 (/tmp/TestAssembly558089320/test.go:6)     ORW     R3, R1
                        0x0098 00152 (/tmp/TestAssembly558089320/test.go:6)     SLW     $16, R5, R2
                        0x009e 00158 (/tmp/TestAssembly558089320/test.go:6)     ORW     R1, R2, R1
                        0x00a2 00162 (/tmp/TestAssembly558089320/test.go:6)     SLW     $24, R0
                        0x00a8 00168 (/tmp/TestAssembly558089320/test.go:6)     ORW     R1, R0
                        0x00aa 00170 (/tmp/TestAssembly558089320/test.go:6)     MOVW    R0, "".~r2+32(FP)
                        0x00b0 00176 (/tmp/TestAssembly558089320/test.go:6)     MOVD    (R15), R14
                        0x00b6 00182 (/tmp/TestAssembly558089320/test.go:6)     ADD     $8, R15
                        0x00ba 00186 (/tmp/TestAssembly558089320/test.go:6)     JMP     R14
                        0x00bc 00188 (/tmp/TestAssembly558089320/test.go:6)     PCDATA  $0, $1
                        0x00bc 00188 (/tmp/TestAssembly558089320/test.go:6)     CALL    runtime.panicindex(SB)
                        0x00c2 00194 (/tmp/TestAssembly558089320/test.go:6)     UNDEF
                        0x00c6 00198 (/tmp/TestAssembly558089320/test.go:6)     PCDATA  $0, $1
                        0x00c6 00198 (/tmp/TestAssembly558089320/test.go:6)     CALL    runtime.panicslice(SB)
                        0x00cc 00204 (/tmp/TestAssembly558089320/test.go:6)     UNDEF
                        0x00d0 00208 (/tmp/TestAssembly558089320/test.go:6)     NOP
                        0x00d0 00208 (/tmp/TestAssembly558089320/test.go:5)     PCDATA  $0, $-1
                        0x00d0 00208 (/tmp/TestAssembly558089320/test.go:5)     MOVD    R14, R5
                        0x00d4 00212 (/tmp/TestAssembly558089320/test.go:5)     CALL    runtime.morestack_noctxt(SB)
                        0x00da 00218 (/tmp/TestAssembly558089320/test.go:5)     JMP     0
                        0x0000 e3 30 d0 10 00 04 ec 3f 00 65 a0 65 e3 e0 ff f8  .0.....?.e.e....
                        0x0010 ff 24 e3 ff 0f f8 ff 71 e3 00 f0 28 00 04 e3 10  .$.....q...(....
                        0x0020 f0 18 00 04 b9 21 00 01 a7 29 00 00 a7 39 00 01  .....!...)...9..
                        0x0030 b9 e2 c0 23 a7 2e 00 00 a7 84 00 47 b9 09 00 10  ...#.......G....
                        0x0040 c2 1e 00 00 00 03 a7 19 00 00 b9 e2 20 13 e3 20  ............ .. 
                        0x0050 f0 20 00 04 b9 09 00 20 b9 03 00 22 eb 22 00 3f  . ..... ...".".?
                        0x0060 00 0a b9 80 00 02 a7 1e 00 00 a7 84 00 29 b9 04  .............)..
                        0x0070 00 10 e3 20 f0 10 00 04 e3 31 20 00 00 90 e3 41  ... .....1 ....A
                        0x0080 20 01 00 90 e3 51 20 02 00 90 e3 01 20 03 00 90   ....Q ..... ...
                        0x0090 eb 14 00 08 00 df 16 13 eb 25 00 10 00 df b9 f6  .........%......
                        0x00a0 20 11 eb 00 00 18 00 df 16 01 e3 00 f0 30 00 50   ............0.P
                        0x00b0 e3 e0 f0 00 00 04 a7 fb 00 08 07 fe c0 e5 00 00  ................
                        0x00c0 00 00 00 00 00 00 c0 e5 00 00 00 00 00 00 00 00  ................
                        0x00d0 b9 04 00 5e c0 e5 00 00 00 00 a7 f4 ff 93 00 00  ...^............
                        rel 190+4 t=8 runtime.panicindex+6
                        rel 200+4 t=8 runtime.panicslice+6
                        rel 214+4 t=8 runtime.morestack_noctxt+6

...

looks like load-combining rules without bswap are not getting triggerred.

I beg you pardon in advance if this is not related to regression in 6317f92.

@navytux
Copy link
Contributor

navytux commented Feb 13, 2017

This are s390x related. Sorry for the noise.

@gopherbot
Copy link
Contributor

CL https://golang.org/cl/36881 mentions this issue.

@randall77
Copy link
Contributor

The s390x failures are #19059

gopherbot pushed a commit that referenced this issue Feb 13, 2017
It is not always obvious from the first glance when looking at
TestAssembly failure in which context the code was generated. For
example x86 and x86-64 are similar, and those of us who do not work with
assembly every day can even take s390x version as something similar to x86.

So when something fails lets print the whole test context - this
includes os and arch which were previously missing. An example failure:

before:

--- FAIL: TestAssembly (40.48s)
        asm_test.go:46: expected:       MOVWZ   \(.*\),
                go:
                import "encoding/binary"
                func f(b []byte) uint32 {
                        return binary.LittleEndian.Uint32(b)
                }

                asm:"".f t=1 size=160 args=0x20 locals=0x0
		...

after:

--- FAIL: TestAssembly (40.43s)
        asm_test.go:46: linux/s390x: expected:  MOVWZ   \(.*\),
                go:
                import "encoding/binary"
                func f(b []byte) uint32 {
                        return binary.LittleEndian.Uint32(b)
                }

                asm:"".f t=1 size=160 args=0x20 locals=0x0

Motivated-by: #18946#issuecomment-279491071

Change-Id: I61089ceec05da7a165718a7d69dec4227dd0e993
Reviewed-on: https://go-review.googlesource.com/36881
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@golang golang locked and limited conversation to collaborators Feb 13, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants