public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@redhat.com>
To: Richard Biener <rguenther@suse.de>
Cc: gcc-patches@gcc.gnu.org
Subject: [PATCH] bitint: Fix up adjustment of large/huge _BitInt arguments of returns_twice calls [PR113466]
Date: Thu, 14 Mar 2024 09:28:08 +0100	[thread overview]
Message-ID: <ZfK1GNhuXFhxWr9q@tucnak> (raw)

Hi!

This patch (on top of the just posted gsi_safe_insert* fixes patch)
fixes the instrumentation of large/huge _BitInt SSA_NAME arguments of
returns_twice calls.

In this case it isn't just a matter of using gsi_safe_insert_before instead
of gsi_insert_before, we need to do more.

One thing is that unlike the asan/ubsan instrumentation which does just some
checking, here we want the statement before the call to load into a SSA_NAME
which is passed to the call.  With another edge we need to add a PHI,
with one PHI argument the loaded SSA_NAME, another argument an uninitialized
warning free SSA_NAME and a result and arrange for all 3 SSA_NAMEs to be
preserved (i.e. stay as is, be no longer lowered afterwards).

Another problem is because edge_before_returns_twice_call may use
copy_ssa_name, we can end up with large/huge _BitInt SSA_NAMEs we don't
really track in the pass.  We need an underlying variable for those, but
because of the way they are constructed we can find that easily, we can
use the same underlying variable for the PHI arg from non-EDGE_ABNORMAL
edge as we use for the corresponding PHI result.  The ugliest part of
this is growing the partition if it needs to be growed (otherwise it is
just a partition_union).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2024-03-14  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/113466
	* gimple-lower-bitint.cc (bitint_large_huge::lower_call): Handle
	ECF_RETURNS_TWICE call arguments correctly.
	(gimple_lower_bitint): Ignore PHIs where the PHI result is
	in m_preserved bitmap.

	* gcc.dg/bitint-100.c: New test.

--- gcc/gimple-lower-bitint.cc.jj	2024-03-13 13:03:08.120117081 +0100
+++ gcc/gimple-lower-bitint.cc	2024-03-13 15:05:54.830303524 +0100
@@ -5248,6 +5248,7 @@ bitint_large_huge::lower_call (tree obj,
       default:
 	break;
       }
+  int returns_twice = (gimple_call_flags (stmt) & ECF_RETURNS_TWICE) != 0;
   for (unsigned int i = 0; i < nargs; ++i)
     {
       tree arg = gimple_call_arg (stmt, i);
@@ -5255,6 +5256,8 @@ bitint_large_huge::lower_call (tree obj,
 	  || TREE_CODE (TREE_TYPE (arg)) != BITINT_TYPE
 	  || bitint_precision_kind (TREE_TYPE (arg)) <= bitint_prec_middle)
 	continue;
+      if (m_preserved == NULL)
+	m_preserved = BITMAP_ALLOC (NULL);
       if (SSA_NAME_IS_DEFAULT_DEF (arg)
 	  && (!SSA_NAME_VAR (arg) || VAR_P (SSA_NAME_VAR (arg))))
 	{
@@ -5270,11 +5273,93 @@ bitint_large_huge::lower_call (tree obj,
 	    v = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (arg), v);
 	  arg = make_ssa_name (TREE_TYPE (arg));
 	  gimple *g = gimple_build_assign (arg, v);
-	  gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+	  gsi_safe_insert_before (&gsi, g);
+	  if (returns_twice)
+	    {
+	      basic_block bb = gimple_bb (stmt);
+	      gcc_checking_assert (EDGE_COUNT (bb->preds) == 2);
+	      edge e = EDGE_PRED (bb, 0), ead = EDGE_PRED (bb, 1);
+	      if ((ead->flags & EDGE_ABNORMAL) == 0)
+		std::swap (e, ead);
+	      gcc_checking_assert ((e->flags & EDGE_ABNORMAL) == 0
+				   && (ead->flags & EDGE_ABNORMAL));
+	      if (returns_twice == 1)
+		{
+		  /* edge_before_returns_twice_call can use copy_ssa_name
+		     for some PHIs, but in that case we need to put it
+		     into the same partition as the copied SSA_NAME.   */
+		  unsigned max_ver = 0;
+		  for (gphi_iterator gsi = gsi_start_phis (bb);
+		       !gsi_end_p (gsi); gsi_next (&gsi))
+		    {
+		      gphi *phi = gsi.phi ();
+		      tree lhs = gimple_phi_result (phi);
+		      tree arg = gimple_phi_arg_def_from_edge (phi, e);
+		      if (m_names
+			  && TREE_CODE (arg) == SSA_NAME
+			  && TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+			  && (bitint_precision_kind (TREE_TYPE (lhs))
+			      > bitint_prec_middle)
+			  && bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs))
+			  && !bitmap_bit_p (m_names, SSA_NAME_VERSION (arg)))
+			max_ver = MAX (max_ver, SSA_NAME_VERSION (arg));
+		    }
+		  if (max_ver != 0)
+		    {
+		      if ((unsigned) m_map->var_partition->num_elements
+			  <= max_ver)
+			{
+			  partition p = partition_new (max_ver + 1);
+			  partition o = m_map->var_partition;
+			  for (int e = 0; e < o->num_elements; ++e)
+			    {
+			      p->elements[e].class_element
+				= o->elements[e].class_element;
+			      p->elements[e].class_count
+				= o->elements[e].class_count;
+			      p->elements[e].next
+				= &p->elements[0] + (o->elements[e].next
+						     - &o->elements[0]);
+			    }
+			  m_map->var_partition = p;
+			  partition_delete (o);
+			}
+		      for (gphi_iterator gsi = gsi_start_phis (bb);
+			   !gsi_end_p (gsi); gsi_next (&gsi))
+			{
+			  gphi *phi = gsi.phi ();
+			  tree lhs = gimple_phi_result (phi);
+			  tree arg = gimple_phi_arg_def_from_edge (phi, e);
+			  if (m_names
+			      && TREE_CODE (arg) == SSA_NAME
+			      && TREE_CODE (TREE_TYPE (lhs)) == BITINT_TYPE
+			      && (bitint_precision_kind (TREE_TYPE (lhs))
+				  > bitint_prec_middle)
+			      && bitmap_bit_p (m_names, SSA_NAME_VERSION (lhs))
+			      && bitmap_set_bit (m_names,
+						 SSA_NAME_VERSION (arg)))
+			    partition_union (m_map->var_partition,
+					     SSA_NAME_VERSION (lhs),
+					     SSA_NAME_VERSION (arg));
+			}
+		    }
+		  returns_twice = 2;
+		}
+	      gphi *phi = create_phi_node (make_ssa_name (TREE_TYPE (arg)),
+					   bb);
+	      add_phi_arg (phi, arg, e, UNKNOWN_LOCATION);
+	      bitmap_set_bit (m_preserved, SSA_NAME_VERSION (arg));
+	      tree var = create_tmp_reg (TREE_TYPE (arg));
+	      suppress_warning (var, OPT_Wuninitialized);
+	      arg = get_or_create_ssa_default_def (cfun, var);
+	      SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg) = 1;
+	      add_phi_arg (phi, arg, ead, UNKNOWN_LOCATION);
+	      bitmap_set_bit (m_preserved, SSA_NAME_VERSION (arg));
+	      arg = gimple_phi_result (phi);
+	      SSA_NAME_OCCURS_IN_ABNORMAL_PHI (arg) = 1;
+	    }
 	}
       gimple_call_set_arg (stmt, i, arg);
