[dev.ssa] cmd/compile: copy values during rewrites

Rather than require an explicit Copy on the RHS of rewrite rules,
use rulegen magic to add it.

The advantages to handling this in rulegen are:

* simpler rules
* harder to accidentally miss a Copy

Change-Id: I46853bade83bdf517eee9495bf5a553175277b53
Reviewed-on: https://go-review.googlesource.com/13242
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules
index 2a54bb0..1e9f615 100644
--- a/src/cmd/compile/internal/ssa/gen/AMD64.rules
+++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules
@@ -71,12 +71,12 @@
 (ZeroExt32to64 x) -> (MOVLQZX x)
 
 // Because we ignore high parts of registers, truncates are just copies.
-(Trunc16to8 x) -> (Copy x)
-(Trunc32to8 x) -> (Copy x)
-(Trunc32to16 x) -> (Copy x)
-(Trunc64to8 x) -> (Copy x)
-(Trunc64to16 x) -> (Copy x)
-(Trunc64to32 x) -> (Copy x)
+(Trunc16to8 x) -> x
+(Trunc32to8 x) -> x
+(Trunc32to16 x) -> x
+(Trunc64to8 x) -> x
+(Trunc64to16 x) -> x
+(Trunc64to32 x) -> x
 
 // Lowering shifts
 // Unsigned shifts need to return 0 if shift amount is >= width of shifted value.
@@ -338,7 +338,7 @@
 // strength reduction
 (MULQconst [-1] x) -> (NEGQ x)
 (MULQconst [0] _) -> (MOVQconst [0])
-(MULQconst [1] x) -> (Copy x)
+(MULQconst [1] x) -> x
 (MULQconst [3] x) -> (LEAQ2 x x)
 (MULQconst [5] x) -> (LEAQ4 x x)
 (MULQconst [9] x) -> (LEAQ8 x x)
@@ -393,10 +393,10 @@
 (MOVQloadidx8 [off1] (ADDQconst [off2] ptr) idx mem) -> (MOVQloadidx8 [addOff(off1, off2)] ptr idx mem)
 (MOVQstoreidx8 [off1] (ADDQconst [off2] ptr) idx val mem) -> (MOVQstoreidx8 [addOff(off1, off2)] ptr idx val mem)
 
-(ADDQconst [0] x) -> (Copy x)
+(ADDQconst [0] x) -> x
 
 // lower Zero instructions with word sizes
-(Zero [0] _ mem) -> (Copy mem)
+(Zero [0] _ mem) -> mem
 (Zero [1] destptr mem) -> (MOVBstore destptr (MOVBconst <config.Frontend().TypeInt8()> [0]) mem)
 (Zero [2] destptr mem) -> (MOVWstore destptr (MOVWconst <config.Frontend().TypeInt16()> [0]) mem)
 (Zero [4] destptr mem) -> (MOVLstore destptr (MOVLconst <config.Frontend().TypeInt32()> [0]) mem)
@@ -440,14 +440,14 @@
 (ANDLconst [c] _) && int32(c)==0  -> (MOVLconst [0])
 (ANDWconst [c] _) && int16(c)==0  -> (MOVWconst [0])
 (ANDBconst [c] _) && int8(c)==0   -> (MOVBconst [0])
