This file is miscompiled on ppc64le:
package main
//go:noinline
func g(i uint64) uint64 {
return uint64(uint32(i))
}
var sink uint64
func main() {
for i := uint64(0); i < 1; i++ {
i32 := int32(i - 1)
sink = uint64((uint32(i32) << 1) ^ uint32((i32 >> 31)))
x := g(uint64(i32))
if x != uint64(uint32(i32)) {
panic(x)
}
}
}
On amd64 with tip, or on ppc64le with Go 1.11.5, this program runs without error. On ppc64le GNU/Linux with tip, the program panics:
panic: 4294967295
goroutine 1 [running]:
main.main()
/home/ian/foo.go:16 +0xa8
exit status 2
Using objdump to look at the executable, I see this:
/home/ian/foo.go:12
621cc: ff ff 83 38 addi r4,r3,-1
621d0: 28 00 85 78 rldic r5,r4,0,32
621d4: 30 00 a1 90 stw r5,48(r1)
/home/ian/foo.go:13
621d8: 3c 08 a6 54 rlwinm r6,r5,1,0,30
621dc: 70 fe a7 7c srawi r7,r5,31
621e0: 78 3a c6 7c xor r6,r6,r7
621e4: 28 00 c6 78 rldic r6,r6,0,32
621e8: 10 00 e0 3f lis r31,16
621ec: 18 3d df f8 std r6,15640(r31)
/home/ian/foo.go:14
621f0: b4 07 84 7c extsw r4,r4
621f4: 20 00 81 f8 std r4,32(r1)
621f8: 89 ff ff 4b bl 62180 <main.g>
621fc: 28 00 61 e8 ld r3,40(r1)
/home/ian/foo.go:15
62200: 32 00 81 e8 lwa r4,48(r1)
62204: 00 20 23 7c cmpd r3,r4
62208: b0 ff 82 41 beq 621b8 <main.main+0x28>
6220c: 14 00 00 48 b 62220 <main.main+0x90>
62210: 00 00 e1 eb ld r31,0(r1)
62214: a6 03 e8 7f mtlr r31
62218: 40 00 21 38 addi r1,r1,64
6221c: 20 00 80 4e blr
The variable i32 is stored at 48(r1). At PC 62200, the value is loaded, but it is loaded with an lwa instruction, which sign extends the value. This corresponds to the Go expression uint64(uint32(i32)), which should zero extend the value, presumably using lwz.
This is a miscompilation of valid code so it is a release blocker for 1.12.
CC @randall77 @laboger
This file is miscompiled on ppc64le:
On amd64 with tip, or on ppc64le with Go 1.11.5, this program runs without error. On ppc64le GNU/Linux with tip, the program panics:
Using objdump to look at the executable, I see this:
The variable
i32is stored at48(r1). At PC62200, the value is loaded, but it is loaded with anlwainstruction, which sign extends the value. This corresponds to the Go expressionuint64(uint32(i32)), which should zero extend the value, presumably usinglwz.This is a miscompilation of valid code so it is a release blocker for 1.12.
CC @randall77 @laboger