This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix init_range_entry (PR tree-optimization/58364)


Jakub Jelinek <jakub@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  <jakub@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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]