This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/67781] [5/6 Regression] wrong code generated on big-endian with -O1 -fexpensive-optimizations


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67781

--- Comment #8 from Thomas Preud'homme <thopre01 at gcc dot gnu.org> ---
Looking more into find_bswap_or_nop, it became clear that the rsize loop is
fine for both endianness because it operates on the result of the expression
being analyzed and that result lies in register.

it's the cmpxchg and cmpnop bit manipulation below that need changing instead.
the rsize loop is fine for both endianness because it operates on the result of
the expression being analyzed and the result is in register.

So it became clear that the cmpxchg and cmpnop bit manipulation were to blame
instead. They are tasked of computing what to compare the result of the
symbolic execution against. They fail to account that in the case of a memory
source, some bytes at either end of the memory range can be lost and there
would be no 0 in the symbolic number result. They currently only deal with the
most significant bytes being lost.

However, note how this mistake is not endian specific: it is true for both end
of a symbolic number. The reason for the asymmetry between little endian and
big endian is that the current code will always do the load from the lowest
address of all sources in the expression being analyzed.

This work fine for little endian since the most significant bytes are at the
highest address so doing a smaller load is sufficient, and the real range
computation in the rsize loop takes care of this. It fails for big endian
targets though, where the most significant byte are at the lowest address and
the current code does not adjust the address of the load accordingly.

The right fix would thus be to change the cmpxchg and cmpnop computation to
remove the least significant bytes lost in the expression (by comparing rsize
against the range returned by find_bswap_or_nop_1). And this shows a possible
improvement: add code to change the address of the load to allow both end of
the symbolic number to be truncated.

So I'll spin a patch tomorrow and hopefully propose a valid fix for GCC 5 and 6
by the following day.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]