Bug 83513 - [8 Regression] ICE: qsort checking failed (error: qsort comparator non-negative on sorted output: 3) in fill_vec_av_set in selective scheduler
Summary: [8 Regression] ICE: qsort checking failed (error: qsort comparator non-negati...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 8.0
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-checking, ice-on-valid-code
Depends on:
Blocks: qsort_chk
  Show dependency treegraph
 
Reported: 2017-12-20 17:46 UTC by Arseny Solokha
Modified: 2017-12-26 14:36 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-12-21 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arseny Solokha 2017-12-20 17:46:47 UTC
gcc-8.0.0-alpha20171217 snapshot (r255766) ICEs when compiling the following snippet w/ -O1 (-O2, -Os) -fschedule-insns -fselective-scheduling -fno-guess-branch-probability:

void
oh (long int qc, short int de)
{
  {
    long int uf = 0;
    int *xu, *gx = &uf;

 p6:
    *gx = (qc == 0) ? -1 : (qc - uf);
    if (de == *gx)
      {
        ++*xu;
        de = *xu;
      }
    else
      de = qc;
  }

  goto p6;
}

% gcc-8.0.0-alpha20171217 -O1 -fschedule-insns -fselective-scheduling -fno-guess-branch-probability -c -w vugfco5g.c                                                 
vugfco5g.c: In function 'oh':
vugfco5g.c:20:1: error: qsort comparator non-negative on sorted output: 3
 }
 ^
during RTL pass: sched1
vugfco5g.c:20:1: internal compiler error: qsort checking failed
0x829340 qsort_chk_error
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/vec.c:222
0x8293c7 qsort_chk(void*, unsigned long, unsigned long, int (*)(void const*, void const*))
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/vec.c:274
0xd069c4 vec<_expr*, va_heap, vl_embed>::qsort(int (*)(void const*, void const*))
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/vec.h:1050
0xd069c4 vec<_expr*, va_heap, vl_ptr>::qsort(int (*)(void const*, void const*))
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/vec.h:1812
0xd069c4 fill_vec_av_set
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:3725
0xd089ea fill_ready_list
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:4022
0xd089ea find_best_expr
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:4382
0xd089ea fill_insns
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:5539
0xd0ae50 schedule_on_fences
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:7356
0xd0ae50 sel_sched_region_2
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:7494
0xd0c588 sel_sched_region_1
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:7536
0xd0c588 sel_sched_region(int)
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:7637
0xd0d5e1 run_selective_scheduling()
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sel-sched.c:7713
0xcedadd rest_of_handle_sched
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sched-rgn.c:3715
0xcedadd execute
	/var/tmp/portage/sys-devel/gcc-8.0.0_alpha20171217/work/gcc-8-20171217/gcc/sched-rgn.c:3825
Comment 1 Martin Liška 2017-12-21 12:31:14 UTC
Confirmed, started with r255607.
Comment 2 Alexander Monakov 2017-12-21 14:30:45 UTC
Thanks. So the fix for PR 82398 was incomplete. Here we have insns:

i1: uid: 43  prio: 0  usefulness: 100%
i2: uid: 20  prio: 3  usefulness: 0%
i3: uid: 46  prio: 5  usefulness: 0%

and sel_rank_for_schedule says i2 < i3 by priority difference, but i1 < i2 && i3 < i1 by uid difference (btw it appears that either the comment or the sense of the last tiebreaker is inverted). Now priority comparison code doesn't account for the possibility of priority being 0.

I think we should either
 - simplify priority comparison to always compare by (prio + prio_adj) * use (in which case comparison i2<?>i3 will fall down to uid comparison), or
 - slightly expand it to always sort zero-usefulness exprs after non-zero ones (even when they have priority 0 like i1 in the example).

Andrey, do you have a preference?
Comment 3 Alexander Monakov 2017-12-21 16:14:36 UTC
> (btw it appears that either the comment or the sense of the last tiebreaker is inverted)

I have to take that back, I was confused by the unusual tmp vs. tmp2 order:

  sel_rank_for_schedule (const void *x, const void *y)
  {
    expr_t tmp = *(const expr_t *) y;
    expr_t tmp2 = *(const expr_t *) x;

... and the ordering sel_rank_for_schedule seeks to produce is "worse insns first, better last". The rest of the previous comment still stands.
Comment 4 Andrey Belevantsev 2017-12-22 10:11:42 UTC
(In reply to Alexander Monakov from comment #2)
> Thanks. So the fix for PR 82398 was incomplete. Here we have insns:
> 
> i1: uid: 43  prio: 0  usefulness: 100%
> i2: uid: 20  prio: 3  usefulness: 0%
> i3: uid: 46  prio: 5  usefulness: 0%
> 
> and sel_rank_for_schedule says i2 < i3 by priority difference, but i1 < i2
> && i3 < i1 by uid difference (btw it appears that either the comment or the
> sense of the last tiebreaker is inverted). Now priority comparison code
> doesn't account for the possibility of priority being 0.
> 
> I think we should either
>  - simplify priority comparison to always compare by (prio + prio_adj) * use
> (in which case comparison i2<?>i3 will fall down to uid comparison), or
>  - slightly expand it to always sort zero-usefulness exprs after non-zero
> ones (even when they have priority 0 like i1 in the example).
> 
> Andrey, do you have a preference?

I think the second choice is better as then we do not fall down to uids for different priorities.  I was hoping we would not get a zero usefulness in real life with REG_BR_PROB_BASE equal to 10000... sigh.
Comment 5 Alexander Monakov 2017-12-26 14:35:05 UTC
Author: amonakov
Date: Tue Dec 26 14:34:33 2017
New Revision: 256001

URL: https://gcc.gnu.org/viewcvs?rev=256001&root=gcc&view=rev
Log:
sel-sched: fix zero-usefulness case in sel_rank_for_schedule (PR 83513)

	PR rtl-optimization/83513
	* sel-sched.c (sel_rank_for_schedule): Order by non-zero usefulness
	before priority comparison.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/sel-sched.c
Comment 6 Alexander Monakov 2017-12-26 14:36:51 UTC
Fixed.