aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2017-12-13 15:05:57 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2017-12-13 15:05:57 +0100
commit2046f23f52d5ed4299f12e5f98a88491e4936c44 (patch)
treefdd3d7a0babdfbf3b3c64e2de65288c9cc43e89b
parent2b031ef48e365e256495a3e6d226a59f2290444f (diff)
downloadgcc-2046f23f52d5ed4299f12e5f98a88491e4936c44.zip
gcc-2046f23f52d5ed4299f12e5f98a88491e4936c44.tar.gz
gcc-2046f23f52d5ed4299f12e5f98a88491e4936c44.tar.bz2
combine: Fix PR83393
In move_deaths we move a REG_DEAD note if the instruction combination has extended the lifetime of a register so that the existing note is no longer valid. We find that note using reg_stat, but what that finds can refer to a later insn. If so, we cannot use the cached value. This patch implements that. PR rtl-optimization/83393 * combine.c (move_deaths): If reg_stat points to a too new insn in last_death, do not use it: find the proper insn instead. gcc/testsuite/ PR rtl-optimization/83393 * gcc.dg/pr83393.c: New testcase. From-SVN: r255606
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/combine.c2
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr83393.c38
4 files changed, 50 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9b4829d..5d992af 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-13 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/83393
+ * combine.c (move_deaths): If reg_stat points to a too new insn in
+ last_death, do not use it: find the proper insn instead.
+
2017-12-12 Jeff Law <law@redhat.com>
PR tree-optimization/83298
diff --git a/gcc/combine.c b/gcc/combine.c
index b6410c3..eb737f6 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -13880,7 +13880,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn,
/* If we do not know where the register died, it may still die between
FROM_LUID and TO_INSN. If so, find it. This is PR83304. */
- if (!where_dead)
+ if (!where_dead || DF_INSN_LUID (where_dead) >= DF_INSN_LUID (to_insn))
{
rtx_insn *insn = prev_real_insn (to_insn);
while (insn
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7159ab9..c5f1d44 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-12-13 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/83393
+ * gcc.dg/pr83393.c: New testcase.
+
2017-12-13 Nathan Sidwell <nathan@acm.org>
PR c++/15272
diff --git a/gcc/testsuite/gcc.dg/pr83393.c b/gcc/testsuite/gcc.dg/pr83393.c
new file mode 100644
index 0000000..a9a6b33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr83393.c
@@ -0,0 +1,38 @@
+/* PR rtl-optimization/83393 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-forward-propagate -fno-tree-bit-ccp" } */
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+typedef unsigned long long u64;
+
+u32 a, d;
+u64 b;
+u8 c;
+
+static u64 __attribute__ ((noinline, noclone))
+foo (u16 f, u64 g)
+{
+ f <<= 15;
+ f *= d;
+ f -= g %= 44;
+ f <<= f <= g;
+ c = 255;
+ c >>= (u8) f == 0;
+ f *= g;
+ c -= ~c;
+ return f + a + b + f;
+}
+
+int
+main (void)
+{
+#if (__SIZEOF_LONG_LONG__ == 8 && __SIZEOF_INT__ == 4 \
+ && __SIZEOF_SHORT__ == 2 && __CHAR_BIT__ == 8)
+ u64 x = foo (3, 0xE6C0011BBA6DBD7LL);
+ if (x != 0x1f66e)
+ __builtin_abort ();
+#endif
+ return 0;
+}