-      if (m_preserved == NULL)
-	m_preserved = BITMAP_ALLOC (NULL);
       bitmap_set_bit (m_preserved, SSA_NAME_VERSION (arg));
     }
   tree lhs = gimple_call_lhs (stmt);
@@ -6870,6 +6955,9 @@ gimple_lower_bitint (void)
 	  if (TREE_CODE (TREE_TYPE (lhs)) != BITINT_TYPE
 	      || bitint_precision_kind (TREE_TYPE (lhs)) < bitint_prec_large)
 	    continue;
+	  if (large_huge.m_preserved
+	      && bitmap_bit_p (large_huge.m_preserved, SSA_NAME_VERSION (lhs)))
+	    continue;
 	  int p1 = var_to_partition (large_huge.m_map, lhs);
 	  gcc_assert (large_huge.m_vars[p1] != NULL_TREE);
 	  tree v1 = large_huge.m_vars[p1];
--- gcc/testsuite/gcc.dg/bitint-100.c.jj	2024-03-13 15:21:02.313768843 +0100
+++ gcc/testsuite/gcc.dg/bitint-100.c	2024-03-13 12:11:18.636036865 +0100
@@ -0,0 +1,61 @@
+/* PR tree-optimization/113466 */
+/* { dg-do compile { target bitint575 } } */
+/* { dg-options "-O2" } */
+
+int foo (int);
+
+__attribute__((returns_twice, noipa)) _BitInt(325)
+bar (_BitInt(575) x)
+{
+  (void) x;
+  return 0wb;
+}
+
+_BitInt(325)
+baz (_BitInt(575) y)
+{
+  foo (1);
+  return bar (y);
+}
+
+_BitInt(325)
+qux (int x, _BitInt(575) y)
+{
+  if (x == 25)
+    x = foo (2);
+  else if (x == 42)
+    x = foo (foo (3));
+  return bar (y);
+}
+
+void
+corge (int x, _BitInt(575) y, _BitInt(325) *z)
+{
+  void *q[] = { &&l1, &&l2, &&l3, &&l3 };
+  if (x == 25)
+    {
+    l1:
+      x = foo (2);
+    }
+  else if (x == 42)
+    {
+    l2:
+      x = foo (foo (3));
+    }
+l3:
+  *z = bar (y);
+  if (x < 4)
+    goto *q[x & 3];
+}
+
+_BitInt(325)
+freddy (int x, _BitInt(575) y)
+{
+  bar (y);
+  ++y;
+  if (x == 25)
+    x = foo (2);
+  else if (x == 42)
+    x = foo (foo (3));
+  return bar (y);
+}

	Jakub


             reply	other threads:[~2024-03-14  8:28 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-14  8:28 Jakub Jelinek [this message]
2024-03-14  8:48 ` Richard Biener
2024-03-14  8:53   ` Jakub Jelinek
2024-03-14  8:59     ` Richard Biener
2024-03-14 10:42       ` [PATCH] bitint, v2: " Jakub Jelinek
2024-03-14 11:52         ` Richard Biener

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=ZfK1GNhuXFhxWr9q@tucnak \
    --to=jakub@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=rguenther@suse.de \
    /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).