public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] tree-optimization/107919 - uninit diagnostic predicate simplification
@ 2022-11-30 11:00 Richard Biener
  0 siblings, 0 replies; only message in thread
From: Richard Biener @ 2022-11-30 11:00 UTC (permalink / raw)
  To: gcc-patches

We fail to simplify

        ((_145 != 0B) AND (_531 == 2) AND (_109 == 0))
        OR ((NOT (_145 != 0B)) AND (_531 == 2) AND (_109 == 0))
        OR ((NOT (_531 == 2)) AND (_109 == 0))

because the existing simplification of !A && B || A && B is implemented
too simplistic.  The following re-implements that which fixes the
bogus uninit diagnostic when using -O1 but not yet at -O2.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	PR tree-optimization/107919
	* gimple-predicate-analysis.cc (predicate::simplify_2):
	Handle predicates of arbitrary length.

	* g++.dg/warn/Wuninitialized-pr107919-1.C: New testcase.
---
 gcc/gimple-predicate-analysis.cc              | 71 ++++++++-----------
 .../g++.dg/warn/Wuninitialized-pr107919-1.C   | 15 ++++
 2 files changed, 43 insertions(+), 43 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C

diff --git a/gcc/gimple-predicate-analysis.cc b/gcc/gimple-predicate-analysis.cc
index 5013a4447d6..23be4b69bab 100644
--- a/gcc/gimple-predicate-analysis.cc
+++ b/gcc/gimple-predicate-analysis.cc
@@ -1257,64 +1257,49 @@ predicate::simplify_2 ()
   /* (X AND Y) OR (!X AND Y) is equivalent to Y.
      (X AND Y) OR (X AND !Y) is equivalent to X.  */
 
-  unsigned n = m_preds.length ();
-  for (unsigned i = 0; i < n; i++)
+  for (unsigned i = 0; i < m_preds.length (); i++)
     {
       pred_chain &a_chain = m_preds[i];
-      if (a_chain.length () != 2)
-	continue;
-
-      /* Create copies since the chain may be released below before
-	 the copy is added to the other chain.  */
-      const pred_info x = a_chain[0];
-      const pred_info y = a_chain[1];
 
-      for (unsigned j = 0; j < n; j++)
+      for (unsigned j = i + 1; j < m_preds.length (); j++)
 	{
-	  if (j == i)
-	    continue;
-
 	  pred_chain &b_chain = m_preds[j];
-	  if (b_chain.length () != 2)
+	  if (b_chain.length () != a_chain.length ())
 	    continue;
 
-	  const pred_info &x2 = b_chain[0];
-	  const pred_info &y2 = b_chain[1];
-
-	  if (pred_equal_p (x, x2) && pred_neg_p (y, y2))
+	  unsigned neg_idx = -1U;
+	  for (unsigned k = 0; k < a_chain.length (); ++k)
 	    {
-	      /* Kill a_chain.  */
-	      b_chain.release ();
-	      a_chain.release ();
-	      b_chain.safe_push (x);
-	      simplified = true;
-	      break;
+	      if (pred_equal_p (a_chain[k], b_chain[k]))
+		continue;
+	      if (neg_idx != -1U)
+		{
+		  neg_idx = -1U;
+		  break;
+		}
+	      if (pred_neg_p (a_chain[k], b_chain[k]))
+		neg_idx = k;
+	      else
+		break;
 	    }
-	  if (pred_neg_p (x, x2) && pred_equal_p (y, y2))
+	  /* If we found equal chains with one negated predicate
+	     simplify.  */
+	  if (neg_idx != -1U)
 	    {
-	      /* Kill a_chain.  */
-	      a_chain.release ();
-	      b_chain.release ();
-	      b_chain.safe_push (y);
+	      a_chain.ordered_remove (neg_idx);
+	      m_preds.ordered_remove (j);
 	      simplified = true;
+	      if (a_chain.is_empty ())
+		{
+		  /* A && !A simplifies to true, wipe the whole predicate.  */
+		  for (unsigned k = 0; k < m_preds.length (); ++k)
+		    m_preds[k].release ();
+		  m_preds.truncate (0);
+		}
 	      break;
 	    }
 	}
     }
-  /* Now clean up the chain.  */
-  if (simplified)
-    {
-      pred_chain_union s_preds = vNULL;
-      for (unsigned i = 0; i < n; i++)
-	{
-	  if (m_preds[i].is_empty ())
-	    continue;
-	  s_preds.safe_push (m_preds[i]);
-	}
-      m_preds.release ();
-      m_preds = s_preds;
-      s_preds = vNULL;
-    }
 
   return simplified;
 }
diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C
new file mode 100644
index 00000000000..dd631dc8bfe
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-pr107919-1.C
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-require-effective-target c++17 }
+// { dg-options "-O -Wuninitialized" }
+
+#include <memory>
+#include <variant>
+
+using Event = std::variant<std::variant<std::tuple<std::unique_ptr<int>>>, int, char>;
+
+void do_something(void* storage)
+{
+  Event event {};
+  auto& swappedValue = *reinterpret_cast<Event*>(storage);
+  std::swap(event, swappedValue);
+}
-- 
2.35.3

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-11-30 11:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-30 11:00 [PATCH] tree-optimization/107919 - uninit diagnostic predicate simplification Richard Biener

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).