This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PRs 27132, 23295 and 29548
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 22 Oct 2006 20:43:50 +0200 (CEST)
- Subject: [PATCH] Fix PRs 27132, 23295 and 29548
These two patches fix some long-standing fold missing-optimizations.
One is folding of i - -1 to i + 1, another is a similar optimization,
optimizing -a - 5 to -5 - a. Implementing this causes quite some fallout,
both in testsuite pattern matching and PR29548 where we miss to fold
b * -2 + a * 6 to (b + a * -3) * -2 and in turn that to (a * 3 - b) * 2,
which we expect for ivopts.
Bootstrapped and tested both patches together on x86_64-unknown-linux-gnu.
Ok for mainline?
Thanks,
Richard.
:ADDPATCH middle-end:
2006-10-22 Richard Guenther <rguenther@suse.de>
PR middle-end/27132
PR middle-end/23295
* builtins.c (fold_binary): Remove checks for flag_wrapv
and flag_trapv where negate_expr_p covers these cases.
* gcc.dg/pr27132.c: New testcase.
* gcc.dg/pr23295.c: Likewise.
* gcc.dg/tree-ssa/pr23294.c: Adjust patterns.
* g++.dg/tree-ssa/pr19807.C: Likewise.
Index: fold-const.c
===================================================================
*** fold-const.c (revision 117952)
--- fold-const.c (working copy)
*************** fold_binary (enum tree_code code, tree t
*** 8752,8758 ****
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR
&& (FLOAT_TYPE_P (type)
! || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv))
&& negate_expr_p (arg1)
&& reorder_operands_p (arg0, arg1))
return fold_build2 (MINUS_EXPR, type, negate_expr (arg1),
--- 8752,8758 ----
/* (-A) - B -> (-B) - A where B is easily negated and we can swap. */
if (TREE_CODE (arg0) == NEGATE_EXPR
&& (FLOAT_TYPE_P (type)
! || INTEGRAL_TYPE_P (type))
&& negate_expr_p (arg1)
&& reorder_operands_p (arg0, arg1))
return fold_build2 (MINUS_EXPR, type, negate_expr (arg1),
*************** fold_binary (enum tree_code code, tree t
*** 8838,8844 ****
/* Avoid this transformation if B is a positive REAL_CST. */
&& (TREE_CODE (arg1) != REAL_CST
|| REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
! || (INTEGRAL_TYPE_P (type) && flag_wrapv && !flag_trapv)))
return fold_build2 (PLUS_EXPR, type,
fold_convert (type, arg0),
fold_convert (type, negate_expr (arg1)));
--- 8838,8844 ----
/* Avoid this transformation if B is a positive REAL_CST. */
&& (TREE_CODE (arg1) != REAL_CST
|| REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
! || INTEGRAL_TYPE_P (type)))
return fold_build2 (PLUS_EXPR, type,
fold_convert (type, arg0),
fold_convert (type, negate_expr (arg1)));
Index: testsuite/gcc.dg/pr27132.c
===================================================================
*** testsuite/gcc.dg/pr27132.c (revision 0)
--- testsuite/gcc.dg/pr27132.c (revision 0)
***************
*** 0 ****
--- 1,10 ----
+ /* { dg-do compile } */
+ /* { dg-options "-fdump-tree-gimple" } */
+
+ int foo(int i)
+ {
+ return i - -1;
+ }
+
+ /* { dg-final { scan-tree-dump "i \\+ 1" "gimple" } } */
+ /* { dg-final { cleanup-tree-dump "gimple" } } */
Index: testsuite/gcc.dg/pr23295.c
===================================================================
*** testsuite/gcc.dg/pr23295.c (revision 0)
--- testsuite/gcc.dg/pr23295.c (revision 0)
***************
*** 0 ****
--- 1,10 ----
+ /* { dg-do compile } */
+ /* { dg-options "-fdump-tree-gimple" } */
+
+ int foo(int i)
+ {
+ return -i - 5;
+ }
+
+ /* { dg-final { scan-tree-dump "-5 - i" "gimple" } } */
+ /* { dg-final { cleanup-tree-dump "gimple" } } */
Index: testsuite/gcc.dg/tree-ssa/pr23294.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/pr23294.c (revision 117952)
--- testsuite/gcc.dg/tree-ssa/pr23294.c (working copy)
*************** int f6(int a, int b)
*** 32,38 ****
}
/* { dg-final { scan-tree-dump-times "a \\\* 5" 3 "optimized" } } */
! /* { dg-final { scan-tree-dump "\\\(b \\\* 3 \\\+ a\\\) \\\* 2" "optimized" } } */
! /* { dg-final { scan-tree-dump "\\\(a - b \\\* 3\\\) \\\* 2" "optimized" } } */
! /* { dg-final { scan-tree-dump "\\\(a \\\* 3 - b\\\) \\\* 2" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
--- 32,37 ----
}
/* { dg-final { scan-tree-dump-times "a \\\* 5" 3 "optimized" } } */
! /* { dg-final { scan-tree-dump-times "\\\) \\\* 2" 3 "optimized" } } */
! /* { dg-final { scan-tree-dump-not "\\\* 6" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
Index: testsuite/g++.dg/tree-ssa/pr19807.C
===================================================================
*** testsuite/g++.dg/tree-ssa/pr19807.C (revision 117952)
--- testsuite/g++.dg/tree-ssa/pr19807.C (working copy)
*************** void bar(int i)
*** 19,24 ****
}
/* { dg-final { scan-tree-dump-times "&a\\\[2\\\]" 3 "optimized" } } */
! /* { dg-final { scan-tree-dump-times "&a\\\[.* - 1\\\]" 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "&a\\\[.* \\+ 1\\\]" 1 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
--- 19,24 ----
}
/* { dg-final { scan-tree-dump-times "&a\\\[2\\\]" 3 "optimized" } } */
! /* { dg-final { scan-tree-dump-times "&a\\\[.* \\+ -1\\\]" 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "&a\\\[.* \\+ 1\\\]" 1 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
2006-10-22 Richard Guenther <rguenther@suse.de>
PR middle-end/29548
* fold-const.c (fold_plusminus_mult_expr): Check exact power
of two on the absolute value.
(fold_binary): Fold x * -C to -x * C if x is easily negatable
and negating -C does not overflow.
Index: fold-const.c
===================================================================
*** fold-const.c (revision 117952)
--- fold-const.c (working copy)
*************** fold_plusminus_mult_expr (enum tree_code
*** 6787,6793 ****
else
maybe_same = arg11;
! if (exact_log2 (int11) > 0 && int01 % int11 == 0)
{
alt0 = fold_build2 (MULT_EXPR, TREE_TYPE (arg00), arg00,
build_int_cst (TREE_TYPE (arg00),
--- 6787,6793 ----
else
maybe_same = arg11;
! if (exact_log2 (abs (int11)) > 0 && int01 % int11 == 0)
{
alt0 = fold_build2 (MULT_EXPR, TREE_TYPE (arg00), arg00,
build_int_cst (TREE_TYPE (arg00),
*************** fold_binary (enum tree_code code, tree t
*** 8923,8928 ****
--- 8923,8936 ----
/* Transform x * -1 into -x. */
if (integer_all_onesp (arg1))
return fold_convert (type, negate_expr (arg0));
+ /* Transform x * -C into -x * C if x is easily negatable. */
+ if (TREE_CODE (arg1) == INTEGER_CST
+ && tree_int_cst_sgn (arg1) == -1
+ && negate_expr_p (arg0)
+ && (tem = negate_expr (arg1)) != arg1
+ && !TREE_OVERFLOW (tem))
+ return fold_build2 (MULT_EXPR, type,
+ negate_expr (arg0), tem);
/* (a * (1 << b)) is (a << b) */
if (TREE_CODE (arg1) == LSHIFT_EXPR