diff mbox

combine: Yet another distribute_notes problem (PR64682)

Message ID ab412d1606aaa4b099fb3a5f68541bab35b84d74.1421855844.git.segher@kernel.crashing.org
State New
Headers show

Commit Message

Segher Boessenkool Jan. 21, 2015, 4:16 p.m. UTC
If we are combining insns like

	I1: (... r90)   REG_DEAD r90
	I2: (set r90 ...)
	I3: (...)

resulting in

	I2: (set r90 ...)
	I3: (...)

distribute_notes for that REG_DEAD r90 wil start searching (backwards)
for r90 starting from I3.  Then it will find I2, and because it thinks
it is a dead set, delete it.

This fixes it.  Tested on powerpc64-linux (c,c++,ada,fortran) with
--disable-libsanitizer --disable-libgomp, -m32,-m32/-mpowerpc,-m64,
-m64/-mlra; and on x86_64-linux (c,c++,fortran), no other options.
The new testcase fails on x86_64-linux without the patch (-O2 or
higher).

Is this okay for mainline?


Segher


2015-01-21  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	PR rtl-optimization/64682
	* combine.c (distribute_notes): When moving a death note for
	a register that is set in the new I2, make sure to put it
	before that new I2.

gcc/testsuite/
	PR rtl-optimization/64682
	* gcc.c-torture/execute/pr64682.c: New file.

---
 gcc/combine.c                                 |  5 +++++
 gcc/testsuite/gcc.c-torture/execute/pr64682.c | 26 ++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)
 create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr64682.c

Comments

Richard Henderson Jan. 21, 2015, 10:04 p.m. UTC | #1
On 01/21/2015 08:16 AM, Segher Boessenkool wrote:
> 2015-01-21  Segher Boessenkool  <segher@kernel.crashing.org>
> 
> gcc/
> 	PR rtl-optimization/64682
> 	* combine.c (distribute_notes): When moving a death note for
> 	a register that is set in the new I2, make sure to put it
> 	before that new I2.
> 
> gcc/testsuite/
> 	PR rtl-optimization/64682
> 	* gcc.c-torture/execute/pr64682.c: New file.

Ok.


r~
diff mbox

Patch

diff --git a/gcc/combine.c b/gcc/combine.c
index 597aa80..5c763b4 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13684,6 +13684,11 @@  distribute_notes (rtx notes, rtx_insn *from_insn, rtx_insn *i3, rtx_insn *i2,
 		       || rtx_equal_p (XEXP (note, 0), elim_i0))
 		break;
 	      tem_insn = i3;
+	      /* If the new I2 sets the same register that is marked dead
+		 in the note, the note now should not be put on I2, as the
+		 note refers to a previous incarnation of the reg.  */
+	      if (i2 != 0 && reg_set_p (XEXP (note, 0), PATTERN (i2)))
+		tem_insn = i2;
 	    }
 
 	  if (place == 0)
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr64682.c b/gcc/testsuite/gcc.c-torture/execute/pr64682.c
new file mode 100644
index 0000000..58f610a
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr64682.c
@@ -0,0 +1,26 @@ 
+/* PR rtl-optimization/64682 */
+
+int a, b = 1;
+
+__attribute__((noinline, noclone)) void
+foo (int x)
+{
+  if (x != 5)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 56; i++)
+    for (; a; a--)
+      ;
+  int *c = &b;
+  if (*c)
+    *c = 1 % (unsigned int) *c | 5;
+
+  foo (b);
+
+  return 0;
+}