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]

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


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.

--- 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]