Message ID | 51600373.7050706@redhat.com |
---|---|
State | New |
Headers | show |
On Sat, Apr 6, 2013 at 1:13 PM, Jeff Law <law@redhat.com> wrote: > > > The tree combiner/forward propagator is missing opportunities to collapse > sequences like this: > > _15 = _12 ^ _14; > if (_15 != 0) > > > Into: > > if (_12 != _14) > > The tree combiner/forward propagator builds this tree: > > x ^ y > > Then passes it to canonicalize_cond_expr_cond That is not suitable for the > condition in a gimple COND_EXPR. So canonicalize_cond_expr_cond returns > NULL. Thus combine_cond_expr_cond decides the tree it created isn't useful > and throws it away. > > This patch changes canonicalize_cond_expr to rewrite x ^ y into x != y. The > net result being the tree combiner/forward propagator is able to perform the > desired simplification, eliminating the BIT_XOR_EXPR. > > Bootstrapped and regression tested on x86_64-unknown-linux-gnu. As you can > see from the testcase, these kinds of sequences show up when compiling gcc > itself. > > OK for the trunk? Nice. Ok. Thanks, Richard. > commit 809408a4bde6dfbaf62c5bda9ab7ae6c4447d984 > Author: Jeff Law <law@redhat.com> > Date: Sat Apr 6 05:11:17 2013 -0600 > > * gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into > x != y. > > * gcc.dg/tree-ssa/forwprop-25.c: New test > > diff --git a/gcc/ChangeLog b/gcc/ChangeLog > index b8a6900..44797cc 100644 > --- a/gcc/ChangeLog > +++ b/gcc/ChangeLog > @@ -1,3 +1,8 @@ > +2013-04-06 Jeff Law <law@redhat.com> > + > + * gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into > + x != y. > + > 2013-04-03 Jeff Law <law@redhat.com> > > * Makefile.in (lra-constraints.o): Depend on $(OPTABS_H). > diff --git a/gcc/gimple.c b/gcc/gimple.c > index 785c2f0..cdb6f24 100644 > --- a/gcc/gimple.c > +++ b/gcc/gimple.c > @@ -2958,7 +2958,11 @@ canonicalize_cond_expr_cond (tree t) > t = build2 (TREE_CODE (top0), TREE_TYPE (t), > TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1)); > } > - > + /* For x ^ y use x != y. */ > + else if (TREE_CODE (t) == BIT_XOR_EXPR) > + t = build2 (NE_EXPR, TREE_TYPE (t), > + TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)); > + > if (is_gimple_condexpr (t)) > return t; > > diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog > index dc0b745..601ca66 100644 > --- a/gcc/testsuite/ChangeLog > +++ b/gcc/testsuite/ChangeLog > @@ -1,3 +1,7 @@ > +2013-04-06 Jeff Law <law@redhat.com> > + > + * gcc.dg/tree-ssa/forwprop-25.c: New test > + > 2013-04-03 Jeff Law <law@redhat.com> > > PR tree-optimization/56799 > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c > b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c > new file mode 100644 > index 0000000..cf0c504 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c > @@ -0,0 +1,43 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O1 -fdump-tree-forwprop1" } */ > + > +struct rtx_def; > +typedef struct rtx_def *rtx; > +typedef const struct rtx_def *const_rtx; > +enum machine_mode > +{ > + MAX_MACHINE_MODE, > + NUM_MACHINE_MODES = MAX_MACHINE_MODE > +}; > +extern const char *const mode_name[NUM_MACHINE_MODES]; > +enum mode_class > +{ MODE_RANDOM, MODE_CC, MODE_INT, MODE_PARTIAL_INT, MODE_FRACT, > MODE_UFRACT, > + MODE_ACCUM, MODE_UACCUM, MODE_FLOAT, MODE_DECIMAL_FLOAT, > MODE_COMPLEX_INT, > + MODE_COMPLEX_FLOAT, MODE_VECTOR_INT, MODE_VECTOR_FRACT, > + MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM, > + MODE_VECTOR_FLOAT, MAX_MODE_CLASS }; > +extern const unsigned char mode_class[NUM_MACHINE_MODES]; > +extern const unsigned short mode_precision[NUM_MACHINE_MODES]; > +struct rtx_def > +{ > + __extension__ enum machine_mode mode:8; > +}; > +void > +convert_move (rtx to, rtx from, int unsignedp) > +{ > + enum machine_mode to_mode = ((enum machine_mode) (to)->mode); > + enum machine_mode from_mode = ((enum machine_mode) (from)->mode); > + ((void) > + (!((mode_precision[from_mode] != mode_precision[to_mode]) > + || ((((enum mode_class) mode_class[from_mode]) == MODE_DECIMAL_FLOAT) > != > + (((enum mode_class) mode_class[to_mode]) == > + MODE_DECIMAL_FLOAT))) ? > + fancy_abort ("/home/gcc/virgin-gcc/gcc/expr.c", 380, __FUNCTION__), > + 0 : 0)); > +} > + > +/* { dg-final { scan-tree-dump "Replaced.*!=.*with.*!=.* " "forwprop1"} } > */ > +/* { dg-final { cleanup-tree-dump "forwprop1" } } */ > + > + > + >
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8a6900..44797cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2013-04-06 Jeff Law <law@redhat.com> + + * gimple.c (canonicalize_cond_expr_cond): Rewrite x ^ y into + x != y. + 2013-04-03 Jeff Law <law@redhat.com> * Makefile.in (lra-constraints.o): Depend on $(OPTABS_H). diff --git a/gcc/gimple.c b/gcc/gimple.c index 785c2f0..cdb6f24 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -2958,7 +2958,11 @@ canonicalize_cond_expr_cond (tree t) t = build2 (TREE_CODE (top0), TREE_TYPE (t), TREE_OPERAND (top0, 0), TREE_OPERAND (top0, 1)); } - + /* For x ^ y use x != y. */ + else if (TREE_CODE (t) == BIT_XOR_EXPR) + t = build2 (NE_EXPR, TREE_TYPE (t), + TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)); + if (is_gimple_condexpr (t)) return t; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dc0b745..601ca66 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2013-04-06 Jeff Law <law@redhat.com> + + * gcc.dg/tree-ssa/forwprop-25.c: New test + 2013-04-03 Jeff Law <law@redhat.com> PR tree-optimization/56799 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c new file mode 100644 index 0000000..cf0c504 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-25.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-forwprop1" } */ + +struct rtx_def; +typedef struct rtx_def *rtx; +typedef const struct rtx_def *const_rtx; +enum machine_mode +{ + MAX_MACHINE_MODE, + NUM_MACHINE_MODES = MAX_MACHINE_MODE +}; +extern const char *const mode_name[NUM_MACHINE_MODES]; +enum mode_class +{ MODE_RANDOM, MODE_CC, MODE_INT, MODE_PARTIAL_INT, MODE_FRACT, MODE_UFRACT, + MODE_ACCUM, MODE_UACCUM, MODE_FLOAT, MODE_DECIMAL_FLOAT, MODE_COMPLEX_INT, + MODE_COMPLEX_FLOAT, MODE_VECTOR_INT, MODE_VECTOR_FRACT, + MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM, + MODE_VECTOR_FLOAT, MAX_MODE_CLASS }; +extern const unsigned char mode_class[NUM_MACHINE_MODES]; +extern const unsigned short mode_precision[NUM_MACHINE_MODES]; +struct rtx_def +{ + __extension__ enum machine_mode mode:8; +}; +void +convert_move (rtx to, rtx from, int unsignedp) +{ + enum machine_mode to_mode = ((enum machine_mode) (to)->mode); + enum machine_mode from_mode = ((enum machine_mode) (from)->mode); + ((void) + (!((mode_precision[from_mode] != mode_precision[to_mode]) + || ((((enum mode_class) mode_class[from_mode]) == MODE_DECIMAL_FLOAT) != + (((enum mode_class) mode_class[to_mode]) == + MODE_DECIMAL_FLOAT))) ? + fancy_abort ("/home/gcc/virgin-gcc/gcc/expr.c", 380, __FUNCTION__), + 0 : 0)); +} + +/* { dg-final { scan-tree-dump "Replaced.*!=.*with.*!=.* " "forwprop1"} } */ +/* { dg-final { cleanup-tree-dump "forwprop1" } } */ + + +