https://gcc.gnu.org/g:dd9ed951f4002419ceff744bbd87ae9b8affdaf4

commit r15-9008-gdd9ed951f4002419ceff744bbd87ae9b8affdaf4
Author: Andrew MacLeod <amacl...@redhat.com>
Date:   Wed Mar 26 10:34:42 2025 -0400

    If the LHS does not contain zero, neither do multiply operands.
    
    Given ~[0,0] = op1 * op2, range-ops should determine that neither op1 nor
    op2 is zero.  Add this to the operator_mult for op1_range.  op2_range
    simply invokes op1_range, so both will be covered.
    
            PR tree-optimzation/110992.c
            PR tree-optimzation/119471.c
            gcc/
            * range-op.cc (operator_mult::op1_range): If the LHS does not
            contain zero, return non-zero.
    
            gcc/testsuite/
            * gcc.dg/pr110992.c: New.
            * gcc.dg/pr119471.c: New.

Diff:
---
 gcc/range-op.cc                 |  7 +++++++
 gcc/testsuite/gcc.dg/pr110992.c | 18 ++++++++++++++++++
 gcc/testsuite/gcc.dg/pr119471.c | 19 +++++++++++++++++++
 3 files changed, 44 insertions(+)

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 6310ce27f03c..f72b4ae92cfd 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2220,6 +2220,13 @@ operator_mult::op1_range (irange &r, tree type,
   wide_int offset;
   if (op2.singleton_p (offset) && offset != 0)
     return range_op_handler (TRUNC_DIV_EXPR).fold_range (r, type, lhs, op2);
+
+  //  ~[0, 0] = op1 * op2  defines op1 and op2 as non-zero.
+  if (!lhs.contains_p (wi::zero (TYPE_PRECISION (lhs.type ()))))
+    {
+      r.set_nonzero (type);
+      return true;
+    }
   return false;
 }
 
diff --git a/gcc/testsuite/gcc.dg/pr110992.c b/gcc/testsuite/gcc.dg/pr110992.c
new file mode 100644
index 000000000000..05e9b9267e6f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110992.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void foo (int);
+
+int f(unsigned b, short c)
+{
+  int bt = b;
+  int bt1 = bt;
+  int t = bt1 & -(c!=0);
+ // int t = bt1 * (c!=0);
+
+  if (!t) return 0;
+  foo(bt == 0);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "foo \\(0\\)" 1 "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr119471.c b/gcc/testsuite/gcc.dg/pr119471.c
new file mode 100644
index 000000000000..4c55d85f77c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr119471.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+int fa(int a, int b)
+{
+  int c = a * b;
+  if (c != 0)
+    return (a != 0);
+  return 0;
+}
+int fb(int a, int b)
+{
+  int c = a * b;
+  if (c != 0)
+    return (b != 0);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "PHI <1" 2 "evrp" } } */

Reply via email to