Combine logical OR ranges properly.
authorAndrew MacLeod <amacleod@redhat.com>
Mon, 26 Oct 2020 18:55:00 +0000 (14:55 -0400)
committerAndrew MacLeod <amacleod@redhat.com>
Mon, 26 Oct 2020 21:41:07 +0000 (17:41 -0400)
When combining logical OR operands with a FALSE result, union the false
ranges for operand1 and operand2... not intersection.

gcc/
PR tree-optimization/97567
* gimple-range-gori.cc (gori_compute::logical_combine): Union the
ranges of operand1 and operand2, not intersect.
gcc/testsuite/
* gcc.dg/pr97567.c: New.

gcc/gimple-range-gori.cc
gcc/testsuite/gcc.dg/pr97567.c [new file with mode: 0644]

index 5d50b111d2ae582f21f366f1bf4dbbee56fd7484..de0f653860d3c4d7e94801c8e410fdf508926a22 100644 (file)
@@ -730,10 +730,10 @@ gori_compute::logical_combine (irange &r, enum tree_code code,
         if (lhs.zero_p ())
          {
            // An OR operation will only take the FALSE path if both
-           // operands are false, so [20, 255] intersect [0, 5] is the
+           // operands are false, so either [20, 255] or [0, 5] is the
            // union: [0,5][20,255].
            r = op1.false_range;
-           r.intersect (op2.false_range);
+           r.union_ (op2.false_range);
          }
        else
          {
diff --git a/gcc/testsuite/gcc.dg/pr97567.c b/gcc/testsuite/gcc.dg/pr97567.c
new file mode 100644 (file)
index 0000000..b2b72a4
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int a, b, c, d;
+void k() {
+  unsigned f = 1;
+  long g = 4073709551615;
+  for (; a; a++)
+    for (;;) {
+      d = 0;
+    L1:
+      break;
+    }
+  if (f)
+    for (; a; a++)
+      ;
+  g || f;
+  int i = 0 - f || g;
+  long j = g - f;
+  if (j || f) {
+    if (g < 4073709551615)
+      for (;;)
+        ;
+    int e = ~f, h = b / ~e;
+    if (c)
+      goto L2;
+    g = f = h;
+  }
+  g || d;
+L2:
+  if (c)
+    goto L1;
+}
+int main() { k(); return 0; }