public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Aldy Hernandez <aldyh@redhat.com>
To: GCC patches <gcc-patches@gcc.gnu.org>
Cc: Andrew MacLeod <amacleod@redhat.com>, Aldy Hernandez <aldyh@redhat.com>
Subject: [COMMITTED] Set nonzero bits for multiplication and divisions by a power of 2.
Date: Fri,  4 Nov 2022 15:19:05 +0100	[thread overview]
Message-ID: <20221104141905.312059-1-aldyh@redhat.com> (raw)

We're missing a lot of TLC in keeping track of nonzero bits across
range-ops.  It isn't an oversight, but just limited amount of hours to
implement stuff.

This patch keeps better track of the nonzero mask (really
maybe_nonzero bits as discussed) across multiplication and division
when the RHS is a power of 2.

It fixes PR107342 and also touches on PR55157.  In the latter, the
nonzero mask is being set quite late (CCP2) but could be set by evrp
time if we enhanced range-ops.  I have added tests from both PRs.

Tested

	PR tree-optimization/107342

gcc/ChangeLog:

	* range-op.cc (operator_mult::fold_range): New.
	(operator_div::fold_range): New.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/vrp122.c: New test.
	* gcc.dg/tree-ssa/vrp123.c: New test.
---
 gcc/range-op.cc                        | 59 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/vrp122.c | 19 +++++++++
 gcc/testsuite/gcc.dg/tree-ssa/vrp123.c | 18 ++++++++
 3 files changed, 96 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp122.c
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/vrp123.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 49ee7be3d3b..25c004d8287 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -1742,9 +1742,13 @@ cross_product_operator::wi_cross_product (irange &r, tree type,
 
 class operator_mult : public cross_product_operator
 {
+  using range_operator::fold_range;
   using range_operator::op1_range;
   using range_operator::op2_range;
 public:
+  virtual bool fold_range (irange &r, tree type,
+			   const irange &lh, const irange &rh,
+			   relation_trio = TRIO_VARYING) const final override;
   virtual void wi_fold (irange &r, tree type,
 		        const wide_int &lh_lb,
 		        const wide_int &lh_ub,
@@ -1762,6 +1766,32 @@ public:
 			  relation_trio) const;
 } op_mult;
 
+bool
+operator_mult::fold_range (irange &r, tree type,
+			   const irange &lh, const irange &rh,
+			   relation_trio trio) const
+{
+  if (!cross_product_operator::fold_range (r, type, lh, rh, trio))
+    return false;
+
+  if (lh.undefined_p ())
+    return true;
+
+  tree t;
+  if (rh.singleton_p (&t))
+    {
+      wide_int w = wi::to_wide (t);
+      int shift = wi::exact_log2 (w);
+      if (shift != -1)
+	{
+	  wide_int nz = lh.get_nonzero_bits ();
+	  nz = wi::lshift (nz, shift);
+	  r.set_nonzero_bits (nz);
+	}
+    }
+  return true;
+}
+
 bool
 operator_mult::op1_range (irange &r, tree type,
 			  const irange &lhs, const irange &op2,
@@ -1902,10 +1932,39 @@ public:
 		        const wide_int &rh_ub) const;
   virtual bool wi_op_overflows (wide_int &res, tree type,
 				const wide_int &, const wide_int &) const;
+  virtual bool fold_range (irange &r, tree type,
+			   const irange &lh, const irange &rh,
+			   relation_trio trio) const final override;
 private:
   enum tree_code code;
 };
 
+bool
+operator_div::fold_range (irange &r, tree type,
+			  const irange &lh, const irange &rh,
+			  relation_trio trio) const
+{
+  if (!cross_product_operator::fold_range (r, type, lh, rh, trio))
+    return false;
+
+  if (lh.undefined_p ())
+    return true;
+
+  tree t;
+  if (rh.singleton_p (&t))
+    {
+      wide_int wi = wi::to_wide (t);
+      int shift = wi::exact_log2 (wi);
+      if (shift != -1)
+	{
+	  wide_int nz = lh.get_nonzero_bits ();
+	  nz = wi::rshift (nz, shift, TYPE_SIGN (type));
+	  r.set_nonzero_bits (nz);
+	}
+    }
+  return true;
+}
+
 bool
 operator_div::wi_op_overflows (wide_int &res, tree type,
 			       const wide_int &w0, const wide_int &w1) const
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c
new file mode 100644
index 00000000000..b2ddcda023c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp122.c
@@ -0,0 +1,19 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-evrp-details" }
+
+void gg(void);
+int f(unsigned t)
+{
+  unsigned g = t*16;
+  if (g==0)  return 1;
+  gg();
+  gg();
+  gg();
+  gg();
+  gg();
+  gg();
+  if (g<=4)  return 1;
+  return 0;
+}
+
+// { dg-final { scan-tree-dump "Global Exported: g_.* NONZERO 0x.*fff0" "evrp" } }
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp123.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp123.c
new file mode 100644
index 00000000000..1ad3caa4384
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp123.c
@@ -0,0 +1,18 @@
+// { dg-options "-O1 -fdump-tree-dom3-raw" }
+
+extern int
+__attribute__((const))
+foo4b (int);
+
+int f4b (unsigned int r)
+{
+  if (foo4b (r))
+    r *= 8U;
+
+  if ((r / 2U) & 2U)
+    r += foo4b (r);
+
+  return r;
+}
+
+// { dg-final { scan-tree-dump-times {gimple_call <foo4b,} 1 dom3 } }
-- 
2.38.1


                 reply	other threads:[~2022-11-04 14:19 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221104141905.312059-1-aldyh@redhat.com \
    --to=aldyh@redhat.com \
    --cc=amacleod@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).