From 7863f742c4e8427a7169325b024c2d8a970e0134 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 1 Oct 2020 09:57:52 -0700 Subject: [release-branch.go1.15] cmd/compile: fix left shift constant folding rule The 32-bit left shift constant folding rule should keep its result properly sign extended. Fixes #41720 Fixes #41711 Change-Id: I0fc74444d444274e911952e1725dab0b7737a846 Reviewed-on: https://go-review.googlesource.com/c/go/+/258817 Trust: Keith Randall Run-TryBot: Keith Randall Reviewed-by: David Chase TryBot-Result: Go Bot --- src/cmd/compile/internal/ssa/gen/AMD64.rules | 2 +- src/cmd/compile/internal/ssa/rewriteAMD64.go | 4 ++-- test/fixedbugs/issue41711.go | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 test/fixedbugs/issue41711.go diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index 9967c7b030..ee9ccfb41c 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 20eab05e9c..72ed1eb62c 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 0000000000..4e09440ba5 --- /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 +} -- cgit v1.2.3-54-g00ecf