src/cmd/compile/internal/ssa/gen/AMD64.rules | 2 +- src/cmd/compile/internal/ssa/rewriteAMD64.go | 4 ++-- test/fixedbugs/issue41711.go | 17 +++++++++++++++++ diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 9967c7b0305ea76a2a98b4f9ee54f9ddac6503fa..ee9ccfb41c64cbcc03cddb89af6bcbee34b40b29 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -1454,7 +1454,7 @@ (ORL x x) -> x (XORQ x x) -> (MOVQconst [0]) (XORL x x) -> (MOVLconst [0]) -(SHLLconst [d] (MOVLconst [c])) -> (MOVLconst [int64(int32(c)) << uint64(d)]) +(SHLLconst [d] (MOVLconst [c])) -> (MOVLconst [int64(int32(c) << uint64(d))]) (SHLQconst [d] (MOVQconst [c])) -> (MOVQconst [c << uint64(d)]) (SHLQconst [d] (MOVLconst [c])) -> (MOVQconst [int64(int32(c)) << uint64(d)]) diff --git a/src/cmd/compile/internal/ssa/rewriteAMD64.go b/src/cmd/compile/internal/ssa/rewriteAMD64.go index 20eab05e9ca2ab02df8494eaa1c2c6b98e7bc347..72ed1eb62c8692514e44862c9184ab352feff262 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -25454,7 +25454,7 @@ v.copyOf(x) return true } // match: (SHLLconst [d] (MOVLconst [c])) - // result: (MOVLconst [int64(int32(c)) << uint64(d)]) + // result: (MOVLconst [int64(int32(c) << uint64(d))]) for { d := v.AuxInt if v_0.Op != OpAMD64MOVLconst { @@ -25462,7 +25462,7 @@ break } c := v_0.AuxInt v.reset(OpAMD64MOVLconst) - v.AuxInt = int64(int32(c)) << uint64(d) + v.AuxInt = int64(int32(c) << uint64(d)) return true } return false diff --git a/test/fixedbugs/issue41711.go b/test/fixedbugs/issue41711.go new file mode 100644 index 0000000000000000000000000000000000000000..4e09440ba59801894ef4c90a84eb738c3c4c9b0e --- /dev/null +++ b/test/fixedbugs/issue41711.go @@ -0,0 +1,17 @@ +// compile -d=ssa/check/on + +// Copyright 2020 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 + +func f() uint32 { + s := "food" + x := uint32(s[0]) + uint32(s[1])<<8 + uint32(s[2])<<16 + uint32(s[3])<<24 + // x is a constant, but that's not known until lowering. + // shifting it by 8 moves the high byte up into the high 32 bits of + // a 64-bit word. That word is not properly sign-extended by the faulty + // rule, which causes the compiler to fail. + return x << 8 +}