summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2006-09-10 21:27:36 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2006-09-10 21:27:36 +0000
commit7bb0bd010747ea3893c4c475534f3950e059ce6d (patch)
treed3c5020c21152292317e1a64bd9a4574e3d04193
parent32acc84a1f344f5ebfb5c81ed6665542c56c2880 (diff)
downloadgcc-7bb0bd010747ea3893c4c475534f3950e059ce6d.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@116827 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/combine.c27
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20060910-1.c37
4 files changed, 63 insertions, 12 deletions
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 <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
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 <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
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 <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;
+}