aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2020-10-26 14:55:00 -0400
committerAndrew MacLeod <amacleod@redhat.com>2020-10-26 17:41:07 -0400
commit48722d158cbf692c24025e345ecbbbb570f66aa5 (patch)
tree9918c57fb703d14c7fe3ec85918f665030487526
parentb784bbbe45414084551a824504650f21cb653ca1 (diff)
downloadgcc-48722d158cbf692c24025e345ecbbbb570f66aa5.zip
gcc-48722d158cbf692c24025e345ecbbbb570f66aa5.tar.gz
gcc-48722d158cbf692c24025e345ecbbbb570f66aa5.tar.bz2
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.
-rw-r--r--gcc/gimple-range-gori.cc4
-rw-r--r--gcc/testsuite/gcc.dg/pr97567.c34
2 files changed, 36 insertions, 2 deletions
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 5d50b11..de0f653 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 0000000..b2b72a4
--- /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; }