re PR rtl-optimization/28636 (Miscompiled loop)

PR rtl-optimization/28636
	* combine.c (force_to_mode): Test for side-effects before
	substituting by zero.
	(simplify_shift_const): Likewise for zero or other constants.

From-SVN: r116827
This commit is contained in:
Eric Botcazou 2006-09-10 23:27:36 +02:00 committed by Eric Botcazou
parent 4fe337f67a
commit de097a3b99
4 changed files with 63 additions and 12 deletions

View File

@ -1,3 +1,10 @@
2006-09-10 Eric Botcazou <ebotcazou@libertysurf.fr>
PR rtl-optimization/28636
* combine.c (force_to_mode): Test for side-effects before
substituting by zero.
(simplify_shift_const): Likewise for zero or other constants.
2006-09-10 Steven Bosscher <steven@gcc.gnu.org>
PR middle-end/26983

View File

@ -6860,7 +6860,7 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
nonzero = nonzero_bits (x, mode);
/* If none of the bits in X are needed, return a zero. */
if (! just_select && (nonzero & mask) == 0)
if (!just_select && (nonzero & mask) == 0 && !side_effects_p (x))
x = const0_rtx;
/* If X is a CONST_INT, return a new one. Do this here since the
@ -8637,14 +8637,14 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
== 0))
code = LSHIFTRT;
if (code == LSHIFTRT
&& GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
&& !(nonzero_bits (varop, shift_mode) >> count))
varop = const0_rtx;
if (code == ASHIFT
&& GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
&& !((nonzero_bits (varop, shift_mode) << count)
& GET_MODE_MASK (shift_mode)))
if (((code == LSHIFTRT
&& GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
&& !(nonzero_bits (varop, shift_mode) >> count))
|| (code == ASHIFT
&& GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
&& !((nonzero_bits (varop, shift_mode) << count)
& GET_MODE_MASK (shift_mode))))
&& !side_effects_p (varop))
varop = const0_rtx;
switch (GET_CODE (varop))
@ -9229,9 +9229,12 @@ simplify_shift_const_1 (enum rtx_code code, enum machine_mode result_mode,
if (outer_op == AND)
x = simplify_and_const_int (NULL_RTX, result_mode, x, outer_const);
else if (outer_op == SET)
/* This means that we have determined that the result is
equivalent to a constant. This should be rare. */
x = GEN_INT (outer_const);
{
/* This means that we have determined that the result is
equivalent to a constant. This should be rare. */
if (!side_effects_p (x))
x = GEN_INT (outer_const);
}
else if (GET_RTX_CLASS (outer_op) == RTX_UNARY)
x = simplify_gen_unary (outer_op, result_mode, x, result_mode);
else

View File

@ -1,3 +1,7 @@
2006-09-10 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/execute/20060910-1.c: New test.
2006-09-10 Steven Bosscher <steven@gcc.gnu.org>
PR middle-end/26983

View File

@ -0,0 +1,37 @@
/* PR rtl-optimization/28636 */
/* Origin: Andreas Schwab <schwab@suse.de> */
extern void abort(void);
struct input_ty
{
unsigned char *buffer_position;
unsigned char *buffer_end;
};
int input_getc_complicated (struct input_ty *x) { return 0; }
int check_header (struct input_ty *deeper)
{
unsigned len;
for (len = 0; len < 6; len++)
if (((deeper)->buffer_position < (deeper)->buffer_end
? *((deeper)->buffer_position)++
: input_getc_complicated((deeper))) < 0)
return 0;
return 1;
}
struct input_ty s;
unsigned char b[6];
int main (void)
{
s.buffer_position = b;
s.buffer_end = b + sizeof b;
if (!check_header(&s))
abort();
if (s.buffer_position != s.buffer_end)
abort();
return 0;
}