public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: gcc-patches@gcc.gnu.org
Cc: segher@kernel.crashing.org, rth@redhat.com,
	ebotcazou@adacore.com,  jason@redhat.com
Subject: [PATCH][v2] rtl-optimization/105231 - distribute_notes and REG_EH_REGION
Date: Tue, 19 Apr 2022 13:02:09 +0200 (CEST)	[thread overview]
Message-ID: <20220419110209.A4C1F139BE@imap2.suse-dmz.suse.de> (raw)

The following mitigates a problem in combine distribute_notes which
places an original REG_EH_REGION based on only may_trap_p which is
good to test whether a non-call insn can possibly throw but not if
actually it does or we care.  That's something we decided at RTL
expansion time where we possibly still know the insn evaluates
to a constant.

In fact, the REG_EH_REGION can only come from the original i3 and
an assert is added to that effect.  That means we only need to
retain the note on i3 or, if that cannot trap, drop it but we
should never move it to i2.  If splitting of i3 ever becomes a
problem here the insn split should be rejected instead.

We are also considering all REG_EH_REGION equal, including
must-not-throw and nothrow kinds but when those are not from i3
we have no good idea what should happen to them, so the following
simply drops them.

Bootstrapped and tested on x86_64-unknown-linux-gnu, OK for trunk?

Thanks,
Richard.

2022-04-19  Richard Biener  <rguenther@suse.de>

	PR rtl-optimization/105231
	* combine.cc (distribute_notes): Assert that a REG_EH_REGION
	with landing pad > 0 is from i3 and only keep it there or drop
	it if the insn can not trap.  Throw away REG_EH_REGION with
	landing pad <= 0 if it does not originate from i3.

	* gcc.dg/torture/pr105231.c: New testcase.
---
 gcc/combine.cc                          | 44 +++++++++++++++----------
 gcc/testsuite/gcc.dg/torture/pr105231.c | 15 +++++++++
 2 files changed, 42 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr105231.c

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 53dcac92abc..ca9d6f0e6e0 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -14175,23 +14175,33 @@ distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
 	  break;
 
 	case REG_EH_REGION:
-	  /* These notes must remain with the call or trapping instruction.  */
-	  if (CALL_P (i3))
-	    place = i3;
-	  else if (i2 && CALL_P (i2))
-	    place = i2;
-	  else
-	    {
-	      gcc_assert (cfun->can_throw_non_call_exceptions);
-	      if (may_trap_p (i3))
-		place = i3;
-	      else if (i2 && may_trap_p (i2))
-		place = i2;
-	      /* ??? Otherwise assume we've combined things such that we
-		 can now prove that the instructions can't trap.  Drop the
-		 note in this case.  */
-	    }
-	  break;
+	  {
+	    int lp_nr = INTVAL (XEXP (note, 0));
+	    /* A REG_EH_REGION note transfering control can only ever come
+	       from i3.  */
+	    gcc_assert (lp_nr <= 0 || from_insn == i3);
+	    /* For nothrow (lp_nr == 0 or lp_nr == INT_MIN) and
+	       for insns in a MUST_NOT_THROW region (lp_nr < 0)
+	       it's difficult to decide what to do for notes
+	       coming from an insn that is not i3.  Just drop
+	       those.  */
+	    if (from_insn != i3)
+	      ;
+	    /* Otherwise the note must remain with the call or trapping
+	       instruction.  */
+	    else if (CALL_P (i3))
+	      place = i3;
+	    else
+	      {
+		gcc_assert (cfun->can_throw_non_call_exceptions);
+		/* If i3 can still trap preserve the note, otherwise we've
+		   combined things such that we can now prove that the
+		   instructions can't trap.  Drop the note in this case.  */
+		if (may_trap_p (i3))
+		  place = i3;
+	      }
+	    break;
+	  }
 
 	case REG_ARGS_SIZE:
 	  /* ??? How to distribute between i3-i1.  Assume i3 contains the
diff --git a/gcc/testsuite/gcc.dg/torture/pr105231.c b/gcc/testsuite/gcc.dg/torture/pr105231.c
new file mode 100644
index 00000000000..50459219c08
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr105231.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-require-effective-target dfp } */
+/* { dg-additional-options "-fsanitize-coverage=trace-pc -fnon-call-exceptions --param=max-cse-insns=1 -frounding-math" } */
+/* { dg-additional-options "-mstack-arg-probe" { target x86_64-*-* i?86-*-* } } */
+
+void baz (int *);
+void bar (double, double, _Decimal64);
+
+void
+foo (void)
+{
+  int s __attribute__((cleanup (baz)));
+  bar (0xfffffffffffffffe, 0xebf3fff2fbebaf7f, 0xffffffffffffff);
+}
-- 
2.34.1

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

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-19 11:02 Richard Biener [this message]
2022-04-19 12:29 ` Segher Boessenkool
2022-04-19 12:58   ` Richard Biener
2022-04-19 13:19     ` Segher Boessenkool
2022-04-19 15:00       ` Richard Biener
2022-04-19 16:10         ` Segher Boessenkool

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=20220419110209.A4C1F139BE@imap2.suse-dmz.suse.de \
    --to=rguenther@suse.de \
    --cc=ebotcazou@adacore.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=rth@redhat.com \
    --cc=segher@kernel.crashing.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).