aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2007-11-12 13:24:06 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2007-11-12 13:24:06 +0000
commit65648dd47e35451645d3f2fb2cdcd02cf43e1d87 (patch)
tree1748ca812d38b49f003e3b8885790ebee8e08000 /gcc
parent50d76c246f1268b945c941c24d877b7acc5acae9 (diff)
downloadgcc-65648dd47e35451645d3f2fb2cdcd02cf43e1d87.zip
gcc-65648dd47e35451645d3f2fb2cdcd02cf43e1d87.tar.gz
gcc-65648dd47e35451645d3f2fb2cdcd02cf43e1d87.tar.bz2
re PR tree-optimization/34027 (-Os code size nearly doubled)
2007-11-12 Richard Guenther <rguenther@suse.de> PR middle-end/34027 * fold-const.c (fold_binary): Fold n - (n / m) * m to n % m. (fold_binary): Fold unsinged FLOOR_DIV_EXPR to TRUNC_DIV_EXPR. * gcc.dg/pr34027-1.c: New testcase. * gcc.dg/pr34027-2.c: Likewise. From-SVN: r130097
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/fold-const.c36
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/pr34027-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr34027-2.c10
5 files changed, 73 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1093ef3..b95f35d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2007-11-12 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/34027
+ * fold-const.c (fold_binary): Fold n - (n / m) * m to n % m.
+ (fold_binary): Fold unsinged FLOOR_DIV_EXPR to TRUNC_DIV_EXPR.
+
+ * gcc.dg/pr34027-1.c: New testcase.
+ * gcc.dg/pr34027-2.c: Likewise.
+
2007-11-12 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/33953
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index a09c9ea..5b81d88 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -9653,6 +9653,21 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
return omit_one_operand (type, t1, arg0);
}
}
+
+ /* X + (X / CST) * -CST is X % CST. */
+ if (TREE_CODE (arg1) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR
+ && operand_equal_p (arg0,
+ TREE_OPERAND (TREE_OPERAND (arg1, 0), 0), 0))
+ {
+ tree cst0 = TREE_OPERAND (TREE_OPERAND (arg1, 0), 1);
+ tree cst1 = TREE_OPERAND (arg1, 1);
+ tree sum = fold_binary (PLUS_EXPR, TREE_TYPE (cst1), cst1, cst0);
+ if (sum && integer_zerop (sum))
+ return fold_convert (type,
+ fold_build2 (TRUNC_MOD_EXPR,
+ TREE_TYPE (arg0), arg0, cst0));
+ }
}
/* Handle (A1 * C1) + (A2 * C2) with A1, A2 or C1, C2 being the
@@ -10061,6 +10076,19 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
&& integer_all_onesp (arg0))
return fold_build1 (BIT_NOT_EXPR, type, op1);
+
+ /* X - (X / CST) * CST is X % CST. */
+ if (INTEGRAL_TYPE_P (type)
+ && TREE_CODE (arg1) == MULT_EXPR
+ && TREE_CODE (TREE_OPERAND (arg1, 0)) == TRUNC_DIV_EXPR
+ && operand_equal_p (arg0,
+ TREE_OPERAND (TREE_OPERAND (arg1, 0), 0), 0)
+ && operand_equal_p (TREE_OPERAND (TREE_OPERAND (arg1, 0), 1),
+ TREE_OPERAND (arg1, 1), 0))
+ return fold_convert (type,
+ fold_build2 (TRUNC_MOD_EXPR, TREE_TYPE (arg0),
+ arg0, TREE_OPERAND (arg1, 1)));
+
if (! FLOAT_TYPE_P (type))
{
if (integer_zerop (arg0))
@@ -11221,6 +11249,14 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
fold_convert (type, arg0), sh_cnt);
}
}
+
+ /* For unsigned integral types, FLOOR_DIV_EXPR is the same as
+ TRUNC_DIV_EXPR. Rewrite into the latter in this case. */
+ if (INTEGRAL_TYPE_P (type)
+ && TYPE_UNSIGNED (type)
+ && code == FLOOR_DIV_EXPR)
+ return fold_build2 (TRUNC_DIV_EXPR, type, op0, op1);
+
/* Fall thru */
case ROUND_DIV_EXPR:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 476b82b..e224859 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2007-11-12 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/34027
+ * gcc.dg/pr34027-1.c: New testcase.
+ * gcc.dg/pr34027-2.c: Likewise.
+
2007-11-12 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/33953
diff --git a/gcc/testsuite/gcc.dg/pr34027-1.c b/gcc/testsuite/gcc.dg/pr34027-1.c
new file mode 100644
index 0000000..532e497
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr34027-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fdump-tree-optimized" } */
+
+unsigned long foobar(unsigned long ns)
+{
+ while(ns >= 10000L)
+ ns -= 10000L;
+ return ns;
+}
+
+/* { dg-final { scan-tree-dump "ns % 10000" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr34027-2.c b/gcc/testsuite/gcc.dg/pr34027-2.c
new file mode 100644
index 0000000..70c4561
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr34027-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-gimple" } */
+
+long foo(long n, long m)
+{
+ return n - (n / m) * m;
+}
+
+/* { dg-final { scan-tree-dump "n % m" "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */