golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.52k stars 17.6k forks source link

cmd/gc: arm codegen bug #9604

Closed allgoewer closed 9 years ago

allgoewer commented 9 years ago

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:

package main

import "fmt"

func bug() bool {
        b := byte(0xFF)
        return ^b == 0
}

func main() {
        fmt.Println(bug())
}

On amd64 the snippet correctly prints "true", whereas on arm it prints "false".

See https://groups.google.com/forum/m/#!topic/golang-nuts/WHATTQezbWo

bradfitz commented 9 years ago

/cc @rsc @minux @josharian

davecheney commented 9 years ago

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.

siritinga commented 9 years ago

It gives false in the Raspberry in go1.3.3, go1.4 and tip. With gccgo, it gives true.

mwhudson commented 9 years ago

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
randall77 commented 9 years ago

CL out for review https://go-review.googlesource.com/2940