diff options
author | Richard Biener <rguenther@suse.de> | 2013-02-25 15:31:31 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-02-25 15:31:31 +0000 |
commit | 259ee451e5455640a2ca975d45725496e08fab8e (patch) | |
tree | 2fae06852bcfc3d5f8c5c7798fab758d652f646e /gcc | |
parent | 5621a5d7b10710eb5dac52ee668c711bcc42fa72 (diff) | |
download | gcc-259ee451e5455640a2ca975d45725496e08fab8e.zip gcc-259ee451e5455640a2ca975d45725496e08fab8e.tar.gz gcc-259ee451e5455640a2ca975d45725496e08fab8e.tar.bz2 |
re PR tree-optimization/56175 (Issue with combine phase on x86.)
2013-02-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/56175
* tree-ssa-forwprop.c (hoist_conversion_for_bitop_p): New predicate,
split out from ...
(simplify_bitwise_binary): ... here. Also guard the conversion
of (type) X op CST to (type) (X op ((type-x) CST)) with it.
* gcc.dg/tree-ssa/forwprop-24.c: New testcase.
From-SVN: r196263
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/forwprop-24.c | 18 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 37 |
4 files changed, 58 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 13fad12..ec210d6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2013-02-25 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56175 + * tree-ssa-forwprop.c (hoist_conversion_for_bitop_p): New predicate, + split out from ... + (simplify_bitwise_binary): ... here. Also guard the conversion + of (type) X op CST to (type) (X op ((type-x) CST)) with it. + 2013-02-25 Catherine Moore <clm@codesourcery.com> Revert: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a33bed4..bd2b6d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-02-25 Richard Biener <rguenther@suse.de> + + PR tree-optimization/56175 + * gcc.dg/tree-ssa/forwprop-24.c: New testcase. + 2013-02-24 Jakub Jelinek <jakub@redhat.com> PR c++/56403 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-24.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-24.c new file mode 100644 index 0000000..74207cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-24.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-cddce1" } */
+
+void bar (void);
+unsigned short
+foo (unsigned char x, unsigned short y)
+{
+ unsigned char t = (unsigned char)((x & 1) ^ ((unsigned char)y & 1));
+ if (t == 1)
+ bar ();
+ return y;
+}
+
+/* We should have combined this to require only one bitwise and
+ as in (x ^ (char) y) & 1. */
+
+/* { dg-final { scan-tree-dump-times " & " 1 "cddce1" } } */
+/* { dg-final { cleanup-tree-dump "cddce1" } } */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 855c212..edcf929 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -1772,6 +1772,29 @@ defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2) /* Ignore arg3 currently. */ } +/* Return true if a conversion of an operand from type FROM to type TO + should be applied after performing the operation instead. */ + +static bool +hoist_conversion_for_bitop_p (tree to, tree from) +{ + /* That's a good idea if the conversion widens the operand, thus + after hoisting the conversion the operation will be narrower. */ + if (TYPE_PRECISION (from) < TYPE_PRECISION (to)) + return true; + + /* It's also a good idea if the conversion is to a non-integer mode. */ + if (GET_MODE_CLASS (TYPE_MODE (to)) != MODE_INT) + return true; + + /* Or if the precision of TO is not the same as the precision + of its mode. */ + if (TYPE_PRECISION (to) != GET_MODE_PRECISION (TYPE_MODE (to))) + return true; + + return false; +} + /* Simplify bitwise binary operations. Return true if a transformation applied, otherwise return false. */ @@ -1789,9 +1812,11 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi) defcodefor_name (arg1, &def1_code, &def1_arg1, &def1_arg2); defcodefor_name (arg2, &def2_code, &def2_arg1, &def2_arg2); - /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST)). */ + /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST)) + when profitable. */ if (TREE_CODE (arg2) == INTEGER_CST && CONVERT_EXPR_CODE_P (def1_code) + && hoist_conversion_for_bitop_p (TREE_TYPE (arg1), TREE_TYPE (def1_arg1)) && INTEGRAL_TYPE_P (TREE_TYPE (def1_arg1)) && int_fits_type_p (arg2, TREE_TYPE (def1_arg1))) { @@ -1816,15 +1841,7 @@ simplify_bitwise_binary (gimple_stmt_iterator *gsi) if (CONVERT_EXPR_CODE_P (def1_code) && CONVERT_EXPR_CODE_P (def2_code) && types_compatible_p (TREE_TYPE (def1_arg1), TREE_TYPE (def2_arg1)) - /* Make sure that the conversion widens the operands, or has same - precision, or that it changes the operation to a bitfield - precision. */ - && ((TYPE_PRECISION (TREE_TYPE (def1_arg1)) - <= TYPE_PRECISION (TREE_TYPE (arg1))) - || (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (arg1))) - != MODE_INT) - || (TYPE_PRECISION (TREE_TYPE (arg1)) - != GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (arg1)))))) + && hoist_conversion_for_bitop_p (TREE_TYPE (arg1), TREE_TYPE (def1_arg1))) { gimple newop; tree tem = make_ssa_name (TREE_TYPE (def1_arg1), NULL); |