It seems strange that the bad result is ABCDEF12000000 and not ABCDEF1200000000. i.e., 6 zeros and not 8. Can you confirm?
Definitely sounds like a bug to me. You should open an issue. On Tuesday, November 28, 2023 at 1:44:59 PM UTC-8 Timothy Olsen wrote: > A coworker suggested I try with optimizations off: > > [tol...@rhel74-z-dev.dallasisv.build ~]$ go version > go version go1.21.4 linux/s390x > [tol...@rhel74-z-dev.dallasisv.build ~]$ go build -o /tmp/scratch_1 > scratch_1.go > [tol...@rhel74-z-dev.dallasisv.build ~]$ /tmp/scratch_1 > ABCDEF12 > ABCDEF12000000 > [tol...@rhel74-z-dev.dallasisv.build ~]$ go build -gcflags='-N' -o > /tmp/scratch_1 scratch_1.go > [tol...@rhel74-z-dev.dallasisv.build ~]$ /tmp/scratch_1 > ABCDEF12 > ABCDEF12 > [tol...@rhel74-z-dev.dallasisv.build ~]$ export > GOROOT=/opt/golang/go1.20.11 > [tol...@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 > [tol...@rhel74-z-dev.dallasisv.build ~]$ go build -o /tmp/scratch_1 > scratch_1.go > [tol...@rhel74-z-dev.dallasisv.build ~]$ /tmp/scratch_1 > ABCDEF12 > ABCDEF12 > [tol...@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 < > golan...@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/b2a37dfc-7b6a-412a-8cbb-40a2210d6921n%40googlegroups.com.