cmd/compile: do not reuse dead value in expand_calls pass

We reuse a value for the same selector on the same arg. But if the
value is already marked dead, don't reuse it. A use of an
OpInvalid will confuse the compiler.

Fixes #48916.

Change-Id: I15b9e15b49f6e1991fe91df246cd12a193385e85
Reviewed-on: https://go-review.googlesource.com/c/go/+/355409
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index a0f0e65..18c9ab6 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -1678,7 +1678,7 @@
 		t := v.Type
 		key := selKey{v, 0, t.Size(), t}
 		w := x.commonArgs[key]
-		if w != nil {
+		if w != nil && w.Uses != 0 { // do not reuse dead value
 			v.copyOf(w)
 			break
 		}
@@ -1709,9 +1709,15 @@
 	}
 	key := selKey{baseArg, offset, t.Size(), t}
 	w := x.commonArgs[key]
-	if w != nil {
+	if w != nil && w.Uses != 0 { // do not reuse dead value
 		if toReplace != nil {
 			toReplace.copyOf(w)
+			if x.debug > 1 {
+				x.Printf("...replace %s\n", toReplace.LongString())
+			}
+		}
+		if x.debug > 1 {
+			x.Printf("-->%s\n", w.LongString())
 		}
 		return w
 	}
diff --git a/test/fixedbugs/issue48916.go b/test/fixedbugs/issue48916.go
new file mode 100644
index 0000000..cbe97b5
--- /dev/null
+++ b/test/fixedbugs/issue48916.go
@@ -0,0 +1,37 @@
+// compile
+
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 48916: expand_calls pass crashes due to a (dead)
+// use of an OpInvalid value.
+
+package p
+
+type T struct {
+	num int64
+}
+
+func foo(vs map[T]struct{}, d T) error {
+	_, ok := vs[d]
+	if !ok {
+		return nil
+	}
+
+	switch d.num {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 5:
+	case 6:
+		var num float64
+		if num != 0 {
+			return nil
+		}
+	}
+
+	return nil
+}