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