re PR rtl-optimization/84614 (wrong code with u16->u128 extension at aarch64 -fno...
authorJakub Jelinek <jakub@redhat.com>
Fri, 2 Mar 2018 09:16:50 +0000 (10:16 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 2 Mar 2018 09:16:50 +0000 (10:16 +0100)
PR target/84614
* rtl.h (prev_real_nondebug_insn, next_real_nondebug_insn): New
prototypes.
* emit-rtl.c (next_real_insn, prev_real_insn): Fix up function
comments.
(next_real_nondebug_insn, prev_real_nondebug_insn): New functions.
* cfgcleanup.c (try_head_merge_bb): Use prev_real_nondebug_insn
instead of a loop around prev_real_insn.
* combine.c (move_deaths): Use prev_real_nondebug_insn instead of
prev_real_insn.

* gcc.dg/pr84614.c: New test.

From-SVN: r258129

gcc/ChangeLog
gcc/cfgcleanup.c
gcc/combine.c
gcc/emit-rtl.c
gcc/rtl.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr84614.c [new file with mode: 0644]

index bb32cf440e2016216a14f76516c4bf9fffe3fe0a..09cae39cc27942fad347f5cf7946f63fe35615d9 100644 (file)
@@ -1,5 +1,16 @@
 2018-03-02  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/84614
+       * rtl.h (prev_real_nondebug_insn, next_real_nondebug_insn): New
+       prototypes.
+       * emit-rtl.c (next_real_insn, prev_real_insn): Fix up function
+       comments.
+       (next_real_nondebug_insn, prev_real_nondebug_insn): New functions.
+       * cfgcleanup.c (try_head_merge_bb): Use prev_real_nondebug_insn
+       instead of a loop around prev_real_insn.
+       * combine.c (move_deaths): Use prev_real_nondebug_insn instead of
+       prev_real_insn.
+
        PR inline-asm/84625
        * config/i386/i386.c (ix86_print_operand): Use conditional
        output_operand_lossage instead of gcc_assert if CONST_VECTOR is not
index 6892d806e53272dc76b5adcb8accedc44cb5451f..4f721537eb2f7eb6eba32425e8b3139e1b85b9d8 100644 (file)
@@ -2448,9 +2448,7 @@ try_head_merge_bb (basic_block bb)
       max_match--;
       if (max_match == 0)
        return false;
-      do
-       e0_last_head = prev_real_insn (e0_last_head);
-      while (DEBUG_INSN_P (e0_last_head));
+      e0_last_head = prev_real_nondebug_insn (e0_last_head);
     }
 
   if (max_match == 0)
index 6b761c609ae9f0db0b7cb5a4a567372ea7332280..ddea5b18fe07cf282e9a3714c87de0309d9a9faf 100644 (file)
@@ -13923,7 +13923,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn,
         FROM_LUID and TO_INSN.  If so, find it.  This is PR83304.  */
       if (!where_dead || DF_INSN_LUID (where_dead) >= DF_INSN_LUID (to_insn))
        {
-         rtx_insn *insn = prev_real_insn (to_insn);
+         rtx_insn *insn = prev_real_nondebug_insn (to_insn);
          while (insn
                 && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (to_insn)
                 && DF_INSN_LUID (insn) >= from_luid)
@@ -13935,7 +13935,7 @@ move_deaths (rtx x, rtx maybe_kill_insn, int from_luid, rtx_insn *to_insn,
                  break;
                }
 
-             insn = prev_real_insn (insn);
+             insn = prev_real_nondebug_insn (insn);
            }
        }
 
index dd8fec3f34938a81398fd12be4671230611191f3..4dce18df04190395af4268d1252ba5fa32c326b3 100644 (file)
@@ -3597,7 +3597,7 @@ prev_nonnote_nondebug_insn_bb (rtx_insn *insn)
   return insn;
 }
 
-/* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
+/* Return the next INSN, CALL_INSN, JUMP_INSN or DEBUG_INSN after INSN;
    or 0, if there is none.  This routine does not look inside
    SEQUENCEs.  */
 
