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.

Reply via email to