diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 9967c7b0305ea7..ee9ccfb41c64cb 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -1454,7 +1454,7 @@ (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 20eab05e9ca2ab..72ed1eb62c8692 100644 --- a/src/cmd/compile/internal/ssa/rewriteAMD64.go +++ b/src/cmd/compile/internal/ssa/rewriteAMD64.go @@ -25454,7 +25454,7 @@ func rewriteValueAMD64_OpAMD64SHLLconst(v *Value) bool { 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 @@ func rewriteValueAMD64_OpAMD64SHLLconst(v *Value) bool { } 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 00000000000000..4e09440ba59801 --- /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 +}