Hello! Apparently, the wrong insn is used when adding insn dependencies. The "last" index gets updated to the found !NONDEBUG_INSN. Use "first_arg" that points to the right insn instead.
2013-05-03 Uros Bizjak <ubiz...@gmail.com> PR target/57106 * config/i386/i386.c (add_parameter_dependencies): Add dependence between "first_arg" and "insn", not "last" and "insn". testsuite/ChangeLog: 2013-05-03 Uros Bizjak <ubiz...@gmail.com> * gcc.target/i386/pr57106.c: New test. Tested on x86_64-pc-linux-gnu {,-m32}. I will wait for Intel guys to check this patch with -fschedule-insns on their codes. Uros.
Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 198577) +++ config/i386/i386.c (working copy) @@ -24662,7 +24662,7 @@ add_parameter_dependencies (rtx call, rtx head) /* Add output depdendence between two function arguments if chain of output arguments contains likely spilled HW registers. */ if (is_spilled) - add_dependence (last, insn, REG_DEP_OUTPUT); + add_dependence (first_arg, insn, REG_DEP_OUTPUT); first_arg = last = insn; } else @@ -41355,7 +41355,8 @@ ix86_enum_va_list (int idx, const char **pname, tr #undef TARGET_SCHED_ADJUST_PRIORITY #define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority #undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK -#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK ix86_dependencies_evaluation_hook +#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK \ + ix86_dependencies_evaluation_hook /* The size of the dispatch window is the total number of bytes of object code allowed in a window. */ Index: testsuite/gcc.target/i386/pr57106.c =================================================================== --- testsuite/gcc.target/i386/pr57106.c (revision 0) +++ testsuite/gcc.target/i386/pr57106.c (working copy) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fschedule-insns -funroll-all-loops -fcompare-debug" } */ + +typedef void block128_f (int *, int); + +void +foo (int *out, int *iv, block128_f block) +{ + while (1) + { + *out = *out ^ *iv; + block (out, *out); + iv = out; + } +}