Repository: go
Issue: cmd/compile: treat "d = append(make([]T, 0, len(s)), s...)" as  "d = make([]T, len(s)); copy(d, s)"
Labels: Performance,NeedsFix,compiler/runtime

<!--
Please answer these questions before submitting your issue. Thanks!
For questions please use one of our forums: https://github.com/golang/go/wiki/Questions
-->

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version go1.16.3 linux/amd64
</pre>

### Does this issue reproduce with the latest release?

Yes.

### What did you do?

```Go
package main

import (
	"testing"
)

type T = int

var sMakeCopy128 []T
func Benchmark_MakeCopy_128(b *testing.B) {
	s := make([]T, 128)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		sMakeCopy128 = make([]T, len(s))
		copy(sMakeCopy128, s)
	}
}

var sMakeAppend128 []T
func Benchmark_MakeAppend_128(b *testing.B) {
	s := make([]T, 128)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		sMakeAppend128 = append(make([]T, 0, len(s)), s...)
	}
}

var sMakeCopy1024 []T
func Benchmark_MakeCopy_1024(b *testing.B) {
	s := make([]T, 1024)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		sMakeCopy1024 = make([]T, len(s))
		copy(sMakeCopy1024, s)
	}
}

var sMakeAppend1024 []T
func Benchmark_MakeAppend_1024(b *testing.B) {
	s := make([]T, 1024)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		sMakeAppend1024 = append(make([]T, 0, len(s)), s...)
	}
}

var sMakeCopy8192 []T
func Benchmark_MakeCopy_8192(b *testing.B) {
	s := make([]T, 8192)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		sMakeCopy8192 = make([]T, len(s))
		copy(sMakeCopy8192, s)
	}
}

var sMakeAppend8192 []T
func Benchmark_MakeAppend_8192(b *testing.B) {
	s := make([]T, 8192)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		sMakeAppend8192 = append(make([]T, 0, len(s)), s...)
	}
}

var sMakeCopy65536 []T
func Benchmark_MakeCopy_65536(b *testing.B) {
	s := make([]T, 65536)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		sMakeCopy65536 = make([]T, len(s))
		copy(sMakeCopy65536, s)
	}
}

var sMakeAppend65536 []T
func Benchmark_MakeAppend_65536(b *testing.B) {
	s := make([]T, 65536)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		sMakeAppend65536 = append(make([]T, 0, len(s)), s...)
	}
}
```

### What did you expect to see?

No performance difference between the two ways.

### What did you see instead?

The larger the length of the slices, the bigger performance difference between the two.

```
$ go test -bench=. -benchmem -benchtime=3s
goos: linux
goarch: amd64
pkg: a.b/c/ttt
cpu: Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz
Benchmark_MakeCopy_128-4       	14257712	       254.3 ns/op	    1024 B/op	       1 allocs/op
Benchmark_MakeAppend_128-4     	13141005	       268.5 ns/op	    1024 B/op	       1 allocs/op
Benchmark_MakeCopy_1024-4      	 1885544	      1928 ns/op	    8192 B/op	       1 allocs/op
Benchmark_MakeAppend_1024-4    	 1663520	      2369 ns/op	    8192 B/op	       1 allocs/op
Benchmark_MakeCopy_8192-4      	  268628	     14040 ns/op	   65536 B/op	       1 allocs/op
Benchmark_MakeAppend_8192-4    	  196272	     18757 ns/op	   65536 B/op	       1 allocs/op
Benchmark_MakeCopy_65536-4     	   36700	    100680 ns/op	  524291 B/op	       1 allocs/op
Benchmark_MakeAppend_65536-4   	   24723	    136324 ns/op	  524288 B/op	       1 allocs/op
```

[Edit]: it looks the allocated bytes/op is the not same for the last two benchmarks. Bug or some inaccuracy?