Knowing that X << X is non-zero means X is also non-zero.  This patch
teaches this this to range-ops.

As usual, the big twiddling experts could come up with all sorts of
fancy enhancements in this area, and we welcome all patches :).

I will push this pending tests.

gcc/ChangeLog:

        PR tree-optimization/102546
        * range-op.cc (operator_lshift::op1_range): Handle EQ_EXPR
        relation.
---
 gcc/range-op.cc                          | 19 ++++++++++++++++---
 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c | 23 +++++++++++++++++++++++
 2 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr102546.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 5e37133026d..53f3be4266e 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2075,9 +2075,14 @@ operator_lshift::op1_range (irange &r,
                            tree type,
                            const irange &lhs,
                            const irange &op2,
-                           relation_kind rel ATTRIBUTE_UNUSED) const
+                           relation_kind rel) const
 {
   tree shift_amount;
+  int_range<2> adjust (type);
+
+  if (rel == EQ_EXPR && !lhs.contains_p (build_zero_cst (type)))
+    adjust.set_nonzero (type);
+
   if (op2.singleton_p (&shift_amount))
     {
       wide_int shift = wi::to_wide (shift_amount);
@@ -2086,10 +2091,11 @@ operator_lshift::op1_range (irange &r,
       if (wi::ge_p (shift, wi::uhwi (TYPE_PRECISION (type),
                                     TYPE_PRECISION (op2.type ())),
                    UNSIGNED))
-       return false;
+       goto done;
       if (shift == 0)
        {
          r = lhs;
+         r.intersect (adjust);
          return true;
        }
 
@@ -2126,9 +2132,16 @@ operator_lshift::op1_range (irange &r,
 
       if (utype != type)
        range_cast (r, type);
+      r.intersect (adjust);
       return true;
     }
-  return false;
+
+ done:
+  if (adjust.varying_p ())
+    return false;
+
+  r = adjust;
+  return true;
 }
 
 bool
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
new file mode 100644
index 00000000000..4bd98747732
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr102546.c
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-O3 -fdump-tree-optimized" }
+
+static int a;
+static char b, c, d;
+void bar(void);
+void foo(void);
+
+int main() {
+    int f = 0;
+    for (; f <= 5; f++) {
+        bar();
+        b = b && f;
+        d = f << f;
+        if (!(a >= d || f))
+            foo();
+        c = 1;
+        for (; c; c = 0)
+            ;
+    }
+}
+
+// { dg-final { scan-tree-dump-not "foo" "optimized" } }
-- 
2.31.1

Reply via email to