Hi!

As mentioned in the PR, SLOT_TEMP slots may be created during expansion,
and by the time the stv pass is run it is hard to find out what are the
insn ranges where those temporary slots from expansion are live and thus
where we should avoid reusing those even if they have the same mode.

The patch just never reuses temporary slots between expansion and stv
by introducing a new kind for the stv stack slots.

Bootstrapped/regtested on x86_64-linux and i686-linux, acked in the PR
by Uros, commited to trunk.

2016-12-14  Jakub Jelinek  <ja...@redhat.com>

        PR target/78791
        * config/i386/i386.h (enum ix86_stack_slot): Add SLOT_STV_TEMP.
        * config/i386/i386.c (dimode_scalar_chain::make_vector_copies,
        dimode_scalar_chain::convert_reg): Use SLOT_STV_TEMP instead of
        SLOT_TEMP.

        * gcc.c-torture/execute/pr78791.c: New test.
        * gcc.target/i386/pr78791.c: New test.

--- gcc/config/i386/i386.h.jj   2016-12-12 22:46:54.000000000 +0100
+++ gcc/config/i386/i386.h      2016-12-14 16:11:54.953312786 +0100
@@ -2400,6 +2400,7 @@ enum ix86_stack_slot
   SLOT_CW_FLOOR,
   SLOT_CW_CEIL,
   SLOT_CW_MASK_PM,
+  SLOT_STV_TEMP,
   MAX_386_STACK_LOCALS
 };
 
--- gcc/config/i386/i386.c.jj   2016-12-12 22:46:54.000000000 +0100
+++ gcc/config/i386/i386.c      2016-12-14 16:12:45.905664834 +0100
@@ -3555,7 +3555,7 @@ dimode_scalar_chain::make_vector_copies
          }
        else
          {
-           rtx tmp = assign_386_stack_local (DImode, SLOT_TEMP);
+           rtx tmp = assign_386_stack_local (DImode, SLOT_STV_TEMP);
            emit_move_insn (adjust_address (tmp, SImode, 0),
                            gen_rtx_SUBREG (SImode, reg, 0));
            emit_move_insn (adjust_address (tmp, SImode, 4),
@@ -3632,7 +3632,7 @@ dimode_scalar_chain::convert_reg (unsign
            }
          else
            {
-             rtx tmp = assign_386_stack_local (DImode, SLOT_TEMP);
+             rtx tmp = assign_386_stack_local (DImode, SLOT_STV_TEMP);
              emit_move_insn (tmp, reg);
              emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 0),
                              adjust_address (tmp, SImode, 0));
--- gcc/testsuite/gcc.c-torture/execute/pr78791.c.jj    2016-12-14 
16:15:40.950438819 +0100
+++ gcc/testsuite/gcc.c-torture/execute/pr78791.c       2016-12-14 
16:14:15.000000000 +0100
@@ -0,0 +1,19 @@
+/* PR target/78791 */
+
+__attribute__((used, noinline, noclone)) unsigned long long
+foo (unsigned long long x, unsigned long long y, unsigned long long z)
+{
+  unsigned long long a = x / y;
+  unsigned long long b = x % y;
+  a |= z;
+  b ^= z;
+  return a + b;
+}
+
+int
+main ()
+{
+  if (foo (64, 7, 0) != 10 || foo (28, 3, 2) != 14)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.target/i386/pr78791.c.jj  2016-12-14 16:18:28.291310774 
+0100
+++ gcc/testsuite/gcc.target/i386/pr78791.c     2016-12-14 16:18:21.935391601 
+0100
@@ -0,0 +1,5 @@
+/* PR target/78791 */
+/* { dg-do run { target sse2_runtime } } */
+/* { dg-options "-O2 -msse2" } */
+
+#include "../../gcc.c-torture/execute/pr78791.c"

        Jakub

Reply via email to