Created attachment 42899 [details] reduced testcase This ICE has been reproducing with various testcases, but the used command line switches were needed for all of them (only opt. level and max-sched-extend-regions-iters=n value varies). Compiler output: $ x86_64-pc-linux-gnu-gcc -Og -fschedule-insns -fsched-pressure -fno-sched-critical-path-heuristic -fno-sched-rank-heuristic --param=max-sched-extend-regions-iters=2 --param=sched-pressure-algorithm=2 testcase.c testcase.c: In function 'c': testcase.c:9:1: error: qsort comparator non-negative on sorted output: 1 } ^ during RTL pass: sched1 testcase.c:9:1: internal compiler error: qsort checking failed 0x6be441 qsort_chk_error /repo/gcc-trunk/gcc/vec.c:222 0x1779f5a qsort_chk(void*, unsigned long, unsigned long, int (*)(void const*, void const*)) /repo/gcc-trunk/gcc/vec.c:274 0x1683338 ready_sort_real /repo/gcc-trunk/gcc/haifa-sched.c:3087 0x168c6d2 schedule_block(basic_block_def**, void*) /repo/gcc-trunk/gcc/haifa-sched.c:6675 0xcd688a schedule_region /repo/gcc-trunk/gcc/sched-rgn.c:3174 0xcd688a schedule_insns() /repo/gcc-trunk/gcc/sched-rgn.c:3513 0xcd6cb3 schedule_insns() /repo/gcc-trunk/gcc/sched-rgn.c:3498 0xcd6cb3 rest_of_handle_sched /repo/gcc-trunk/gcc/sched-rgn.c:3717 0xcd6cb3 execute /repo/gcc-trunk/gcc/sched-rgn.c:3825 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. $ x86_64-pc-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=/repo/gcc-trunk/binary-latest-amd64/bin/x86_64-pc-linux-gnu-gcc COLLECT_LTO_WRAPPER=/repo/gcc-trunk/binary-trunk-255776-checking-yes-rtl-df-extra-nobootstrap-nographite-amd64/bin/../libexec/gcc/x86_64-pc-linux-gnu/8.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /repo/gcc-trunk//configure --enable-languages=c,c++ --enable-valgrind-annotations --disable-nls --enable-checking=yes,rtl,df,extra --disable-bootstrap --without-cloog --without-ppl --without-isl --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu --with-ld=/usr/bin/x86_64-pc-linux-gnu-ld --with-as=/usr/bin/x86_64-pc-linux-gnu-as --disable-libstdcxx-pch --prefix=/repo/gcc-trunk//binary-trunk-255776-checking-yes-rtl-df-extra-nobootstrap-nographite-amd64 Thread model: posix gcc version 8.0.0 20171218 (experimental) (GCC) Tested revisions: r255776 - ICE r255386 - ICE 7-branch r255536 - OK
So, in this case we have: (gdb) p debug_rtx (first[0]) (insn 4 2 3 2 (set (reg/v:SI 95 [ e ]) (reg:SI 4 si [ e ])) "pr83459.c":6 86 {*movsi_internal} (expr_list:REG_DEAD (reg:SI 4 si [ e ]) (nil))) $21 = void (gdb) p debug_rtx (first[1]) (insn 15 14 16 4 (set (reg:SI 98 [ b ]) (sign_extend:SI (mem/c:HI (symbol_ref:DI ("b") [flags 0x2] <var_decl 0x7ffff7ff5ea0 b>) [1 b+0 S2 A16]))) "pr83459.c":8 153 {extendhisi2} (nil)) $22 = void (gdb) p debug_rtx (first[2]) (insn 9 3 10 2 (set (reg:SI 96 [ a ]) (sign_extend:SI (mem/c:HI (symbol_ref:DI ("a") [flags 0x2] <var_decl 0x7ffff7ff5e10 a>) [1 a+0 S2 A16]))) "pr83459.c":7 153 {extendhisi2} (nil)) and p rank_for_schedule (&first[0], &first[1]) $24 = -1 determined by val = (dep_list_size (tmp2, SD_LIST_FORW) - dep_list_size (tmp, SD_LIST_FORW)); if (flag_sched_dep_count_heuristic && val != 0) return rfs_result (RFS_DEP_COUNT, val, tmp, tmp2); where val is -1, then p rank_for_schedule (&first[1], &first[2]) $25 = -4 determined by: /* If insns are equally good, sort by INSN_LUID (original insn order), so that we make the sort stable. This minimizes instruction movement, thus minimizing sched's effect on debugging and cross-jumping. */ return rfs_result (RFS_TIE, INSN_LUID (tmp) - INSN_LUID (tmp2), tmp, tmp2); and finally: p rank_for_schedule (&first[0], &first[2]) $26 = 1 determined by: /* Prefer instructions that occur earlier in the model schedule. */ if (sched_pressure == SCHED_PRESSURE_MODEL && INSN_BB (tmp) == target_bb && INSN_BB (tmp2) == target_bb) { diff = model_index (tmp) - model_index (tmp2); gcc_assert (diff != 0); return rfs_result (RFS_PRESSURE_INDEX, diff, tmp, tmp2); } which is checked earliest. If we want a stable sort, I'm afraid for SCHED_PRESSURE_MODEL we need to sort insns where INSN_BB (tmp) == target_bb and INSN_BB (tmp2) != target_bb or INSN_BB (tmp2) == target_bb and INSN_BB (tmp) != target_bb regardless of dep_list_size. Thoughts on this?
I agree with the analysis. Insns where INSN_BB (i) != target_bb correspond to (likely speculative) insns outside of current basic block, so for SCHED_PRESSURE_MODEL we definitely want to sort them _after_ insns from target_bb. When both insns are outside of current bb we can defer to next tiebreakers. The following (completely untested) patch implements this change. I can run it through a bootstrap/regtest cycle if it looks reasonable: diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 549e8961411..f169d57a634 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -2783,12 +2783,20 @@ rank_for_schedule (const void *x, const void *y) } /* Prefer instructions that occur earlier in the model schedule. */ - if (sched_pressure == SCHED_PRESSURE_MODEL - && INSN_BB (tmp) == target_bb && INSN_BB (tmp2) == target_bb) + if (sched_pressure == SCHED_PRESSURE_MODEL) { - diff = model_index (tmp) - model_index (tmp2); - gcc_assert (diff != 0); - return rfs_result (RFS_PRESSURE_INDEX, diff, tmp, tmp2); + if (INSN_BB (tmp) == target_bb) + { + if (INSN_BB (tmp2) == target_bb) + { + diff = model_index (tmp) - model_index (tmp2); + gcc_assert (diff != 0); + return rfs_result (RFS_PRESSURE_INDEX, diff, tmp, tmp2); + } + return rfs_result (RFS_PRESSURE_INDEX, -1, tmp, tmp2); + } + if (INSN_BB (tmp2) == target_bb) + return rfs_result (RFS_PRESSURE_INDEX, 1, tmp, tmp2); } /* Prefer the insn which has more later insns that depend on it.
Author: wilco Date: Thu Feb 8 12:29:28 2018 New Revision: 257481 URL: https://gcc.gnu.org/viewcvs?rev=257481&root=gcc&view=rev Log: PR84068, PR83459: Fix sort order of SCHED_PRESSURE_MODEL The comparison function for SCHED_PRESSURE_MODEL is incorrect. If either instruction is not in target_bb, the ordering is not well defined. Since all instructions outside the target_bb get the highest model_index, all we need to do is sort on model_index. If the model_index is the same we defer to RFS_DEP_COUNT and/or RFS_TIE. gcc/ PR rtl-optimization/84068 PR rtl-optimization/83459 * haifa-sched.c (rank_for_schedule): Fix SCHED_PRESSURE_MODEL sorting. gcc/testsuite PR rtl-optimization/84068 PR rtl-optimization/83459 * gcc.dg/pr84068.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr84068.c Modified: trunk/gcc/ChangeLog trunk/gcc/haifa-sched.c trunk/gcc/testsuite/ChangeLog
Fixed in r257481.