Patchwork Fix init_range_entry (PR tree-optimization/58364)

login
register
mail settings
Submitter Jakub Jelinek
Date Sept. 9, 2013, 3:20 p.m.
Message ID <20130909152059.GO1817@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/273588/
State New
Headers show

Comments

Jakub Jelinek - Sept. 9, 2013, 3:20 p.m.
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?

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.


	Jakub
Richard Guenther - Sept. 9, 2013, 5:05 p.m.
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

Patch

--- 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;
+}