Closed allgoewer closed 9 years ago
/cc @rsc @minux @josharian
Investigating a bit
package main
import "fmt"
func main() {
a := uint8(0xff)
fmt.Println(^a == 0)
b := uint16(0xffff)
fmt.Println(^b == 0)
c := uint32(0xffffffff)
fmt.Println(^c == 0)
d := uint64(0xffffffffffffffff)
fmt.Println(^d == 0)
}
should print true four times, on arm it prints false twice, then true twice. Moving the ^ operator out of the comparison does not trigger the bug.
It gives false in the Raspberry in go1.3.3, go1.4 and tip. With gccgo, it gives true.
The result of the ^ operator is not being rounded back to a uint8 before the comparison (ARM syntax assembly):
00010c00 <main.bug>:
10c00: e3a00000 mov r0, #0
10c04: e3a000ff mov r0, #255 ; 0xff
10c08: e20000ff and r0, r0, #255 ; 0xff
10c0c: e1e01000 mvn r1, r0 <<< the ^ operator
10c10: e3510000 cmp r1, #0 <<< the comparison comparing the whole word
10c14: 0a000002 beq 10c24 <main.bug+0x24>
10c18: e3a00000 mov r0, #0
10c1c: e5cd0004 strb r0, [sp, #4]
10c20: e28ef000 add pc, lr, #0
10c24: e3a00001 mov r0, #1
10c28: e5cd0004 strb r0, [sp, #4]
10c2c: e28ef000 add pc, lr, #0
CL out for review https://go-review.googlesource.com/2940
I recently found a misbehaviour between
go 1.4 linux/amd64 running on my laptop and go 1.4 linux/arm running on Archlinuxarm on the raspberry pi
The code of concern is the following:
On amd64 the snippet correctly prints "true", whereas on arm it prints "false".
See https://groups.google.com/forum/m/#!topic/golang-nuts/WHATTQezbWo