Skip to content

Commit d93ff73

Browse files
committed
cmd/compile: don't elide extension for LoadReg to FP register on MIPS64
For an extension operation like MOWWreg, if the operand is already extended, we optimize the second extension out. Usually a LoadReg of a proper type would come already extended, as a MOVW/MOVWU etc. instruction does. But for a LoadReg to a floating point register, the instruction does not do the extension. So we cannot elide the extension. Fixes #50671. Change-Id: Id8991df78d5acdecd3fd6138c558428cbd5f6ba3 Reviewed-on: https://go-review.googlesource.com/c/go/+/379236 Trust: Cherry Mui <[email protected]> Run-TryBot: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: David Chase <[email protected]>
1 parent ca33b34 commit d93ff73

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

src/cmd/compile/internal/mips64/ssa.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,10 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
320320
for a.Op == ssa.OpCopy || a.Op == ssa.OpMIPS64MOVVreg {
321321
a = a.Args[0]
322322
}
323-
if a.Op == ssa.OpLoadReg {
323+
if a.Op == ssa.OpLoadReg && mips.REG_R0 <= a.Reg() && a.Reg() <= mips.REG_R31 {
324+
// LoadReg from a narrower type does an extension, except loading
325+
// to a floating point register. So only eliminate the extension
326+
// if it is loaded to an integer register.
324327
t := a.Type
325328
switch {
326329
case v.Op == ssa.OpMIPS64MOVBreg && t.Size() == 1 && t.IsSigned(),

test/fixedbugs/issue50671.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// run
2+
3+
// Copyright 2022 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// Issue 50671: sign extension eliminated incorrectly on MIPS64.
8+
9+
package main
10+
11+
//go:noinline
12+
func F(x int32) (float64, int64) {
13+
a := float64(x)
14+
b := int64(x)
15+
return a, b
16+
}
17+
18+
var a, b, c float64
19+
20+
// Poison some floating point registers with non-zero high bits.
21+
//
22+
//go:noinline
23+
func poison(x float64) {
24+
a = x - 123.45
25+
b = a * 1.2
26+
c = b + 3.4
27+
}
28+
29+
func main() {
30+
poison(333.3)
31+
_, b := F(123)
32+
if b != 123 {
33+
panic("FAIL")
34+
}
35+
}

0 commit comments

Comments
 (0)