cmd/compile: fix misscompilation of Rsh with 32bits rhs on arm64 A copy paste mistake means we used a 64bits compare to check the 32bits shiftend. Fixes #79886 Change-Id: Idcd2213e87ac2bece22fa817880af26354beba59 Reviewed-on: https://go-review.googlesource.com/c/go/+/787920 LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Jorropo <jorropo.pgm@gmail.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
diff --git a/src/cmd/compile/internal/ssa/_gen/ARM64.rules b/src/cmd/compile/internal/ssa/_gen/ARM64.rules index 3c773e1..4c6c437 100644 --- a/src/cmd/compile/internal/ssa/_gen/ARM64.rules +++ b/src/cmd/compile/internal/ssa/_gen/ARM64.rules
@@ -174,8 +174,8 @@ (Rsh64Ux32 <t> x y) && !shiftIsBounded(v) => (CSEL [OpARM64LessThanU] (SRL <t> x y) (Const64 <t> [0]) (CMPWconst [64] y)) (Rsh64Ux(16|8) <t> [bounded] x y) && !shiftIsBounded(v) => (Rsh64Ux32 <t> [bounded] x (ZeroExt(16|8)to32 y)) -(Rsh64x64 <t> x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y))) -(Rsh64x32 <t> x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y))) +(Rsh64x64 <t> x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y))) +(Rsh64x32 <t> x y) && !shiftIsBounded(v) => (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPWconst [64] y))) (Rsh64x(16|8) <t> [bounded] x y) && !shiftIsBounded(v) => (Rsh64x32 <t> [bounded] x (ZeroExt(16|8)to32 y)) // constants
diff --git a/src/cmd/compile/internal/ssa/rewriteARM64.go b/src/cmd/compile/internal/ssa/rewriteARM64.go index 1a985c4..d93a204 100644 --- a/src/cmd/compile/internal/ssa/rewriteARM64.go +++ b/src/cmd/compile/internal/ssa/rewriteARM64.go
@@ -22941,7 +22941,7 @@ } // match: (Rsh64x32 <t> x y) // cond: !shiftIsBounded(v) - // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPconst [64] y))) + // result: (SRA x (CSEL [OpARM64LessThanU] <y.Type> y (Const64 <y.Type> [63]) (CMPWconst [64] y))) for { x := v_0 y := v_1 @@ -22953,8 +22953,8 @@ v0.AuxInt = opToAuxInt(OpARM64LessThanU) v1 := b.NewValue0(v.Pos, OpConst64, y.Type) v1.AuxInt = int64ToAuxInt(63) - v2 := b.NewValue0(v.Pos, OpARM64CMPconst, types.TypeFlags) - v2.AuxInt = int64ToAuxInt(64) + v2 := b.NewValue0(v.Pos, OpARM64CMPWconst, types.TypeFlags) + v2.AuxInt = int32ToAuxInt(64) v2.AddArg(y) v0.AddArg3(y, v1, v2) v.AddArg2(x, v0)
diff --git a/test/fixedbugs/issue79886.go b/test/fixedbugs/issue79886.go new file mode 100644 index 0000000..405d892 --- /dev/null +++ b/test/fixedbugs/issue79886.go
@@ -0,0 +1,25 @@ +// 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. + +package main + +import ( + "fmt" +) + +//go:noinline +func shifted(x int64, y uint64) int64 { + return x >> uint32(y) +} + +func main() { + x := int64(-0x4000000000000000) + got := shifted(x, ^uint64(0)&^(1<<32-2)) + want := x >> 1 + if got != want { + panic(fmt.Sprintf("want %d; got %d", want, got)) + } +}