From de097a3b99ba39804410a1a1c06412cd2dd9f1d1 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 10 Sep 2006 23:27:36 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 7 ++++ gcc/combine.c | 27 ++++++++------ gcc/testsuite/ChangeLog | 4 ++ .../gcc.c-torture/execute/20060910-1.c | 37 +++++++++++++++++++ 4 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20060910-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c4066f353b2..bbf36261fb9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2006-09-10 Eric Botcazou + + 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 PR middle-end/26983 diff --git a/gcc/combine.c b/gcc/combine.c index 727e625ae2c..0f4ea02970f 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 55eee6b1505..45bd6ed94b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-09-10 Eric Botcazou + + * gcc.c-torture/execute/20060910-1.c: New test. + 2006-09-10 Steven Bosscher PR middle-end/26983 diff --git a/gcc/testsuite/gcc.c-torture/execute/20060910-1.c b/gcc/testsuite/gcc.c-torture/execute/20060910-1.c new file mode 100644 index 00000000000..78bf301397f --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20060910-1.c @@ -0,0 +1,37 @@ +/* PR rtl-optimization/28636 */ +/* Origin: Andreas Schwab */ + +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; +} -- 2.30.2