OSDN Git Service

gcc/
authorkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 14 Jan 2006 15:42:11 +0000 (15:42 +0000)
committerkazu <kazu@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 14 Jan 2006 15:42:11 +0000 (15:42 +0000)
PR tree-optimization/25485
* tree-vrp.c (extract_range_from_binary_expr): Handle cases
where one of the operands of TRUTH_AND_EXPR and TRUTH_OR_EXPR
is known to be false and true, respectively.

gcc/testsuite/
PR tree-optimization/25485
* gcc.dg/tree-ssa/pr25485.c: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109704 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr25485.c [new file with mode: 0644]
gcc/tree-vrp.c

index b9dc3c2..d7cc76a 100644 (file)
@@ -1,3 +1,10 @@
+2006-01-14  Kazu Hirata  <kazu@codesourcery.com>
+
+       PR tree-optimization/25485
+       * tree-vrp.c (extract_range_from_binary_expr): Handle cases
+       where one of the operands of TRUTH_AND_EXPR and TRUTH_OR_EXPR
+       is known to be false and true, respectively.
+
 2006-01-14  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/22548
index 318cc53..5567ae3 100644 (file)
@@ -1,3 +1,8 @@
+2006-01-14  Kazu Hirata  <kazu@codesourcery.com>
+
+       PR tree-optimization/25485
+       * gcc.dg/tree-ssa/pr25485.c: New.
+
 2006-01-14  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/22548
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr25485.c b/gcc/testsuite/gcc.dg/tree-ssa/pr25485.c
new file mode 100644 (file)
index 0000000..7d76d07
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR tree-optimization/25485
+   VRP did not fold TRUTH_AND_EXPR.  Make sure it does now.  */
+
+/* { dg-options "-O2 -fdump-tree-vrp" } */
+
+int
+foo (int a, int b)
+{
+  if (a > 50)
+    return 19;
+  if (a > 63 && b < 50)
+    return 17;
+  return 31;
+}
+
+/* { dg-final { scan-tree-dump-times "if" 1 "vrp"} } */
+/* { dg-final { cleanup-tree-dump "vrp" } } */
index daa459f..6bd4725 100644 (file)
@@ -1230,6 +1230,8 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
      the operands is VR_VARYING or symbolic range.  TODO, we may be
      able to derive anti-ranges in some cases.  */
   if (code != BIT_AND_EXPR
+      && code != TRUTH_AND_EXPR
+      && code != TRUTH_OR_EXPR
       && (vr0.type == VR_VARYING
          || vr1.type == VR_VARYING
          || vr0.type != vr1.type
@@ -1277,9 +1279,47 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
       || code == TRUTH_OR_EXPR
       || code == TRUTH_XOR_EXPR)
     {
-      /* Boolean expressions cannot be folded with int_const_binop.  */
-      min = fold_binary (code, TREE_TYPE (expr), vr0.min, vr1.min);
-      max = fold_binary (code, TREE_TYPE (expr), vr0.max, vr1.max);
+      /* If one of the operands is zero, we know that the whole
+        expression evaluates zero.  */
+      if (code == TRUTH_AND_EXPR
+         && ((vr0.type == VR_RANGE
+              && integer_zerop (vr0.min)
+              && integer_zerop (vr0.max))
+             || (vr1.type == VR_RANGE
+                 && integer_zerop (vr1.min)
+                 && integer_zerop (vr1.max))))
+       {
+         type = VR_RANGE;
+         min = max = build_int_cst (TREE_TYPE (expr), 0);
+       }
+      /* If one of the operands is one, we know that the whole
+        expression evaluates one.  */
+      else if (code == TRUTH_OR_EXPR
+              && ((vr0.type == VR_RANGE
+                   && integer_onep (vr0.min)
+                   && integer_onep (vr0.max))
+                  || (vr1.type == VR_RANGE
+                      && integer_onep (vr1.min)
+                      && integer_onep (vr1.max))))
+       {
+         type = VR_RANGE;
+         min = max = build_int_cst (TREE_TYPE (expr), 1);
+       }
+      else if (vr0.type != VR_VARYING
+              && vr1.type != VR_VARYING
+              && vr0.type == vr1.type
+              && !symbolic_range_p (&vr0)
+              && !symbolic_range_p (&vr1))
+       {
+         /* Boolean expressions cannot be folded with int_const_binop.  */
+         min = fold_binary (code, TREE_TYPE (expr), vr0.min, vr1.min);
+         max = fold_binary (code, TREE_TYPE (expr), vr0.max, vr1.max);
+       }
+      else
+       {
+         set_value_range_to_varying (vr);
+         return;
+       }
     }
   else if (code == PLUS_EXPR
           || code == MIN_EXPR