cmd/compile: []T where T is go:notinheap does not need write barriers

Currently, assigning a []T where T is a go:notinheap type generates an
unnecessary write barrier for storing the slice pointer.

This fixes this by teaching HasHeapPointer that this type does not
have a heap pointer, and tweaking the lowering of slice assignments so
the pointer store retains the correct type rather than simply lowering
it to a *uint8 store.

Change-Id: I8bf7c66e64a7fefdd14f2bd0de8a5a3596340bab
Reviewed-on: https://go-review.googlesource.com/76027
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/test/notinheap3.go b/test/notinheap3.go
index b37d73d..d48c2a0 100644
--- a/test/notinheap3.go
+++ b/test/notinheap3.go
@@ -10,11 +10,13 @@
 
 type t1 struct {
 	x *nih
+	s []nih
 	y [1024]byte // Prevent write decomposition
 }
 
 type t2 struct {
 	x *ih
+	s []ih
 	y [1024]byte
 }
 
@@ -37,8 +39,10 @@
 
 func f() {
 	// Test direct writes
-	v1.x = nil // no barrier
-	v2.x = nil // ERROR "write barrier"
+	v1.x = nil        // no barrier
+	v2.x = nil        // ERROR "write barrier"
+	v1.s = []nih(nil) // no barrier
+	v2.s = []ih(nil)  // ERROR "write barrier"
 }
 
 func g() {