|
View:
New views
2 Messages
—
Rating Filter:
Alert me
|
|
|
[PATCH] Fix num_sign_bit_copies UMOD handling (PR rtl-optimization/41917)Hi!
This testcase fails on x86_64-linux, because num_sign_bit_copies sees UMOD (reg:SI) (X | 0xfffffffe), so num_sign_bit_copies of the second argument is large, yet it doesn't say anything about the number of sign bits in the result. It can be anything from 0 up to that number. Only when we know that second operand's sign bit is zero and it has more than one sign bit copy (== 0 bits), we know the result has also at least that many sign bit copies (== 0 bits). UDIV handling already has a similar condition like this. Bootstrapped/regtested on x86_64-linux and i686-linux. Ok for trunk/4.4? For trunk we could perhaps optimize more and handle both operands of UMOD similarly and take the larger number of sign bit copies (== 0 most significant bits), as UMOD result is not just < the second operand, but also <= the first operand. 2009-11-03 Jakub Jelinek <jakub@...> PR rtl-optimization/41917 * rtlanal.c (num_sign_bit_copies1) <case UMOD>: If sign bit of second operand isn't known to be 0, return 1. * gcc.c-torture/execute/pr41917.c: New test. --- gcc/rtlanal.c.jj 2009-09-03 09:59:32.000000000 +0200 +++ gcc/rtlanal.c 2009-11-03 10:23:31.000000000 +0100 @@ -4501,8 +4501,16 @@ num_sign_bit_copies1 (const_rtx x, enum known_x, known_mode, known_ret); case UMOD: - /* The result must be <= the second operand. */ - return cached_num_sign_bit_copies (XEXP (x, 1), mode, + /* The result must be <= the second operand. If the second operand + has (or just might have) the high bit set, we know nothing about + the number of sign bit copies. */ + if (bitwidth > HOST_BITS_PER_WIDE_INT) + return 1; + else if ((nonzero_bits (XEXP (x, 1), mode) + & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0) + return 1; + else + return cached_num_sign_bit_copies (XEXP (x, 1), mode, known_x, known_mode, known_ret); case DIV: --- gcc/testsuite/gcc.c-torture/execute/pr41917.c.jj 2009-11-03 10:36:50.000000000 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr41917.c 2009-11-03 10:36:19.000000000 +0100 @@ -0,0 +1,21 @@ +/* PR rtl-optimization/41917 */ + +extern void abort (void); +unsigned int a = 1; + +int +main (void) +{ + unsigned int b, c, d; + + if (sizeof (int) != 4 || (int) 0xc7d24b5e > 0) + return 0; + + c = 0xc7d24b5e; + d = a | -2; + b = (d == 0) ? c : (c % d); + if (b != c) + abort (); + + return 0; +} Jakub |
|
|
Re: [PATCH] Fix num_sign_bit_copies UMOD handling (PR rtl-optimization/41917)On 11/03/09 05:53, Jakub Jelinek wrote:
> Hi! > > This testcase fails on x86_64-linux, because num_sign_bit_copies > sees UMOD (reg:SI) (X | 0xfffffffe), so num_sign_bit_copies of the second > argument is large, yet it doesn't say anything about the number of sign bits > in the result. It can be anything from 0 up to that number. > Only when we know that second operand's sign bit is zero and it has more > than one sign bit copy (== 0 bits), we know the result has also at least > that many sign bit copies (== 0 bits). > UDIV handling already has a similar condition like this. > > Bootstrapped/regtested on x86_64-linux and i686-linux. Ok for trunk/4.4? > > For trunk we could perhaps optimize more and handle both operands of UMOD > similarly and take the larger number of sign bit copies (== 0 most > significant bits), as UMOD result is not just< the second operand, but > also<= the first operand. > > 2009-11-03 Jakub Jelinek<jakub@...> > > PR rtl-optimization/41917 > * rtlanal.c (num_sign_bit_copies1)<case UMOD>: If sign bit of second > operand isn't known to be 0, return 1. > > * gcc.c-torture/execute/pr41917.c: New test. > jeff |
| Free embeddable forum powered by Nabble | Forum Help |