In the core of gori_compute::logical_combine we are suppose to combine the calculated true and false ranges on each side of  the operation.

when encountering

[0,0] =   c_3  | c_4

we know we only need to consider the FALSE values of the range carried by c_3 and c_4, but it can be EITHER of those ranges, so we need to union them together to get the correct result.

The code was performing an intersection instead, and in this particualr case, we knew the range carried thru c_3 was alwasy [0,0]  and it was always varying through c_4....    instead of returning varying,  we were returning [0,0]  which then caused some folding which was incorrect.

Fixed by correctly calling union...

Bootstrapped on x86_64-pc-linux-gnu, no regressions, and pushed.

Andrew

commit 48722d158cbf692c24025e345ecbbbb570f66aa5
Author: Andrew MacLeod <amacl...@redhat.com>
Date:   Mon Oct 26 14:55:00 2020 -0400

    Combine logical OR ranges properly.
    
    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.

diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 5d50b111d2a..de0f653860d 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -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
index 00000000000..b2b72a4d2a7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97567.c
@@ -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; }

Reply via email to