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.

Reply via email to