From: rguenth Date: Mon, 12 Nov 2007 13:24:06 +0000 (+0000) Subject: 2007-11-12 Richard Guenther X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d997554fab3294d8fb2646702dca35f768d30591;p=thirdparty%2Fgcc.git 2007-11-12 Richard Guenther 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@130097 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1093ef3b261c..b95f35d96793 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2007-11-12 Richard Guenther + + 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 PR tree-optimization/33953 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index a09c9ea7ea0e..5b81d88fd572 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 476b82b63bf6..e22485905ac9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-11-12 Richard Guenther + + PR middle-end/34027 + * gcc.dg/pr34027-1.c: New testcase. + * gcc.dg/pr34027-2.c: Likewise. + 2007-11-12 Ira Rosen 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 000000000000..532e4976dc37 --- /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 000000000000..70c4561d0f10 --- /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" } } */