diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index f1d53bc51f..ff38be550e 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -2405,15 +2405,17 @@ (BSFQ (ORQconst [1<<16] (MOVWQZX x))) -> (BSFQ (ORQconst [1<<16] x)) // Redundant sign/zero extensions -(MOVLQSX x:(MOVLQSX _)) -> x -(MOVLQSX x:(MOVWQSX _)) -> x -(MOVLQSX x:(MOVBQSX _)) -> x -(MOVWQSX x:(MOVWQSX _)) -> x -(MOVWQSX x:(MOVBQSX _)) -> x -(MOVBQSX x:(MOVBQSX _)) -> x -(MOVLQZX x:(MOVLQZX _)) -> x -(MOVLQZX x:(MOVWQZX _)) -> x -(MOVLQZX x:(MOVBQZX _)) -> x -(MOVWQZX x:(MOVWQZX _)) -> x -(MOVWQZX x:(MOVBQZX _)) -> x -(MOVBQZX x:(MOVBQZX _)) -> x +// Note: see issue 21963. We have to make sure we use the right type on +// the resulting extension (the outer type, not the inner type). +(MOVLQSX (MOVLQSX x)) -> (MOVLQSX x) +(MOVLQSX (MOVWQSX x)) -> (MOVWQSX x) +(MOVLQSX (MOVBQSX x)) -> (MOVBQSX x) +(MOVWQSX (MOVWQSX x)) -> (MOVWQSX x) +(MOVWQSX (MOVBQSX x)) -> (MOVBQSX x) +(MOVBQSX (MOVBQSX x)) -> (MOVBQSX x) +(MOVLQZX (MOVLQZX x)) -> (MOVLQZX x) +(MOVLQZX (MOVWQZX x)) -> (MOVWQZX x) +(MOVLQZX (MOVBQZX x)) -> (MOVBQZX x) +(MOVWQZX (MOVWQZX x)) -> (MOVWQZX x) +(MOVWQZX (MOVBQZX x)) -> (MOVBQZX x) +(MOVBQZX (MOVBQZX x)) -> (MOVBQZX x) diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index f2f4896410..9213616f83 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -4319,16 +4319,16 @@ func rewriteValueAMD64_OpAMD64MOVBQSX_0(v *Value) bool { v.AddArg(x) return true } - // match: (MOVBQSX x:(MOVBQSX _)) + // match: (MOVBQSX (MOVBQSX x)) // cond: - // result: x + // result: (MOVBQSX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVBQSX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVBQSX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVBQSX) v.AddArg(x) return true } @@ -4536,16 +4536,16 @@ func rewriteValueAMD64_OpAMD64MOVBQZX_0(v *Value) bool { v.AddArg(x) return true } - // match: (MOVBQZX x:(MOVBQZX _)) + // match: (MOVBQZX (MOVBQZX x)) // cond: - // result: x + // result: (MOVBQZX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVBQZX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVBQZX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVBQZX) v.AddArg(x) return true } @@ -6392,42 +6392,42 @@ func rewriteValueAMD64_OpAMD64MOVLQSX_0(v *Value) bool { v.AddArg(x) return true } - // match: (MOVLQSX x:(MOVLQSX _)) + // match: (MOVLQSX (MOVLQSX x)) // cond: - // result: x + // result: (MOVLQSX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVLQSX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVLQSX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVLQSX) v.AddArg(x) return true } - // match: (MOVLQSX x:(MOVWQSX _)) + // match: (MOVLQSX (MOVWQSX x)) // cond: - // result: x + // result: (MOVWQSX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVWQSX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVWQSX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVWQSX) v.AddArg(x) return true } - // match: (MOVLQSX x:(MOVBQSX _)) + // match: (MOVLQSX (MOVBQSX x)) // cond: - // result: x + // result: (MOVBQSX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVBQSX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVBQSX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVBQSX) v.AddArg(x) return true } @@ -6611,42 +6611,42 @@ func rewriteValueAMD64_OpAMD64MOVLQZX_0(v *Value) bool { v.AddArg(x) return true } - // match: (MOVLQZX x:(MOVLQZX _)) + // match: (MOVLQZX (MOVLQZX x)) // cond: - // result: x + // result: (MOVLQZX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVLQZX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVLQZX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVLQZX) v.AddArg(x) return true } - // match: (MOVLQZX x:(MOVWQZX _)) + // match: (MOVLQZX (MOVWQZX x)) // cond: - // result: x + // result: (MOVWQZX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVWQZX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVWQZX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVWQZX) v.AddArg(x) return true } - // match: (MOVLQZX x:(MOVBQZX _)) + // match: (MOVLQZX (MOVBQZX x)) // cond: - // result: x + // result: (MOVBQZX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVBQZX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVBQZX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVBQZX) v.AddArg(x) return true } @@ -10767,29 +10767,29 @@ func rewriteValueAMD64_OpAMD64MOVWQSX_0(v *Value) bool { v.AddArg(x) return true } - // match: (MOVWQSX x:(MOVWQSX _)) + // match: (MOVWQSX (MOVWQSX x)) // cond: - // result: x + // result: (MOVWQSX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVWQSX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVWQSX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVWQSX) v.AddArg(x) return true } - // match: (MOVWQSX x:(MOVBQSX _)) + // match: (MOVWQSX (MOVBQSX x)) // cond: - // result: x + // result: (MOVBQSX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVBQSX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVBQSX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVBQSX) v.AddArg(x) return true } @@ -10999,29 +10999,29 @@ func rewriteValueAMD64_OpAMD64MOVWQZX_0(v *Value) bool { v.AddArg(x) return true } - // match: (MOVWQZX x:(MOVWQZX _)) + // match: (MOVWQZX (MOVWQZX x)) // cond: - // result: x + // result: (MOVWQZX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVWQZX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVWQZX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVWQZX) v.AddArg(x) return true } - // match: (MOVWQZX x:(MOVBQZX _)) + // match: (MOVWQZX (MOVBQZX x)) // cond: - // result: x + // result: (MOVBQZX x) for { - x := v.Args[0] - if x.Op != OpAMD64MOVBQZX { + v_0 := v.Args[0] + if v_0.Op != OpAMD64MOVBQZX { break } - v.reset(OpCopy) - v.Type = x.Type + x := v_0.Args[0] + v.reset(OpAMD64MOVBQZX) v.AddArg(x) return true } diff --git a/test/fixedbugs/issue21963.go b/test/fixedbugs/issue21963.go new file mode 100644 index 0000000000..996bd63d09 --- /dev/null +++ b/test/fixedbugs/issue21963.go @@ -0,0 +1,27 @@ +// run + +// Copyright 2017 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. + +package main + +import ( + "fmt" + "runtime" +) + +//go:noinline +func f(x []int32, y *int8) int32 { + c := int32(int16(*y)) + runtime.GC() + return x[0] * c +} + +func main() { + var x = [1]int32{5} + var y int8 = -1 + if got, want := f(x[:], &y), int32(-5); got != want { + panic(fmt.Sprintf("wanted %d, got %d", want, got)) + } +}