In PR83424 combine's move_deaths puts a REG_DEAD not in the wrong place
because dead_or_set_regno_p does not account for CLOBBER insns.  This
fixes it.

Bootstrapped and tested on powerpc64-linux {-m32,-m64} and on x86_64-linux.
Is this okay for trunk?


Segher


2017-12-16  Segher Boessenkool  <seg...@kernel.crashing.org>

        PR rtl-optimization/83424
        * rtlanal.c (dead_or_set_regno_p): Handle CLOBBER just like SET.

gcc/testsuite/
        PR rtl-optimization/83424
        * gcc.dg/pr83424.c: New testsuite.

---
 gcc/rtlanal.c                  |    2 +-
 gcc/testsuite/gcc.dg/pr83424.c |   30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr83424.c

diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index c91f3f1..9f6988b 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -2082,7 +2082,7 @@ dead_or_set_regno_p (const rtx_insn *insn, unsigned int 
test_regno)
   if (GET_CODE (pattern) == COND_EXEC)
     return 0;
 
-  if (GET_CODE (pattern) == SET)
+  if (GET_CODE (pattern) == SET || GET_CODE (pattern) == CLOBBER)
     return covers_regno_p (SET_DEST (pattern), test_regno);
   else if (GET_CODE (pattern) == PARALLEL)
     {
diff --git a/gcc/testsuite/gcc.dg/pr83424.c b/gcc/testsuite/gcc.dg/pr83424.c
new file mode 100644
index 0000000..5a304f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr83424.c
@@ -0,0 +1,30 @@
+/* PR rtl-optimization/83424 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O -fno-tree-ccp -fno-tree-coalesce-vars" } */
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+typedef unsigned __int128 u128;
+
+u32 a, c;
+u8 b;
+
+static u128 __attribute__ ((noinline, noclone))
+foo (u128 p)
+{
+  u8 x = ~b;
+  p &= c;
+  x *= -p;
+  x &= a == 0;
+  x >>= 1;
+  return p + x;
+}
+
+int
+main (void)
+{
+  u128 x = foo (0);
+  if (x != 0)
+    __builtin_abort ();
+  return 0;
+}
-- 
1.7.10.4

Reply via email to