diff mbox series

rtl-optimization/105231 - distribute_notes and REG_EH_REGION

Message ID 20220414132905.967FE132C0@imap2.suse-dmz.suse.de
State New
Headers show
Series rtl-optimization/105231 - distribute_notes and REG_EH_REGION | expand

Commit Message

Richard Biener April 14, 2022, 1:29 p.m. UTC
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.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

OK?

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

	PR rtl-optimization/105231
	* combine.cc (distribute_notes): Assert that a REG_EH_REGION
	is from i3 and only keep it there or drop it if the insn
	can not trap.

	* gcc.dg/torture/pr105231.c: New testcase.
---
 gcc/combine.cc                          | 12 +++++-------
 gcc/testsuite/gcc.dg/torture/pr105231.c | 15 +++++++++++++++
 2 files changed, 20 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr105231.c
diff mbox series

Patch

diff --git a/gcc/combine.cc b/gcc/combine.cc
index 53dcac92abc..ec53eda7595 100644
--- a/gcc/combine.cc
+++ b/gcc/combine.cc
@@ -14175,21 +14175,19 @@  distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
 	  break;
 
 	case REG_EH_REGION:
+	  /* A REG_EH_REGION note can only ever come from i3.  */
+	  gcc_assert (from_insn == i3);
 	  /* 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 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;
-	      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;
 
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);
+}