hash/crc32: fix nil Castagnoli table problem

When SSE is available, we don't need the Table. However, it is
returned as a handle by MakeTable. Fix this to always generate
the table.

Further cleanup is discussed in #16909.

Change-Id: Ic05400d68c6b5d25073ebd962000451746137afc
Reviewed-on: https://go-review.googlesource.com/27934
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/hash/crc32/crc32.go b/src/hash/crc32/crc32.go
index 57089a7..6eed8ff 100644
--- a/src/hash/crc32/crc32.go
+++ b/src/hash/crc32/crc32.go
@@ -57,9 +57,12 @@
 	needGenericTables := castagnoliInitArch()
 
 	if needGenericTables {
-		castagnoliTable = makeTable(Castagnoli)
 		castagnoliTable8 = makeTable8(Castagnoli)
 	}
+
+	// Even if we don't need the contents of this table, we use it as a handle
+	// returned by MakeTable. We should find a way to clean this up (see #16909).
+	castagnoliTable = makeTable(Castagnoli)
 }
 
 // IEEETable is the table for the IEEE polynomial.
diff --git a/src/hash/crc32/crc32_amd64_test.go b/src/hash/crc32/crc32_amd64_test.go
index 8bbaa10..e136f78 100644
--- a/src/hash/crc32/crc32_amd64_test.go
+++ b/src/hash/crc32/crc32_amd64_test.go
@@ -15,11 +15,10 @@
 	}
 
 	// Init the SSE42 tables.
-	MakeTable(Castagnoli)
+	castagnoliOnce.Do(castagnoliInit)
 
-	// Manually init the software implementation to compare against.
-	castagnoliTable = makeTable(Castagnoli)
-	castagnoliTable8 = makeTable8(Castagnoli)
+	// Generate a table to use with the non-SSE version.
+	slicingTable := makeTable8(Castagnoli)
 
 	// The optimized SSE4.2 implementation behaves differently for different
 	// lengths (especially around multiples of K*3). Crosscheck against the
@@ -32,7 +31,7 @@
 					p := make([]byte, length)
 					_, _ = rand.Read(p)
 					crcInit := uint32(rand.Int63())
-					correct := updateSlicingBy8(crcInit, castagnoliTable8, p)
+					correct := updateSlicingBy8(crcInit, slicingTable, p)
 					result := updateCastagnoli(crcInit, p)
 					if result != correct {
 						t.Errorf("SSE42 implementation = 0x%x want 0x%x (buffer length %d)",
diff --git a/src/hash/crc32/crc32_test.go b/src/hash/crc32/crc32_test.go
index 113a109..7f7f0a2 100644
--- a/src/hash/crc32/crc32_test.go
+++ b/src/hash/crc32/crc32_test.go
@@ -51,6 +51,9 @@
 
 func TestGolden(t *testing.T) {
 	castagnoliTab := MakeTable(Castagnoli)
+	if castagnoliTab == nil {
+		t.Errorf("nil Castagnoli Table")
+	}
 
 	for _, g := range golden {
 		ieee := NewIEEE()