Hi!

What the STV pass does is clearly wrong, it meant to grab a sequence
of instructions out of a sequence and emit it somewhere else, but
calls end_sequence too late, so the sequence bookkepping vars get
corrupted.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2016-03-08  Jakub Jelinek  <ja...@redhat.com>

        PR target/70110
        * config/i386/i386.c (scalar_chain::make_vector_copies,
        scalar_chain::convert_reg): Call end_sequence in between
        get_insns and emit_conversion_insns rather than after both
        calls.

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

--- gcc/config/i386/i386.c.jj   2016-03-04 21:27:48.000000000 +0100
+++ gcc/config/i386/i386.c      2016-03-07 10:03:44.465981310 +0100
@@ -3272,8 +3272,9 @@ scalar_chain::make_vector_copies (unsign
                            gen_rtx_SUBREG (SImode, reg, 4));
            emit_move_insn (vreg, tmp);
          }
-       emit_conversion_insns (get_insns (), insn);
+       rtx_insn *seq = get_insns ();
        end_sequence ();
+       emit_conversion_insns (seq, insn);
 
        if (dump_file)
          fprintf (dump_file,
@@ -3348,8 +3349,9 @@ scalar_chain::convert_reg (unsigned regn
              emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 4),
                              adjust_address (tmp, SImode, 4));
            }
-         emit_conversion_insns (get_insns (), insn);
+         rtx_insn *seq = get_insns ();
          end_sequence ();
+         emit_conversion_insns (seq, insn);
 
          if (dump_file)
            fprintf (dump_file,
--- gcc/testsuite/gcc.dg/pr70110.c.jj   2016-03-07 10:16:22.211631464 +0100
+++ gcc/testsuite/gcc.dg/pr70110.c      2016-03-07 10:16:05.000000000 +0100
@@ -0,0 +1,39 @@
+/* PR target/70110 */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-additional-options "-msse2" { target i?86-*-* x86_64-*-* } } */
+
+int a, c, d, f, h;
+long long b;
+
+static inline void
+foo (void)
+{
+  if (a) 
+    foo ();
+  b = c;
+}
+
+static inline void 
+bar (int p)
+{
+  if (p)
+    f = 0; 
+  b |= c; 
+} 
+
+void
+baz (int g, int i)
+{
+  for (b = d; (d = 1) != 0; )
+    {
+      if (a)
+       foo ();
+      b |= c;
+      bar (h); 
+      bar (g); 
+      bar (h); 
+      bar (i); 
+      bar (h);
+    }
+}

        Jakub

Reply via email to