mirror of
https://github.com/golang/go.git
synced 2026-06-27 19:30:52 +00:00
cmd/compile: do not misscompile x+x << 63 to x << 0 on amd64
Fixes #79182 Change-Id: I63ca6cb1bd3f6752a7e9b809cfffc8d45b7adc51 Reviewed-on: https://go-review.googlesource.com/c/go/+/774040 Auto-Submit: Jorropo <jorropo.pgm@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
784ea961a4
commit
c3bfc824a5
3 changed files with 38 additions and 3 deletions
|
|
@ -912,7 +912,8 @@
|
|||
(LEA(Q|L)2 [0] {s} (ADD(Q|L) x x) x) && s == nil => (SHL(Q|L)const [2] x)
|
||||
|
||||
// (x + x) << 2 -> x << 3 and similar
|
||||
(SHL(Q|L)const [c] (ADD(Q|L) x x)) => (SHL(Q|L)const [c+1] x)
|
||||
(SHLQconst [c] (ADDQ x x)) && c < 63 => (SHLQconst [c+1] x)
|
||||
(SHLLconst [c] (ADDL x x)) && c < 31 => (SHLLconst [c+1] x)
|
||||
|
||||
// reverse ordering of compare instruction
|
||||
(SETL (InvertFlags x)) => (SETG x)
|
||||
|
|
|
|||
|
|
@ -26294,6 +26294,7 @@ func rewriteValueAMD64_OpAMD64SHLLconst(v *Value) bool {
|
|||
return true
|
||||
}
|
||||
// match: (SHLLconst [c] (ADDL x x))
|
||||
// cond: c < 31
|
||||
// result: (SHLLconst [c+1] x)
|
||||
for {
|
||||
c := auxIntToInt8(v.AuxInt)
|
||||
|
|
@ -26301,7 +26302,7 @@ func rewriteValueAMD64_OpAMD64SHLLconst(v *Value) bool {
|
|||
break
|
||||
}
|
||||
x := v_0.Args[1]
|
||||
if x != v_0.Args[0] {
|
||||
if x != v_0.Args[0] || !(c < 31) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SHLLconst)
|
||||
|
|
@ -26565,6 +26566,7 @@ func rewriteValueAMD64_OpAMD64SHLQconst(v *Value) bool {
|
|||
return true
|
||||
}
|
||||
// match: (SHLQconst [c] (ADDQ x x))
|
||||
// cond: c < 63
|
||||
// result: (SHLQconst [c+1] x)
|
||||
for {
|
||||
c := auxIntToInt8(v.AuxInt)
|
||||
|
|
@ -26572,7 +26574,7 @@ func rewriteValueAMD64_OpAMD64SHLQconst(v *Value) bool {
|
|||
break
|
||||
}
|
||||
x := v_0.Args[1]
|
||||
if x != v_0.Args[0] {
|
||||
if x != v_0.Args[0] || !(c < 63) {
|
||||
break
|
||||
}
|
||||
v.reset(OpAMD64SHLQconst)
|
||||
|
|
|
|||
32
test/fixedbugs/issue79182.go
Normal file
32
test/fixedbugs/issue79182.go
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// run
|
||||
|
||||
// Copyright 2026 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.
|
||||
|
||||
// Issue 79182: SHLQconst/SHLLconst rewrite rule for (x+x)<<c
|
||||
// missed a bounds check on c, causing c+1 to overflow the valid
|
||||
// shift range and producing incorrect results on amd64.
|
||||
|
||||
package main
|
||||
|
||||
//go:noinline
|
||||
func shl32(x uint32) uint32 {
|
||||
return (x + x) << 31
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func shl64(x uint64) uint64 {
|
||||
return (x + x) << 63
|
||||
}
|
||||
|
||||
func main() {
|
||||
if got := shl32(1); got != 0 {
|
||||
println("shl32(1) =", got, "want 0")
|
||||
panic("FAIL")
|
||||
}
|
||||
if got := shl64(1); got != 0 {
|
||||
println("shl64(1) =", got, "want 0")
|
||||
panic("FAIL")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue