aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2008-08-22 12:43:49 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2008-08-22 12:43:49 +0000
commitbeeab17c6ed0733203002932c08d1d3f3fe5d053 (patch)
tree3d71422e6cc09e286c8804aef278b4add145989a
parentda2f5d14dfc05f9a9527ea3e0700a345857a83bc (diff)
downloadgcc-beeab17c6ed0733203002932c08d1d3f3fe5d053.zip
gcc-beeab17c6ed0733203002932c08d1d3f3fe5d053.tar.gz
gcc-beeab17c6ed0733203002932c08d1d3f3fe5d053.tar.bz2
re PR middle-end/36548 (remainder gives the wrong result for wrapping case with unsigned types)
2008-08-22 Richard Guenther <rguenther@suse.de> PR middle-end/36548 PR middle-end/37125 * fold-const.c (extract_muldiv_1): Optimize (X * C1) % C2 only if the multiplication does not overflow. * gcc.c-torture/execute/pr37125.c: New testcase. From-SVN: r139450
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/fold-const.c13
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr37125.c23
4 files changed, 48 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f788ef8..592b28c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2008-08-22 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/36548
+ PR middle-end/37125
+ * fold-const.c (extract_muldiv_1): Optimize (X * C1) % C2 only
+ if the multiplication does not overflow.
+
2008-08-21 Nathan Sidwell <nathan@codesourcery.com>
* c-ppoutput.c (init_pp_output): Initialize src_line to 1.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index cba8826..e6769a6 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -5930,9 +5930,20 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
(C * 8) % 4 since we know that's zero. */
if ((code == TRUNC_MOD_EXPR || code == CEIL_MOD_EXPR
|| code == FLOOR_MOD_EXPR || code == ROUND_MOD_EXPR)
+ /* If the multiplication can overflow we cannot optimize this.
+ ??? Until we can properly mark individual operations as
+ not overflowing we need to treat sizetype special here as
+ stor-layout relies on this opimization to make
+ DECL_FIELD_BIT_OFFSET always a constant. */
+ && (TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t))
+ || (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+ && TYPE_IS_SIZETYPE (TREE_TYPE (t))))
&& TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST
&& integer_zerop (const_binop (TRUNC_MOD_EXPR, op1, c, 0)))
- return omit_one_operand (type, integer_zero_node, op0);
+ {
+ *strict_overflow_p = true;
+ return omit_one_operand (type, integer_zero_node, op0);
+ }
/* ... fall through ... */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ae16c70..061c219 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2008-08-22 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/36548
+ PR middle-end/37125
+ * gcc.c-torture/execute/pr37125.c: New testcase.
+
2008-08-22 Daniel Kraft <d@domob.eu>
* gfortran.dg/used_before_typed_4.f90: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr37125.c b/gcc/testsuite/gcc.c-torture/execute/pr37125.c
new file mode 100644
index 0000000..f29209e
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr37125.c
@@ -0,0 +1,23 @@
+extern void abort (void);
+
+static inline unsigned int
+mod_rhs(int rhs)
+{
+ if (rhs == 0) return 1;
+ return rhs;
+}
+
+void func_44 (unsigned int p_45);
+void func_44 (unsigned int p_45)
+{
+ if (!((p_45 * -9) % mod_rhs (-9))) {
+ abort();
+ }
+}
+
+int main (void)
+{
+ func_44 (2);
+ return 0;
+}
+