-(ANDQconst [-1] x)                -> (Copy x)
-(ANDLconst [c] x) && int32(c)==-1 -> (Copy x)
-(ANDWconst [c] x) && int16(c)==-1 -> (Copy x)
-(ANDBconst [c] x) && int8(c)==-1  -> (Copy x)
-(ORQconst [0] x)                  -> (Copy x)
-(ORLconst [c] x) && int32(c)==0   -> (Copy x)
-(ORWconst [c] x) && int16(c)==0   -> (Copy x)
-(ORBconst [c] x) && int8(c)==0    -> (Copy x)
+(ANDQconst [-1] x)                -> x
+(ANDLconst [c] x) && int32(c)==-1 -> x
+(ANDWconst [c] x) && int16(c)==-1 -> x
+(ANDBconst [c] x) && int8(c)==-1  -> x
+(ORQconst [0] x)                  -> x
+(ORLconst [c] x) && int32(c)==0   -> x
+(ORWconst [c] x) && int16(c)==0   -> x
+(ORBconst [c] x) && int8(c)==0    -> x
 (ORQconst [-1] _)                 -> (MOVQconst [-1])
 (ORLconst [c] _) && int32(c)==-1  -> (MOVLconst [-1])
 (ORWconst [c] _) && int16(c)==-1  -> (MOVWconst [-1])
@@ -505,14 +505,14 @@
 (SUBL x x) -> (MOVLconst [0])
 (SUBW x x) -> (MOVWconst [0])
 (SUBB x x) -> (MOVBconst [0])
-(ANDQ x x) -> (Copy x)
-(ANDL x x) -> (Copy x)
-(ANDW x x) -> (Copy x)
-(ANDB x x) -> (Copy x)
-(ORQ x x) -> (Copy x)
-(ORL x x) -> (Copy x)
-(ORW x x) -> (Copy x)
-(ORB x x) -> (Copy x)
+(ANDQ x x) -> x
+(ANDL x x) -> x
+(ANDW x x) -> x
+(ANDB x x) -> x
+(ORQ x x) -> x
+(ORL x x) -> x
+(ORW x x) -> x
+(ORB x x) -> x
 (XORQ x x) -> (MOVQconst [0])
 (XORL x x) -> (MOVLconst [0])
 (XORW x x) -> (MOVWconst [0])
diff --git a/src/cmd/compile/internal/ssa/gen/generic.rules b/src/cmd/compile/internal/ssa/gen/generic.rules
index cb6a200..8656b7c 100644
--- a/src/cmd/compile/internal/ssa/gen/generic.rules
+++ b/src/cmd/compile/internal/ssa/gen/generic.rules
@@ -34,10 +34,10 @@
 (Neq16 x x) -> (ConstBool {false})
 (Neq8 x x) -> (ConstBool {false})
 
-(Com8 (Com8 x)) -> (Copy x)
-(Com16 (Com16 x)) -> (Copy x)
-(Com32 (Com32 x)) -> (Copy x)
-(Com64 (Com64 x)) -> (Copy x)
+(Com8 (Com8 x)) -> x
+(Com16 (Com16 x)) -> x
+(Com32 (Com32 x)) -> x
+(Com64 (Com64 x)) -> x
 
 // tear apart slices
 // TODO: anything that generates a slice needs to go in here.
diff --git a/src/cmd/compile/internal/ssa/gen/rulegen.go b/src/cmd/compile/internal/ssa/gen/rulegen.go
index 9edef83..6ee22c1 100644
--- a/src/cmd/compile/internal/ssa/gen/rulegen.go
+++ b/src/cmd/compile/internal/ssa/gen/rulegen.go
@@ -376,11 +376,15 @@
 	if result[0] != '(' {
 		// variable
 		if top {
-			fmt.Fprintf(w, "v.Op = %s.Op\n", result)
-			fmt.Fprintf(w, "v.AuxInt = %s.AuxInt\n", result)
-			fmt.Fprintf(w, "v.Aux = %s.Aux\n", result)
+			// It in not safe in general to move a variable between blocks
+			// (and particularly not a phi node).
+			// Introduce a copy.
+			fmt.Fprintf(w, "v.Op = OpCopy\n")
+			fmt.Fprintf(w, "v.AuxInt = 0\n")
+			fmt.Fprintf(w, "v.Aux = nil\n")
 			fmt.Fprintf(w, "v.resetArgs()\n")
-			fmt.Fprintf(w, "v.AddArgs(%s.Args...)\n", result)
+			fmt.Fprintf(w, "v.Type = %s.Type\n", result)
+			fmt.Fprintf(w, "v.AddArg(%s)\n", result)
 		}
 		return result
 	}
diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go
index bdcb991..327f322 100644
--- a/src/cmd/compile/internal/ssa/rewriteAMD64.go
+++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go
@@ -325,21 +325,22 @@
 		;
 		// match: (ADDQconst [0] x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			if v.AuxInt != 0 {
-				goto end288952f259d4a1842f1e8d5c389b3f28
+				goto end03d9f5a3e153048b0afa781401e2a849
 			}
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end288952f259d4a1842f1e8d5c389b3f28
-	end288952f259d4a1842f1e8d5c389b3f28:
+		goto end03d9f5a3e153048b0afa781401e2a849
+	end03d9f5a3e153048b0afa781401e2a849:
 		;
 		// match: (ADDQconst [c] (MOVQconst [d]))
 		// cond:
@@ -566,21 +567,22 @@
 		;
 		// match: (ANDB x x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			if v.Args[1] != x {
-				goto end1c1e017efac06c84c72f2d09d6afadc0
+				goto endb8ff272a1456513da708603abe37541c
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end1c1e017efac06c84c72f2d09d6afadc0
-	end1c1e017efac06c84c72f2d09d6afadc0:
+		goto endb8ff272a1456513da708603abe37541c
+	endb8ff272a1456513da708603abe37541c:
 		;
 	case OpAMD64ANDBconst:
 		// match: (ANDBconst [c] _)
@@ -603,22 +605,23 @@
 		;
 		// match: (ANDBconst [c] x)
 		// cond: int8(c)==-1