@@ -3616,7 +3616,7 @@ next_real_insn (rtx uncast_insn)
   return insn;
 }
 
-/* Return the last INSN, CALL_INSN or JUMP_INSN before INSN;
+/* Return the last INSN, CALL_INSN, JUMP_INSN or DEBUG_INSN before INSN;
    or 0, if there is none.  This routine does not look inside
    SEQUENCEs.  */
 
@@ -3633,6 +3633,42 @@ prev_real_insn (rtx_insn *insn)
   return insn;
 }
 
+/* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
+   or 0, if there is none.  This routine does not look inside
+   SEQUENCEs.  */
+
+rtx_insn *
+next_real_nondebug_insn (rtx uncast_insn)
+{
+  rtx_insn *insn = safe_as_a <rtx_insn *> (uncast_insn);
+
+  while (insn)
+    {
+      insn = NEXT_INSN (insn);
+      if (insn == 0 || NONDEBUG_INSN_P (insn))
+       break;
+    }
+
+  return insn;
+}
+
+/* Return the last INSN, CALL_INSN or JUMP_INSN before INSN;
+   or 0, if there is none.  This routine does not look inside
+   SEQUENCEs.  */
+
+rtx_insn *
+prev_real_nondebug_insn (rtx_insn *insn)
+{
+  while (insn)
+    {
+      insn = PREV_INSN (insn);
+      if (insn == 0 || NONDEBUG_INSN_P (insn))
+       break;
+    }
+
+  return insn;
+}
+
 /* Return the last CALL_INSN in the current list, or 0 if there is none.
    This routine does not look inside SEQUENCEs.  */
 
index c9dd7dd959fcaef387665ca60d9ef7b1e2eab566..f31b4ade9d3e91d7b8a773bc28923851ed26d3c2 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3277,6 +3277,8 @@ extern rtx_insn *next_nonnote_nondebug_insn (rtx_insn *);
 extern rtx_insn *next_nonnote_nondebug_insn_bb (rtx_insn *);
 extern rtx_insn *prev_real_insn (rtx_insn *);
 extern rtx_insn *next_real_insn (rtx);
+extern rtx_insn *prev_real_nondebug_insn (rtx_insn *);
+extern rtx_insn *next_real_nondebug_insn (rtx);
 extern rtx_insn *prev_active_insn (rtx_insn *);
 extern rtx_insn *next_active_insn (rtx_insn *);
 extern int active_insn_p (const rtx_insn *);
index b035c357dbe57b92e3ebb199af0fa3d58cb78fbf..cb19be5925b3cfcda84ca91b32470d4cf1742899 100644 (file)
@@ -1,5 +1,8 @@
 2018-03-02  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/84614
+       * gcc.dg/pr84614.c: New test.
+
        PR inline-asm/84625
        * gcc.target/i386/pr84625.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/pr84614.c b/gcc/testsuite/gcc.dg/pr84614.c
new file mode 100644 (file)
index 0000000..98af26b
--- /dev/null
@@ -0,0 +1,28 @@
+/* PR target/84614 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-Og -fno-split-wide-types -fno-tree-coalesce-vars -g --param=max-combine-insns=3 -fcompare-debug" } */
+
+unsigned __int128 a;
+
+unsigned __int128
+b (unsigned short c, unsigned int d)
+{
+  unsigned long long e;
+  __builtin_sub_overflow (0, d, &e);
+  e >>= c;
+  c ^= 65535;
+  d ^= 824;
+  return c + a + d + e;
+}
+
+int
+main ()
+{
+  unsigned __int128 x = b (0, 9);
+  if (__SIZEOF_INT__ * __CHAR_BIT__ == 32
+      && __SIZEOF_LONG_LONG__ * __CHAR_BIT__ == 64
+      && __SIZEOF_INT128__ * __CHAR_BIT__ == 128
+      && x != (((unsigned __int128) 1 << 64) | 0x10327))
+    __builtin_abort ();
+  return 0;
+}