diff mbox

Fix init_range_entry (PR tree-optimization/58364)

Message ID 20130909152059.GO1817@tucnak.redhat.com
State New
Headers show

Commit Message

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

Comments

Richard Biener Sept. 9, 2013, 5:05 p.m. UTC | #1
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
diff mbox

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