The bswap pass contain the following loop:

for (i = 0; i < size; i++, inc <<= BITS_PER_MARKER)

In the update to inc and i just before exiting the loop, inc can be shifted by 
a total of more than 62bit, making the value too large to be represented by 
int64_t. This is an undefined behavior [1] and it triggers an error under an 
ubsan bootstrap. This patch change the type of inc to be unsigned, removing the 
undefined behavior.

[1] C++ 98 standard section 5.8 paragraph 2:

"The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are 
zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2 , 
reduced modulo one more than the maximum value representable in the result 
type. Otherwise, if E1 has a signed type and non-negative value, and E1 × 2E2 
is representable in the corresponding unsigned type of the result type, then 
that value, converted to the result type, is the resulting value; otherwise, the
behavior is undefined."

ChangeLog entry is as follows:

2015-07-28  Thomas Preud'homme  <thomas.preudho...@arm.com>

        PR tree-optimization/66828
        * tree-ssa-math-opts.c (perform_symbolic_merge): Change type of inc
        from int64_t to uint64_t.

Testsuite was run on a native x86_64-linux-gnu bootstrapped GCC and an 
arm-none-eabi cross-compiler without any regression. Committed as obvious as 
suggested by  Markus Trippelsdorf in PR66828.

Best regards,

Thomas


Reply via email to