-		// result: (Copy x)
+		// result: x
 		{
 			c := v.AuxInt
 			x := v.Args[0]
 			if !(int8(c) == -1) {
-				goto ende983ac58fd9834f2c8503e92e45d83db
+				goto enda0b78503c204c8225de1433949a71fe4
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto ende983ac58fd9834f2c8503e92e45d83db
-	ende983ac58fd9834f2c8503e92e45d83db:
+		goto enda0b78503c204c8225de1433949a71fe4
+	enda0b78503c204c8225de1433949a71fe4:
 		;
 		// match: (ANDBconst [c] (MOVBconst [d]))
 		// cond:
@@ -682,21 +685,22 @@
 		;
 		// match: (ANDL x x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			if v.Args[1] != x {
-				goto end0ff7ad77f6811c422b0b588f48474ddc
+				goto enddfb08a0d0c262854db3905cb323388c7
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end0ff7ad77f6811c422b0b588f48474ddc
-	end0ff7ad77f6811c422b0b588f48474ddc:
+		goto enddfb08a0d0c262854db3905cb323388c7
+	enddfb08a0d0c262854db3905cb323388c7:
 		;
 	case OpAMD64ANDLconst:
 		// match: (ANDLconst [c] _)
@@ -719,22 +723,23 @@
 		;
 		// match: (ANDLconst [c] x)
 		// cond: int32(c)==-1
-		// result: (Copy x)
+		// result: x
 		{
 			c := v.AuxInt
 			x := v.Args[0]
 			if !(int32(c) == -1) {
-				goto enda670b6e074269a5e1fcbdaec05596a28
+				goto end0e852ae30bb8289d6ffee0c9267e3e0c
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto enda670b6e074269a5e1fcbdaec05596a28
-	enda670b6e074269a5e1fcbdaec05596a28:
+		goto end0e852ae30bb8289d6ffee0c9267e3e0c
+	end0e852ae30bb8289d6ffee0c9267e3e0c:
 		;
 		// match: (ANDLconst [c] (MOVLconst [d]))
 		// cond:
@@ -804,21 +809,22 @@
 		;
 		// match: (ANDQ x x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			if v.Args[1] != x {
-				goto endb54d87d7a12ba29a9d19b808319ab055
+				goto end06b5ec19efdd4e79f03a5e4a2c3c3427
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto endb54d87d7a12ba29a9d19b808319ab055
-	endb54d87d7a12ba29a9d19b808319ab055:
+		goto end06b5ec19efdd4e79f03a5e4a2c3c3427
+	end06b5ec19efdd4e79f03a5e4a2c3c3427:
 		;
 	case OpAMD64ANDQconst:
 		// match: (ANDQconst [0] _)
@@ -840,21 +846,22 @@
 		;
 		// match: (ANDQconst [-1] x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			if v.AuxInt != -1 {
-				goto end993d44ced14a02748f2d0e77230e8991
+				goto endb542c4b42ab94a7bedb32dec8f610d67
 			}
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end993d44ced14a02748f2d0e77230e8991
-	end993d44ced14a02748f2d0e77230e8991:
+		goto endb542c4b42ab94a7bedb32dec8f610d67
+	endb542c4b42ab94a7bedb32dec8f610d67:
 		;
 		// match: (ANDQconst [c] (MOVQconst [d]))
 		// cond:
@@ -958,21 +965,22 @@
 		;
 		// match: (ANDW x x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			if v.Args[1] != x {
-				goto end08c49eea4ac769acc212ebd833934be8
+				goto end3a26cf52dd1b77f07cc9e005760dbb11
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end08c49eea4ac769acc212ebd833934be8
-	end08c49eea4ac769acc212ebd833934be8:
+		goto end3a26cf52dd1b77f07cc9e005760dbb11
+	end3a26cf52dd1b77f07cc9e005760dbb11:
 		;
 	case OpAMD64ANDWconst:
 		// match: (ANDWconst [c] _)
@@ -995,22 +1003,23 @@
 		;
 		// match: (ANDWconst [c] x)
 		// cond: int16(c)==-1
-		// result: (Copy x)
+		// result: x
 		{
 			c := v.AuxInt
 			x := v.Args[0]
 			if !(int16(c) == -1) {
-				goto ende01402832ff041ac3e12fc077684125f
+				goto endfb111c3afa8c5c4040fa6000fadee810
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto ende01402832ff041ac3e12fc077684125f
-	ende01402832ff041ac3e12fc077684125f:
+		goto endfb111c3afa8c5c4040fa6000fadee810
+	endfb111c3afa8c5c4040fa6000fadee810:
 		;
 		// match: (ANDWconst [c] (MOVWconst [d]))
 		// cond:
@@ -3554,21 +3563,22 @@
 		;
 		// match: (MULQconst [1] x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			if v.AuxInt != 1 {
-				goto endd7217a7c6311fc7a3e0736a1b0b5be73
+				goto end0b527e71db2b288b2841a1f757aa580d
 			}
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto endd7217a7c6311fc7a3e0736a1b0b5be73
-	endd7217a7c6311fc7a3e0736a1b0b5be73:
+		goto end0b527e71db2b288b2841a1f757aa580d
+	end0b527e71db2b288b2841a1f757aa580d:
 		;
 		// match: (MULQconst [3] x)
 		// cond:
@@ -4223,41 +4233,43 @@
 		;
 		// match: (ORB x x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			if v.Args[1] != x {
-				goto endd53ede4886d67f4b4ae970316a2febb4
+				goto enddca5ce800a9eca157f243cb2fdb1408a
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto endd53ede4886d67f4b4ae970316a2febb4
-	endd53ede4886d67f4b4ae970316a2febb4:
+		goto enddca5ce800a9eca157f243cb2fdb1408a
+	enddca5ce800a9eca157f243cb2fdb1408a:
 		;
 	case OpAMD64ORBconst:
 		// match: (ORBconst [c] x)
 		// cond: int8(c)==0
-		// result: (Copy x)
+		// result: x
 		{
 			c := v.AuxInt
 			x := v.Args[0]
 			if !(int8(c) == 0) {
-				goto end3b9f6d1a1a523595d101f89410f453a1
+				goto end565f78e3a843dc73943b59227b39a1b3
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end3b9f6d1a1a523595d101f89410f453a1
-	end3b9f6d1a1a523595d101f89410f453a1:
+		goto end565f78e3a843dc73943b59227b39a1b3
+	end565f78e3a843dc73943b59227b39a1b3:
 		;
 		// match: (ORBconst [c] _)
 		// cond: int8(c)==-1
@@ -4339,41 +4351,43 @@
 		;
 		// match: (ORL x x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			if v.Args[1] != x {
-				goto end556b9151cacb9db2803373ce10829b2a
+				goto end2dd719b68f4938777ef0d820aab93659
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end556b9151cacb9db2803373ce10829b2a
-	end556b9151cacb9db2803373ce10829b2a:
+		goto end2dd719b68f4938777ef0d820aab93659
+	end2dd719b68f4938777ef0d820aab93659:
 		;
 	case OpAMD64ORLconst:
 		// match: (ORLconst [c] x)
 		// cond: int32(c)==0
-		// result: (Copy x)
+		// result: x
 		{
 			c := v.AuxInt
 			x := v.Args[0]
 			if !(int32(c) == 0) {
-				goto end800adaf85f4201ebf7a0e38dc1768c86
+				goto end5b52623a724e8a7167c71289fb7192f1
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end800adaf85f4201ebf7a0e38dc1768c86
-	end800adaf85f4201ebf7a0e38dc1768c86:
+		goto end5b52623a724e8a7167c71289fb7192f1
+	end5b52623a724e8a7167c71289fb7192f1:
 		;
 		// match: (ORLconst [c] _)
 		// cond: int32(c)==-1
@@ -4461,40 +4475,42 @@
 		;
 		// match: (ORQ x x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			if v.Args[1] != x {
-				goto endcad306e115ea011a2a70f4e4e5440de4
+				goto end47a27d30b82db576978c5a3a57b520fb
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto endcad306e115ea011a2a70f4e4e5440de4
-	endcad306e115ea011a2a70f4e4e5440de4:
+		goto end47a27d30b82db576978c5a3a57b520fb
+	end47a27d30b82db576978c5a3a57b520fb:
 		;
 	case OpAMD64ORQconst:
 		// match: (ORQconst [0] x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			if v.AuxInt != 0 {
-				goto end98a286fc50bc6cf8ca9f5af523e2b5cd
+				goto end44534da6b9ce98d33fad7e20f0be1fbd
 			}
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end98a286fc50bc6cf8ca9f5af523e2b5cd
-	end98a286fc50bc6cf8ca9f5af523e2b5cd:
+		goto end44534da6b9ce98d33fad7e20f0be1fbd
+	end44534da6b9ce98d33fad7e20f0be1fbd:
 		;
 		// match: (ORQconst [-1] _)
 		// cond:
@@ -4575,41 +4591,43 @@
 		;
 		// match: (ORW x x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			if v.Args[1] != x {
-				goto end7c69794f4a3a6ada00bd868f743d86f8
+				goto endc6a23b64e541dc9cfc6a90fd7028e8c1
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end7c69794f4a3a6ada00bd868f743d86f8
-	end7c69794f4a3a6ada00bd868f743d86f8:
+		goto endc6a23b64e541dc9cfc6a90fd7028e8c1
+	endc6a23b64e541dc9cfc6a90fd7028e8c1:
 		;
 	case OpAMD64ORWconst:
 		// match: (ORWconst [c] x)
 		// cond: int16(c)==0
-		// result: (Copy x)
+		// result: x
 		{
 			c := v.AuxInt
 			x := v.Args[0]
 			if !(int16(c) == 0) {
-				goto end61a4fd5308425b3eafd158f13aaf8f13
+				goto endbbbdec9091c8b4c58e587eac8a43402d
 			}
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end61a4fd5308425b3eafd158f13aaf8f13
-	end61a4fd5308425b3eafd158f13aaf8f13:
+		goto endbbbdec9091c8b4c58e587eac8a43402d
+	endbbbdec9091c8b4c58e587eac8a43402d:
 		;
 		// match: (ORWconst [c] _)
 		// cond: int16(c)==-1
@@ -7326,98 +7344,104 @@
 	case OpTrunc16to8:
 		// match: (Trunc16to8 x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end18a19bd8418f9079595720df0874e90a
-	end18a19bd8418f9079595720df0874e90a:
+		goto end8e2f5e0a6e3a06423c077747de6c2bdd
+	end8e2f5e0a6e3a06423c077747de6c2bdd:
 		;
 	case OpTrunc32to16:
 		// match: (Trunc32to16 x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end217b00780a8b1139d068680ed9d61cb0
-	end217b00780a8b1139d068680ed9d61cb0:
+		goto end5bed0e3a3c1c6374d86beb5a4397708c
+	end5bed0e3a3c1c6374d86beb5a4397708c:
 		;
 	case OpTrunc32to8:
 		// match: (Trunc32to8 x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end05d10e0a1c707d66b11b2d342634efd0
-	end05d10e0a1c707d66b11b2d342634efd0:
+		goto endef0b8032ce91979ce6cd0004260c04ee
+	endef0b8032ce91979ce6cd0004260c04ee:
 		;
 	case OpTrunc64to16:
 		// match: (Trunc64to16 x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end4623ae65eb76feca3936354f22d45fa7
-	end4623ae65eb76feca3936354f22d45fa7:
+		goto endd32fd6e0ce970c212835e6f71c3dcbfd
+	endd32fd6e0ce970c212835e6f71c3dcbfd:
 		;
 	case OpTrunc64to32:
 		// match: (Trunc64to32 x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end93e0b16b58a717a3e4f5c2ca67b6be87
-	end93e0b16b58a717a3e4f5c2ca67b6be87:
+		goto end1212c4e84153210aff7fd630fb3e1883
+	end1212c4e84153210aff7fd630fb3e1883:
 		;
 	case OpTrunc64to8:
 		// match: (Trunc64to8 x)
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			x := v.Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto endc4c1a1b86edd0f082339d17eb5096ad0
-	endc4c1a1b86edd0f082339d17eb5096ad0:
+		goto end734f017d4b2810ca2288f7037365824c
+	end734f017d4b2810ca2288f7037365824c:
 		;
 	case OpAMD64XORB:
 		// match: (XORB x (MOVBconst [c]))
@@ -7816,21 +7840,22 @@
 	case OpZero:
 		// match: (Zero [0] _ mem)
 		// cond:
-		// result: (Copy mem)
+		// result: mem
 		{
 			if v.AuxInt != 0 {
-				goto endb85a34a7d102b0e0d801454f437db5bf
+				goto endc9a38a60f0322f93682daa824611272c
 			}
 			mem := v.Args[1]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = mem.Type
 			v.AddArg(mem)
 			return true
 		}
-		goto endb85a34a7d102b0e0d801454f437db5bf
-	endb85a34a7d102b0e0d801454f437db5bf:
+		goto endc9a38a60f0322f93682daa824611272c
+	endc9a38a60f0322f93682daa824611272c:
 		;
 		// match: (Zero [1] destptr mem)
 		// cond:
diff --git a/src/cmd/compile/internal/ssa/rewritegeneric.go b/src/cmd/compile/internal/ssa/rewritegeneric.go
index d706fd7..9753bde 100644
--- a/src/cmd/compile/internal/ssa/rewritegeneric.go
+++ b/src/cmd/compile/internal/ssa/rewritegeneric.go
@@ -80,78 +80,82 @@
 	case OpCom16:
 		// match: (Com16 (Com16 x))
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			if v.Args[0].Op != OpCom16 {
-				goto end388d572e5a72fd87a07da5cab243ebdc
+				goto end1ea17710dd4dd7ba4e710e0e4c7b5a56
 			}
 			x := v.Args[0].Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end388d572e5a72fd87a07da5cab243ebdc
-	end388d572e5a72fd87a07da5cab243ebdc:
+		goto end1ea17710dd4dd7ba4e710e0e4c7b5a56
+	end1ea17710dd4dd7ba4e710e0e4c7b5a56:
 		;
 	case OpCom32:
 		// match: (Com32 (Com32 x))
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			if v.Args[0].Op != OpCom32 {
-				goto end5b2b3834acc7313649923604f685e7c5
+				goto end9a04ed536496e292c27bef4414128cbf
 			}
 			x := v.Args[0].Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end5b2b3834acc7313649923604f685e7c5
-	end5b2b3834acc7313649923604f685e7c5:
+		goto end9a04ed536496e292c27bef4414128cbf
+	end9a04ed536496e292c27bef4414128cbf:
 		;
 	case OpCom64:
 		// match: (Com64 (Com64 x))
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			if v.Args[0].Op != OpCom64 {
-				goto end6d6312f25d06a327d92f028b1ce50566
+				goto ended44e29d5968f0f7b86972b7bf417ab3
 			}
 			x := v.Args[0].Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end6d6312f25d06a327d92f028b1ce50566
-	end6d6312f25d06a327d92f028b1ce50566:
+		goto ended44e29d5968f0f7b86972b7bf417ab3
+	ended44e29d5968f0f7b86972b7bf417ab3:
 		;
 	case OpCom8:
 		// match: (Com8 (Com8 x))
 		// cond:
-		// result: (Copy x)
+		// result: x
 		{
 			if v.Args[0].Op != OpCom8 {
-				goto end70cbd85c4b8e82c170dba7c23f8bc0f3
+				goto end4d92ff3ba567d9afd38fc9ca113602ad
 			}
 			x := v.Args[0].Args[0]
 			v.Op = OpCopy
 			v.AuxInt = 0
 			v.Aux = nil
 			v.resetArgs()
+			v.Type = x.Type
 			v.AddArg(x)
 			return true
 		}
-		goto end70cbd85c4b8e82c170dba7c23f8bc0f3
-	end70cbd85c4b8e82c170dba7c23f8bc0f3:
+		goto end4d92ff3ba567d9afd38fc9ca113602ad
+	end4d92ff3ba567d9afd38fc9ca113602ad:
 		;
 	case OpConstString:
 		// match: (ConstString {s})
@@ -716,11 +720,12 @@
 				goto end0d922460b7e5ca88324034f4bd6c027c
 			}
 			len := v.Args[0].Args[1]
-			v.Op = len.Op
-			v.AuxInt = len.AuxInt
-			v.Aux = len.Aux
+			v.Op = OpCopy
+			v.AuxInt = 0
+			v.Aux = nil
 			v.resetArgs()
-			v.AddArgs(len.Args...)
+			v.Type = len.Type
+			v.AddArg(len)
 			return true
 		}
 		goto end0d922460b7e5ca88324034f4bd6c027c
@@ -735,11 +740,12 @@
 				goto end061edc5d85c73ad909089af2556d9380
 			}
 			ptr := v.Args[0].Args[0]
-			v.Op = ptr.Op
-			v.AuxInt = ptr.AuxInt
-			v.Aux = ptr.Aux
+			v.Op = OpCopy
+			v.AuxInt = 0
+			v.Aux = nil
 			v.resetArgs()
-			v.AddArgs(ptr.Args...)
+			v.Type = ptr.Type
+			v.AddArg(ptr)
 			return true
 		}
 		goto end061edc5d85c73ad909089af2556d9380