Fix init_range_entry (PR tree-optimization/58364)

Submitted by Jakub Jelinek on Sept. 9, 2013, 3:20 p.m.

Details

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

Commit Message

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

Comments

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 hide | download patch | download mbox

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