// 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 80577: on riscv64, sign extensions were elided after // 32-bit instructions that architecturally sign-extend their // result, but an unsigned-typed value spilled across a call is // restored with a zero-extending load, losing the elided // sign extension. package main import "math/bits" var sink uint32 //go:noinline func use(x uint32) { sink = x } //go:noinline func mul(a, b uint32) int64 { p := a * b use(p) // p live across the call, forcing a spill return int64(int32(p)) } //go:noinline func div(a, b uint32) int64 { p := a / b use(p) return int64(int32(p)) } //go:noinline func rem(a, b uint32) int64 { p := a % b use(p) return int64(int32(p)) } //go:noinline func rot(a uint32, k int) int64 { p := bits.RotateLeft32(a, k) use(p) return int64(int32(p)) } func main() { const want = -2147483648 if got := mul(0x8000, 0x10000); got != want { println("mul: got", got, "want", want) panic("bad mul") } if got := div(0x80000000, 1); got != want { println("div: got", got, "want", want) panic("bad div") } if got := rem(0x80000000, 0xffffffff); got != want { println("rem: got", got, "want", want) panic("bad rem") } if got := rot(1, 31); got != want { println("rot: got", got, "want", want) panic("bad rot") } }