diff options
author | Richard Guenther <rguenther@suse.de> | 2007-11-12 13:24:06 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2007-11-12 13:24:06 +0000 |
commit | 65648dd47e35451645d3f2fb2cdcd02cf43e1d87 (patch) | |
tree | 1748ca812d38b49f003e3b8885790ebee8e08000 | |
parent | 50d76c246f1268b945c941c24d877b7acc5acae9 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/fold-const.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr34027-1.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr34027-2.c | 10 |
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" } } */ |