aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@redhat.com>2025-03-26 10:34:42 -0400
committerAndrew MacLeod <amacleod@redhat.com>2025-03-28 10:25:30 -0400
commitdd9ed951f4002419ceff744bbd87ae9b8affdaf4 (patch)
tree7b30ffedee0f05f8c3ab7d3edb8e8bbeea78f159
parentdcb7009efc5358207d1b0612732a0608915a3ef7 (diff)
downloadgcc-dd9ed951f4002419ceff744bbd87ae9b8affdaf4.zip
gcc-dd9ed951f4002419ceff744bbd87ae9b8affdaf4.tar.gz
gcc-dd9ed951f4002419ceff744bbd87ae9b8affdaf4.tar.bz2
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.
-rw-r--r--gcc/range-op.cc7
-rw-r--r--gcc/testsuite/gcc.dg/pr110992.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr119471.c19
3 files changed, 44 insertions, 0 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 6310ce2..f72b4ae 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 0000000..05e9b92
--- /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 0000000..4c55d85
--- /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" } } */