A coworker suggested I try with optimizations off: [tolsen@rhel74-z-dev.dallasisv.build ~]$ go version go version go1.21.4 linux/s390x [tolsen@rhel74-z-dev.dallasisv.build ~]$ go build -o /tmp/scratch_1 scratch_1.go [tolsen@rhel74-z-dev.dallasisv.build ~]$ /tmp/scratch_1 ABCDEF12 ABCDEF12000000 [tolsen@rhel74-z-dev.dallasisv.build ~]$ go build -gcflags='-N' -o /tmp/scratch_1 scratch_1.go [tolsen@rhel74-z-dev.dallasisv.build ~]$ /tmp/scratch_1 ABCDEF12 ABCDEF12 [tolsen@rhel74-z-dev.dallasisv.build ~]$ export GOROOT=/opt/golang/go1.20.11 [tolsen@rhel74-z-dev.dallasisv.build ~]$ export PATH=${GOROOT}/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/ibm/java-s390x-80/bin:/home/tolsen/.local/bin:/home/tolsen/bin [tolsen@rhel74-z-dev.dallasisv.build ~]$ go build -o /tmp/scratch_1 scratch_1.go [tolsen@rhel74-z-dev.dallasisv.build ~]$ /tmp/scratch_1 ABCDEF12 ABCDEF12 [tolsen@rhel74-z-dev.dallasisv.build ~]$
That further confirms a bug with optimizations on s390x (and possibly other big endian machines?) . -Tim On Tue, Nov 28, 2023 at 4:36 PM 'tim....@mongodb.com' via golang-nuts < golang-nuts@googlegroups.com> wrote: > Hello, > > I believe I've found a code-optimization bug in Go 1.21.4 on Linux s390x. > This is what I was able to narrow the code sample down to: > > ////////// > package main > > import "fmt" > > type myStruct struct { > A uint32 > B uint32 > } > > func doOpOnStructElems(a, b uint32) uint64 { > return (uint64(a) << 32) | uint64(b) > } > > func main() { > myVal := myStruct{0, 0xABCDEF12} > > passAsMyStructAndThenDoOp(myVal) > passAsIfaceAndThenDoOp(myVal) > } > > func passAsMyStructAndThenDoOp(myVal myStruct) { > fmt.Printf("%X\n", doOpOnStructElems(myVal.A, myVal.B)) > } > > func passAsIfaceAndThenDoOp(myIface interface{}) { > fmt.Printf("%X\n", doOpOnStructElems(myIface.(myStruct).A, > myIface.(myStruct).B)) > } > //////// > > When I run it I get: > > ///// > > $ go run scratch_1.go > > ABCDEF12 > > ABCDEF12000000 > ////// > > If I run it on Linux zSeries w/ Go 1.20.11 or on Linux AMD64, Linux ARM64, > or macOS w/ Go 1.21.4, I get what I believe is the correct answer: > > //// > > $ go run scratch_1.go > > ABCDEF12 > > ABCDEF12 > > //// > > In other words, with Go 1.21.4 and s390x it appears that A & B are > switched in the 2nd call which passes the struct as an interface{} . > > s390x is the only big endian platform I am able to test on. So I suspect > there may be an endianness issue here. I suspect something has gone wrong > with some sort of code optimization because if I insert Println() at the > beginning of doOpOnStructElems(), the problem goes away. So it's possible > there's some bug with code inlining when what is being passed in was > originally passed in as an interface in the caller? > > If someone could confirm that this is indeed a bug I will be happy to file > an issue. > > Thank you, > > Tim > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAJJHkehymkxVArO5n--H4boq0S4JeUfDSE3bs8pJD12FaDibuA%40mail.gmail.com.