Bug 96594 - Compiled code behaves differently with -O1 and -O0 on s390x
Summary: Compiled code behaves differently with -O1 and -O0 on s390x
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.2.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-08-12 19:03 UTC by Dmitry Shachnev
Modified: 2020-08-12 20:12 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
Test case (561 bytes, text/x-csrc)
2020-08-12 19:03 UTC, Dmitry Shachnev
Details
Assembly dump with -O0 (1.08 KB, text/plain)
2020-08-12 19:04 UTC, Dmitry Shachnev
Details
Assembly dump with -O1 (820 bytes, text/plain)
2020-08-12 19:04 UTC, Dmitry Shachnev
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Shachnev 2020-08-12 19:03:42 UTC
Created attachment 49050 [details]
Test case

Hi,

I was debugging Compiz test failures that started happening on Debian/Ubuntu s390x in July. They are not directly related to GCC upgrade (old GCC 8 behaves the same way), however I noticed a strange thing that I want to report here.

The attached file behaves differently when built with -O0 and -O1:

$ g++ test.cpp -g -O1 -lX11
$ xvfb-run ./a.out
setting value = 0x1020304
got value = 0xffffffff

$ g++ test.cpp -g -O0 -lX11
$ xvfb-run ./a.out
setting value = 0x1020304
got value = 0x0

And both these behaviors are wrong! Expected behavior is (as seen on x86_64):

$ xvfb-run ./a.out 
setting value = 0x1020304
got value = 0x1020304

However, this bug is about differing behaviors with -O1 and -O0.

The only dependency of this file is Xlib. So far I was not able to make an example that does not depend on it.

I wanted to bisect a particular optimization that causes this behavior change, but even with all options from https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-O1 it behaves like -O0.

Some more things I noticed:

- Moving GetProperty and SetProperty functions away from the namespace makes it behave like -O0.

- Adding __attribute__((noinline)) to SetProperty makes it behave like -O0. So the bug may be related to inlining.

I am also attaching assembly dumps with -O1 and -O0.
Comment 1 Dmitry Shachnev 2020-08-12 19:04:17 UTC
Created attachment 49051 [details]
Assembly dump with -O0
Comment 2 Dmitry Shachnev 2020-08-12 19:04:38 UTC
Created attachment 49052 [details]
Assembly dump with -O1
Comment 3 Jakub Jelinek 2020-08-12 19:40:10 UTC
That is just a user error, you didn't read the XChangeProperty man page.
"If the specified format is 16, the property data must be a short
array.  If the specified format is 32, the property data must be a long array."
You are using 32, and I assume you are doing this on 64-bit s390x, i.e. where long is 64-bit, so while it sounds weird, libX11 requires you to put the property into a long or unsigned long variable and pass address of that (and read it through that too).
It kind of "works" on x86_64, because it is little-endian, so you just have random bits in the upper 32 bits of the long that the library actually reads and perhaps it casts it to a 32-bit type later on.
But s390x is big endian, so if you call it with address of a 32-bit variable, the low 32 bits of that are the 32 bits after your variable and can contain arbitrary random values.
Comment 4 Dmitry Shachnev 2020-08-12 20:12:13 UTC
Thanks a lot for the fast response!

Indeed, your suggestion works. It is counter-intuitive that you need a 64-bit variable to store a 32-bit value, but I can see the rationale (long is the only standard type that is guaranteed to be 32-bits).