A coworker suggested I try with optimizations off: [[email protected] ~]$ go version go version go1.21.4 linux/s390x [[email protected] ~]$ go build -o /tmp/scratch_1 scratch_1.go [[email protected] ~]$ /tmp/scratch_1 ABCDEF12 ABCDEF12000000 [[email protected] ~]$ go build -gcflags='-N' -o /tmp/scratch_1 scratch_1.go [[email protected] ~]$ /tmp/scratch_1 ABCDEF12 ABCDEF12 [[email protected] ~]$ export GOROOT=/opt/golang/go1.20.11 [[email protected] ~]$ 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 [[email protected] ~]$ go build -o /tmp/scratch_1 scratch_1.go [[email protected] ~]$ /tmp/scratch_1 ABCDEF12 ABCDEF12 [[email protected] ~]$
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 '[email protected]' via golang-nuts < [email protected]> 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAJJHkehymkxVArO5n--H4boq0S4JeUfDSE3bs8pJD12FaDibuA%40mail.gmail.com.
