re PR rtl-optimization/80501 (Wrong code w/ a signed char, a shift, and a conversion to int)

PR rtl-optimization/80501
	* combine.c (make_compound_operation_int): Set subreg_code to SET
	even for AND with mask of the sign bit of mode.

	* gcc.c-torture/execute/pr80501.c: New test.

From-SVN: r247129
This commit is contained in:
Jakub Jelinek 2017-04-25 09:29:21 +02:00 committed by Jakub Jelinek
parent 75092192da
commit 31a66be10f
4 changed files with 35 additions and 2 deletions

View File

@ -1,5 +1,9 @@
2017-04-25 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/80501
* combine.c (make_compound_operation_int): Set subreg_code to SET
even for AND with mask of the sign bit of mode.
PR rtl-optimization/80500
* loop-unroll.c (combine_var_copies_in_loop_exit): Call copy_rtx on
sum's initial value.

View File

@ -8170,12 +8170,15 @@ make_compound_operation_int (machine_mode mode, rtx *x_ptr,
|| GET_CODE (inner) == SUBREG
/* (subreg:SI (and:DI (reg:DI) (const_int 0x800000000)) 0)
is (const_int 0), rather than
(subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0). */
(subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0).
Similarly (subreg:QI (and:SI (reg:SI) (const_int 0x80)) 0)
for non-equality comparisons against 0 is not equivalent
to (subreg:QI (lshiftrt:SI (reg:SI) (const_int 7)) 0). */
|| (GET_CODE (inner) == AND
&& CONST_INT_P (XEXP (inner, 1))
&& GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner))
&& exact_log2 (UINTVAL (XEXP (inner, 1)))
>= GET_MODE_BITSIZE (mode))))
>= GET_MODE_BITSIZE (mode) - 1)))
subreg_code = SET;
tem = make_compound_operation (inner, subreg_code);

View File

@ -1,5 +1,8 @@
2017-04-25 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/80501
* gcc.c-torture/execute/pr80501.c: New test.
PR rtl-optimization/80500
* gcc.dg/pr80500.c: New test.

View File

@ -0,0 +1,23 @@
/* PR rtl-optimization/80501 */
signed char v = 0;
static signed char
foo (int x, int y)
{
return x << y;
}
__attribute__((noinline, noclone)) int
bar (void)
{
return foo (v >= 0, __CHAR_BIT__ - 1) >= 1;
}
int
main ()
{
if (sizeof (int) > sizeof (char) && bar () != 0)
__builtin_abort ();
return 0;
}