Change writeBlocks signature to avoid making xxh escape

Thanks to @ongardie for the suggestion.
diff --git a/xxhash.go b/xxhash.go
index f896bd2..a10d135 100644
--- a/xxhash.go
+++ b/xxhash.go
@@ -83,7 +83,8 @@
 
 	if len(b) >= 32 {
 		// One or more full blocks left.
-		b = writeBlocks(x, b)
+		nw := writeBlocks(x, b)
+		b = b[nw:]
 	}
 
 	// Store any remaining partial block.
diff --git a/xxhash_amd64.go b/xxhash_amd64.go
index d617652..52b2686 100644
--- a/xxhash_amd64.go
+++ b/xxhash_amd64.go
@@ -9,4 +9,5 @@
 //go:noescape
 func Sum64(b []byte) uint64
 
-func writeBlocks(x *xxh, b []byte) []byte
+//go:noescape
+func writeBlocks(x *xxh, b []byte) int
diff --git a/xxhash_amd64.s b/xxhash_amd64.s
index 757f201..d319fa2 100644
--- a/xxhash_amd64.s
+++ b/xxhash_amd64.s
@@ -172,15 +172,14 @@
 // writeBlocks uses the same registers as above except that it uses AX to store
 // the x pointer.
 
-// func writeBlocks(x *xxh, b []byte) []byte
-TEXT ·writeBlocks(SB), NOSPLIT, $0-56
+// func writeBlocks(x *xxh, b []byte) int
+TEXT ·writeBlocks(SB), NOSPLIT, $0-40
 	// Load fixed primes needed for round.
 	MOVQ ·prime1v(SB), R13
 	MOVQ ·prime2v(SB), R14
 
 	// Load slice.
 	MOVQ b_base+8(FP), CX
-	MOVQ CX, ret_base+32(FP) // initialize return base pointer; see NOTE below
 	MOVQ b_len+16(FP), DX
 	LEAQ (CX)(DX*1), BX
 	SUBQ $32, BX
@@ -209,25 +208,8 @@
 	MOVQ R10, 16(AX)
 	MOVQ R11, 24(AX)
 
-	// Construct return slice.
-	// NOTE: It's important that we don't construct a slice that has a base
-	// pointer off the end of the original slice, as in Go 1.7+ this will
-	// cause runtime crashes. (See discussion in, for example,
-	// https://github.com/golang/go/issues/16772.)
-	// Therefore, we calculate the length/cap first, and if they're zero, we
-	// keep the old base. This is what the compiler does as well if you
-	// write code like
-	//   b = b[len(b):]
-
-	// New length is 32 - (CX - BX) -> BX+32 - CX.
-	ADDQ $32, BX
-	SUBQ CX, BX
-	JZ   afterSetBase
-
-	MOVQ CX, ret_base+32(FP)
-
-afterSetBase:
-	MOVQ BX, ret_len+40(FP)
-	MOVQ BX, ret_cap+48(FP) // set cap == len
+	// The number of bytes written is CX minus the old base pointer.
+	SUBQ b_base+8(FP), CX
+	MOVQ CX, ret+32(FP)
 
 	RET
diff --git a/xxhash_other.go b/xxhash_other.go
index c68d13f..b16806f 100644
--- a/xxhash_other.go
+++ b/xxhash_other.go
@@ -61,8 +61,9 @@
 	return h
 }
 
-func writeBlocks(x *xxh, b []byte) []byte {
+func writeBlocks(x *xxh, b []byte) int {
 	v1, v2, v3, v4 := x.v1, x.v2, x.v3, x.v4
+	n := len(b)
 	for len(b) >= 32 {
 		v1 = round(v1, u64(b[0:8:len(b)]))
 		v2 = round(v2, u64(b[8:16:len(b)]))
@@ -71,5 +72,5 @@
 		b = b[32:len(b):len(b)]
 	}
 	x.v1, x.v2, x.v3, x.v4 = v1, v2, v3, v4
-	return b
+	return n - len(b)
 }