Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >It is not safe to always handle a = ~b; for bool a and b as >in_p = !in_p; exp = arg0. If the current range is say >+[-,-] or -[-,-] or similar (i.e. unconditional false or true), >then the value of exp doesn't matter and thus the fact that exp >has been negated is irrelevant. > >Fixed by just making sure that the range either has 0 as high limit >or 1 as low limit. In fold-const.c we actually are even more >conservative >and just do test for 0: > case TRUTH_NOT_EXPR: > /* We can only do something if the range is testing for zero. */ > if (low == NULL_TREE || high == NULL_TREE > || ! integer_zerop (low) || ! integer_zerop (high)) > return NULL_TREE; > *p_in_p = ! in_p; > return arg0; > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for >trunk/4.8? >
Ok. Thanks, Richard. >2013-09-09 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/58364 > * tree-ssa-reassoc.c (init_range_entry): For BIT_NOT_EXPR on > BOOLEAN_TYPE, only invert in_p and continue with arg0 if > the current range can't be an unconditional true or false. > > * gcc.c-torture/execute/pr58364.c: New test. > >--- gcc/tree-ssa-reassoc.c.jj 2013-08-13 12:20:45.000000000 +0200 >+++ gcc/tree-ssa-reassoc.c 2013-09-09 11:30:07.416312027 +0200 >@@ -1797,7 +1797,14 @@ init_range_entry (struct range_entry *r, > switch (code) > { > case BIT_NOT_EXPR: >- if (TREE_CODE (TREE_TYPE (exp)) == BOOLEAN_TYPE) >+ if (TREE_CODE (TREE_TYPE (exp)) == BOOLEAN_TYPE >+ /* Ensure the range is either +[-,0], +[0,0], >+ -[-,0], -[0,0] or +[1,-], +[1,1], -[1,-] or >+ -[1,1]. If it is e.g. +[-,-] or -[-,-] >+ or similar expression of unconditional true or >+ false, it should not be negated. */ >+ && ((high && integer_zerop (high)) >+ || (low && integer_onep (low)))) > { > in_p = !in_p; > exp = arg0; >--- gcc/testsuite/gcc.c-torture/execute/pr58364.c.jj 2013-09-09 >11:28:59.917681919 +0200 >+++ gcc/testsuite/gcc.c-torture/execute/pr58364.c 2013-09-09 >11:28:40.000000000 +0200 >@@ -0,0 +1,17 @@ >+/* PR tree-optimization/58364 */ >+ >+int a = 1, b, c; >+ >+int >+foo (int x) >+{ >+ return x < 0 ? 1 : x; >+} >+ >+int >+main () >+{ >+ if (foo (a > c == (b = 0))) >+ __builtin_abort (); >+ return 0; >+} > > Jakub