Bug 96394 - [10/11 Regression] ICE in add_new_edges_to_heap, at ipa-inline.c:1746 (-O3 PGO)
Summary: [10/11 Regression] ICE in add_new_edges_to_heap, at ipa-inline.c:1746 (-O3 PGO)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: ipa (show other bugs)
Version: 10.2.0
: P1 normal
Target Milestone: 10.3
Assignee: Martin Jambor
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2020-07-30 22:39 UTC by Sergei Trofimovich
Modified: 2020-10-16 10:20 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-07-31 00:00:00


Attachments
all.tar.gz (854.60 KB, application/gzip)
2020-07-30 22:43 UTC, Sergei Trofimovich
Details
gcc-tauthon-734006-PR96394.tar.gz (69.74 KB, application/gzip)
2020-07-30 23:09 UTC, Sergei Trofimovich
Details
b.tar.gz (695 bytes, application/gzip)
2020-09-23 21:59 UTC, Sergei Trofimovich
Details
b.tar.gz (687 bytes, application/gzip)
2020-09-23 22:04 UTC, Sergei Trofimovich
Details
Single file test-case (783 bytes, patch)
2020-09-29 07:41 UTC, Martin Liška
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2020-07-30 22:39:45 UTC
It's a forward of https://bugs.gentoo.org/734006 where Ștefan Talpalaru found an ICE when gcc tries to build PGO-optimised variant of python tauthon-2.8.2.

I can consistently reproduce the crash on gcc-10.2.0 and was able to extract the backtrace from -O0 ggdb3 gcc:

$ ${HOME}/dev/git/gcc-10-build/gcc/xgcc -B${HOME}/dev/git/gcc-10-build/gcc  -pthread -fPIC -fno-strict-aliasing -O3 -frecord-gcc-switches -fwrapv -DNDEBUG -fprofile-use -fprofile-correction -I. -I/tmp/portage/dev-lang/tauthon-2.8.2/work/tauthon-2.8.2/Include -I/tmp/portage/dev-lang/tauthon-2.8.2/work/x86_64-pc-linux-gnu -c /tmp/portage/dev-lang/tauthon-2.8.2/work/tauthon-2.8.2/Modules/parsermodule.c -o build/temp.linux-x86_64-2.8/tmp/portage/dev-lang/tauthon-2.8.2/work/tauthon-2.8.2/Modules/parsermodule.o -v -fdump-ipa-all-slim

Breakpoint 2, internal_error (gmsgid=0x297d49f "in %s, at %s:%d") at ../../gcc-10/gcc/diagnostic.c:1706
1706    {
(gdb) bt
#0  internal_error (gmsgid=0x297d49f "in %s, at %s:%d") at ../../gcc-10/gcc/diagnostic.c:1706
#1  0x0000000002063d64 in fancy_abort (file=0x2912678 "../../gcc-10/gcc/ipa-inline.c", line=1746, function=0x2912cd4 "add_new_edges_to_heap") at ../../gcc-10/gcc/diagnostic.c:1778
#2  0x0000000001f3fb12 in add_new_edges_to_heap (heap=0x7fffffffce90, new_edges=...) at ../../gcc-10/gcc/ipa-inline.c:1746
#3  0x0000000001f412e0 in inline_small_functions () at ../../gcc-10/gcc/ipa-inline.c:2210
#4  0x0000000001f43074 in ipa_inline () at ../../gcc-10/gcc/ipa-inline.c:2689
#5  0x0000000001f43eb1 in (anonymous namespace)::pass_ipa_inline::execute (this=0x2f03ce0) at ../../gcc-10/gcc/ipa-inline.c:3091
#6  0x0000000000fd326c in execute_one_pass (pass=0x2f03ce0) at ../../gcc-10/gcc/passes.c:2502
#7  0x0000000000fd41c9 in execute_ipa_pass_list (pass=0x2f03ce0) at ../../gcc-10/gcc/passes.c:2929
#8  0x0000000000adbb78 in ipa_passes () at ../../gcc-10/gcc/cgraphunit.c:2678
#9  0x0000000000adbd95 in symbol_table::compile (this=0x7ffff7865100) at ../../gcc-10/gcc/cgraphunit.c:2755
#10 0x0000000000adc33d in symbol_table::finalize_compilation_unit (this=0x7ffff7865100) at ../../gcc-10/gcc/cgraphunit.c:3002
#11 0x00000000011332a9 in compile_file () at ../../gcc-10/gcc/toplev.c:483
#12 0x00000000011364aa in do_compile () at ../../gcc-10/gcc/toplev.c:2298
#13 0x00000000011367b6 in toplev::main (this=0x7fffffffd266, argc=37, argv=0x7fffffffd378) at ../../gcc-10/gcc/toplev.c:2437
#14 0x0000000002035d42 in main (argc=37, argv=0x7fffffffd378) at ../../gcc-10/gcc/main.c:39
(gdb) fr 2
#2  0x0000000001f3fb12 in add_new_edges_to_heap (heap=0x7fffffffce90, new_edges=...) at ../../gcc-10/gcc/ipa-inline.c:1746
1746          gcc_assert (!edge->aux);
(gdb) list
1741    {
1742      while (new_edges.length () > 0)
1743        {
1744          struct cgraph_edge *edge = new_edges.pop ();
1745
1746          gcc_assert (!edge->aux);
1747          gcc_assert (edge->callee);
1748          if (edge->inline_failed
1749              && can_inline_edge_p (edge, true)
1750              && want_inline_small_function_p (edge, true)

Dumping the edge: validate_chain_two_ops/133 -> validate_arith_expr/135

(gdb) call edge->caller->dump(stdout)
validate_chain_two_ops/133 (validate_chain_two_ops) @0x7ffff6efc708
  Type: function definition analyzed
  Visibility: prevailing_def_ironly
  previous sharing asm name: 430
  References: parser_error/46 (read)
  Referring:
  Function validate_chain_two_ops/133 is inline copy in validate_shift_expr/134
  Availability: local
  Profile id: 607042219
  Function flags: count:395 (estimated locally, globally 0) first_run:27 body local unlikely_executed
  Called by: validate_shift_expr/134 (inlined) (395 (estimated locally, globally 0),1.00 per call)
  Calls: validate_arith_expr/135 (indirect_inlining) (9 (estimated locally, globally 0 adjusted),0.02 per call) validate_arith_expr/135 (indirect_inlining) (394 (estimated locally, globally 0 adjusted),1.00 per call) PyErr_Format/202 (0 (precise),0.00 per call)

(gdb) call edge->callee->dump(stdout)
validate_arith_expr/135 (validate_arith_expr) @0x7ffff6efc9d8
  Type: function definition analyzed
  Visibility: prevailing_def_ironly
  previous sharing asm name: 435
  Address is taken.
  References: parser_error/46 (read)
  Referring:
  Availability: available
  Profile id: 829576279
  Function flags: count:1 (adjusted) first_run:28 body hot
  Called by: validate_chain_two_ops/133 (indirect_inlining) (9 (estimated locally, globally 0 adjusted),0.02 per call) validate_chain_two_ops/491 (indirect_inlining) (9 (adjusted),0.02 per call) validate_chain_two_ops/431 (indirect_inlining) (9 (estimated locally, globally 0 adjusted),0.02 per call) validate_chain_two_ops/133 (indirect_inlining) (394 (estimated locally, globally 0 adjusted),1.00 per call) validate_node/162 (0 (precise),0.00 per call)
  Calls: PyErr_Format/202 (0 (precise),0.00 per call) validate_chain_two_ops/430 (inlined) (1 (adjusted),1.00 per call)

If I understand the assert correctly edge was added twice in the heap (or similar?).
Comment 1 Sergei Trofimovich 2020-07-30 22:43:23 UTC
Created attachment 48966 [details]
all.tar.gz

all.tar.gz is a preprocessed file, corresponding .gcda file and a few ipa dumps.
Comment 2 Sergei Trofimovich 2020-07-30 22:48:11 UTC
My guess is it's somehow related to the fact that inliner did 'termvalid' inline (twice probably?):

"""
static int
validate_chain_two_ops(node *tree, int (*termvalid)(node *), int op1, int op2)
 {
    int pos = 1;
    int nch = ((tree)->n_nchildren);
    int res = ((((nch) & 1) == 1)
               && (*termvalid)((&(tree)->n_child[0])));

    for ( ; res && (pos < nch); pos += 2) {
        if ((((&(tree)->n_child[pos]))->n_type) != op1)
            res = validate_ntype((&(tree)->n_child[pos]), op2);
        if (res)
            res = (*termvalid)((&(tree)->n_child[pos + 1]));
    }
    return (res);
}


static int
validate_shift_expr(node *tree)
{
    return (validate_ntype(tree, 321)
            && validate_chain_two_ops(tree, validate_arith_expr,
                                      34, 35));
}


static int
validate_arith_expr(node *tree)
{
    return (validate_ntype(tree, 322)
            && validate_chain_two_ops(tree, validate_term, 14, 15));
}
"""

I can't craft short example from this as is. Is there a way to reduce with cvise/creduce both .c and .gcda files at the same time?
Comment 3 Sergei Trofimovich 2020-07-30 23:09:19 UTC
Created attachment 48967 [details]
gcc-tauthon-734006-PR96394.tar.gz

gcc-tauthon-734006-PR96394.tar.gz is seemingly self-contained example.

It contains preprocessed file, .gcda file and a gcc command (with absolute path to gcc).

GCC is built as:

$ :/home/slyfox/dev/git/gcc-10-build/gcc/xgcc -B/home/slyfox/dev/git/gcc-10-build/gcc -v
Reading specs from /home/slyfox/dev/git/gcc-10-build/gcc/specs
COLLECT_GCC=/home/slyfox/dev/git/gcc-10-build/gcc/xgcc
COLLECT_LTO_WRAPPER=/home/slyfox/dev/git/gcc-10-build/gcc/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-10/configure --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu --enable-languages=c,c++ --disable-bootstrap --with-multilib-list=m64 --prefix=/home/slyfox/dev/git/gcc-10-build/../gcc-native-quick-installed --disable-nls --without-isl --disable-libsanitizer --disable-libvtv --disable-libgomp --disable-libstdcxx-pch --disable-libunwind-exceptions CFLAGS='-O0 -ggdb3 ' CXXFLAGS='-O0 -ggdb3 ' --with-sysroot=/usr/x86_64-HEAD-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.1 20200729 (GCC)
Comment 4 Martin Liška 2020-07-31 06:20:36 UTC
Can you please provide steps how to build entire package with PGO?
I'll try to bisect that then.
Comment 5 Martin Liška 2020-07-31 06:21:16 UTC
> I can't craft short example from this as is. Is there a way to reduce with
> cvise/creduce both .c and .gcda files at the same time?

This is a problematic reduction as .gcda file contains checksums of the source file and one needs to run an instrumented binary.
Comment 6 Martin Liška 2020-07-31 06:52:28 UTC
I reproduced that locally..
Comment 7 Martin Liška 2020-07-31 12:11:52 UTC
Started with r10-6299-g845bb366adcf702331de3d8022fd0e1c1c918607.
Honza can you please take a look?
Comment 8 Sergei Trofimovich 2020-09-06 11:35:25 UTC
Might end up being caused by the same bug in PR96913: TOPN streaming from/for shared libraries is incorrect.

Proposed patch: https://gcc.gnu.org/pipermail/gcc-patches/2020-September/553320.html
Comment 9 Sergei Trofimovich 2020-09-06 21:21:24 UTC
(In reply to Sergei Trofimovich from comment #8)
> Might end up being caused by the same bug in PR96913: TOPN streaming
> from/for shared libraries is incorrect.
> 
> Proposed patch:
> https://gcc.gnu.org/pipermail/gcc-patches/2020-September/553320.html

The patch is not enough to fix the ICE. It only converts gcc-11's hangup to the ICE (as as gcc-10).

Here is the somewhat selfcontained reproducer of the original bug:

    https://dev.gentoo.org/~slyfox/bugs/96394-pgo-ipa-ICE/tauthon-repro-
gcc-10.tar.bz2 (13MB)

The result on gcc-11 with above gcc patch:

  $ LANG=C ./try.bash
  ... < takes a while >


during IPA pass: inline
../tauthon-2.8.2/Modules/parsermodule.c:3760:1: internal compiler error: in add_new_edges_to_heap, at ipa-inline.c:1754
 3760 | }
      | ^
0x5ef2b3 add_new_edges_to_heap
        /usr/src/debug/sys-devel/gcc-11.0.0_pre9999/gcc-11.0.0_pre9999/gcc/ipa-inline.c:1754
0x1429b89 inline_small_functions
        /usr/src/debug/sys-devel/gcc-11.0.0_pre9999/gcc-11.0.0_pre9999/gcc/ipa-inline.c:2218
0x1429b89 ipa_inline
        /usr/src/debug/sys-devel/gcc-11.0.0_pre9999/gcc-11.0.0_pre9999/gcc/ipa-inline.c:2697
0x1429b89 execute
        /usr/src/debug/sys-devel/gcc-11.0.0_pre9999/gcc-11.0.0_pre9999/gcc/ipa-inline.c:3099
Comment 10 Sergei Trofimovich 2020-09-23 21:58:23 UTC
Finally managed to shrink it down to self-contained example. It has to be split into two .c files (and one header) to prevent analyzer from inferring too much:

// node.h:
void bug(void);
void * PyErr_Format(const void * ...);

typedef struct _entry {
    int has_next;
    int next_ix;
    int count;
} entry;
extern entry table[];

// main.c:
  #include "node.h"

  void * PyErr_Format(const void * ...){ return 0; }

  int main(void)
  {
    bug();
  }

  entry table[2] = {
    { .has_next = 1
    , .next_ix  = 1
    , .count    = 0
    },
    { .has_next = 0
    , .next_ix  = 0
    , .count    = 0
    },
  };

// parsermodule.c:

  #include "node.h"

  void ae(entry *);
  int h(entry *);
  int ap(entry *);
  int ag(entry *);

  int ag(entry *j) {
    if (j->has_next)
      h(&table[j->next_ix]);
    return 0;
  }
  static int ai(entry *j, int k(entry *), int l, int m) {
    int am = 1;
    int ab;

    /* k is either 'h' or 'ap': 50%/50% */
    ab = k(j);

    /* loop never gets executed on real data */
    for (; j->count >= 2; am += 2)
      if (l) {
        entry *i = &table[am + m];
        PyErr_Format(i);
      }
    return ab;
  }
  void bug() {
    h(table);
    h(table);
  }
  int h(entry *j) { return ai(j, ap, 4, 5); }
  int ap(entry *j) { return ai(j, ag, 14, 4); }

Commands to crash:

$ g++-11.0.0 -O2 -c -fprofile-generate parsermodule.c -o parsermodule.o
$ g++-11.0.0 -O2 -c -fprofile-generate main.c -o main.o
$ g++-11.0.0 -O2 -fprofile-generate main.o parsermodule.o -o b
$ ./b
$ g++-11.0.0 -O2 -c -fprofile-use parsermodule.c -o parsermodule.o -fopt-info

parsermodule.c:20:9: optimized: Indirect call -> direct call k_6(D) => ap (will resolve by ipa-profile)
parsermodule.c:20:9: optimized: Indirect call -> direct call k_6(D) => ag (will resolve by ipa-profile)
parsermodule.c:20:9: optimized:  Inlined int ag(entry*)/7 into int ai(entry*, int (*)(entry*), int, int)/1 which now has time 15.125000 and size 25, net change of +2.
parsermodule.c:20:9: optimized: converting indirect call in int ai(entry*, int (*)(entry*), int, int)/8 to direct call to int ag(entry*)/0
parsermodule.c:35:29: optimized:  Inlined int ai(entry*, int (*)(entry*), int, int)/8 into int ap(entry*)/4 which now has time 8.625000 and size 15, net change of +6.
parsermodule.c:20:9: optimized: converting indirect call in int ai(entry*, int (*)(entry*), int, int)/1 to direct call to int ap(entry*)/4
during IPA pass: inline
parsermodule.c:35:45: internal compiler error: in add_new_edges_to_heap, at ipa-inline.c:1754
   35 | int ap(entry *j) { return ai(j, ag, 14, 4); }
      |                                             ^
0x621b65 add_new_edges_to_heap
        /usr/src/debug/sys-devel/gcc-11.0.0_pre9999/gcc-11.0.0_pre9999/gcc/ipa-inline.c:1754
0x163ded7 inline_small_functions
        /usr/src/debug/sys-devel/gcc-11.0.0_pre9999/gcc-11.0.0_pre9999/gcc/ipa-inline.c:2218
0x163ded7 ipa_inline
        /usr/src/debug/sys-devel/gcc-11.0.0_pre9999/gcc-11.0.0_pre9999/gcc/ipa-inline.c:2697
0x163ded7 execute
        /usr/src/debug/sys-devel/gcc-11.0.0_pre9999/gcc-11.0.0_pre9999/gcc/ipa-inline.c:3099
Please submit a full bug report,
Comment 11 Sergei Trofimovich 2020-09-23 21:59:00 UTC
Created attachment 49263 [details]
b.tar.gz

Also attaching tiny example as b.tar.gz
Comment 12 Sergei Trofimovich 2020-09-23 22:04:13 UTC
Created attachment 49264 [details]
b.tar.gz
Comment 13 Martin Liška 2020-09-24 10:31:44 UTC
Thank you Sergei for the reduced test-case. What happens:

(gdb) p ie->caller->debug()
ai/1 (ai) @0x7ffff772b168
  Type: function definition analyzed
  Visibility: prevailing_def_ironly
  previous sharing asm name: 8
  References: table/5 (addr) ap/4 (addr) (speculative) ag/0 (addr) (speculative) 
  Referring: 
  Function ai/1 is inline copy in h/3
  Availability: local
  Profile id: 1923518911
  Function flags: count:4 (precise) first_run:4 body local hot
  Called by: h/3 (inlined) (4 (precise),1.00 per call) 
  Calls: ag/7 (speculative) (inlined) (2 (adjusted),0.50 per call) ap/4 (speculative) (2 (adjusted),0.50 per call) PyErr_Format/6 (0 (precise),0.00 per call) 
   Indirect call(speculative) (0 (adjusted),0.00 per call)  of param:1 (vptr maybe changed) Num speculative call targets: 2

We first enqueu the edge ai/1 -> ap/4 and then ipa_make_edge_direct_to_target is called for the Indirect call (with speculative=false) and we end up:

(gdb) p ie->caller->debug()
ai/1 (ai) @0x7ffff772b168
  Type: function definition analyzed
  Visibility: prevailing_def_ironly
  previous sharing asm name: 8
  References: table/5 (addr) 
  Referring: 
  Function ai/1 is inline copy in h/3
  Availability: local
  Profile id: 1923518911
  Function flags: count:4 (precise) first_run:4 body local hot
  Called by: h/3 (inlined) (4 (precise),1.00 per call) 
  Calls: ap/4 (4 (adjusted),1.00 per call) PyErr_Format/6 (0 (precise),0.00 per call) 

and we add the edge again to the heap in ipa-prop:
  3830                new_edges->safe_push (new_direct_edge);

and we ICE due to that. I tried not to add the edge in case new_direct_edge->aux is NULL, but a sanity check in inliner fails:

during IPA pass: inline
parsermodule.c:35:1: internal compiler error: in estimate_calls_size_and_time, at ipa-fnsummary.c:3328
   35 | int ap(entry *j) { return ai(j, ag, 14, 4); }
      | ^~~

So I guess a profile masage is needed. Leaving to Martin as he's more familiar with IPA PROP. Something similar to ipa-prop.c:3309-3316?
Comment 14 Martin Jambor 2020-09-25 14:15:32 UTC
I can confirm the analysis, except that I see the edge we're trying to
add to the heap as already inlined (as a speculative edge it got
inlined even its caller was).  Also just not adding an edge with
non-NULL aux works for me - and at least I cannot think of anything
smarter, I guess the inliner has to figure out it has already dealt
with it.

If it indeed can cause an assert failure in
estimate_calls_size_and_time then I think we simply we need to force
it not to "use_table" when it next comes around to the caller.
Comment 15 Martin Jambor 2020-09-25 15:46:26 UTC
so after Martin asked some good questions, it turns out this should probably be avoided in ipa-prop, after all, as with, for example (untested):

diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index b28c78eeab4..58ffedc20b1 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -3787,11 +3787,12 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
 
       param_index = ici->param_index;
       jfunc = ipa_get_ith_jump_func (top, param_index);
-      cgraph_node *spec_target = NULL;
 
-      /* FIXME: This may need updating for multiple calls.  */
-      if (ie->speculative)
-       spec_target = ie->first_speculative_call_target ()->callee;
+      auto_vec<cgraph_node *, 4> spec_targets;
+      for (cgraph_edge *direct = ie->first_speculative_call_target ();
+          direct;
+          direct = direct->next_speculative_call_target ())
+       spec_targets.safe_push (direct->callee);
 
       if (!opt_for_fn (node->decl, flag_indirect_inlining))
        new_direct_edge = NULL;
@@ -3814,7 +3815,7 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
 
       /* If speculation was removed, then we need to do nothing.  */
       if (new_direct_edge && new_direct_edge != ie
-         && new_direct_edge->callee == spec_target)
+         && spec_targets.contains (new_direct_edge->callee))
        {
          new_direct_edge->indirect_inlining_edge = 1;
          top = IPA_EDGE_REF (cs);
Comment 16 Martin Liška 2020-09-29 07:41:02 UTC
I believe Martin's patch is correct, I'll add a single file test-case for the PR.
Comment 17 Martin Liška 2020-09-29 07:41:20 UTC
Created attachment 49283 [details]
Single file test-case
Comment 18 Martin Jambor 2020-10-01 17:41:59 UTC
I proposed the patch on the mailing list (I guess I should put Martin's name at least to the testsuite ChangeLog and probably to both):

https://gcc.gnu.org/pipermail/gcc-patches/2020-October/555284.html
Comment 19 Martin Liška 2020-10-01 18:42:38 UTC
(In reply to Martin Jambor from comment #18)
> I proposed the patch on the mailing list (I guess I should put Martin's name
> at least to the testsuite ChangeLog and probably to both):
> 

Don't worry about it, just leave the patch as is.
Comment 20 Sergei Trofimovich 2020-10-02 23:02:33 UTC
(In reply to Martin Jambor from comment #18)
> I proposed the patch on the mailing list (I guess I should put Martin's name
> at least to the testsuite ChangeLog and probably to both):
> 
> https://gcc.gnu.org/pipermail/gcc-patches/2020-October/555284.html

Tested the patch against gcc-10.2.0 on original tauthon-2.8.2 test. Works as well. Thank you!
Comment 21 CVS Commits 2020-10-07 12:35:27 UTC
The master branch has been updated by Martin Jambor <jamborm@gcc.gnu.org>:

https://gcc.gnu.org/g:e089e43365f7f2a90979e2316aea25d44823f5a3

commit r11-3698-ge089e43365f7f2a90979e2316aea25d44823f5a3
Author: Martin Jambor <mjambor@suse.cz>
Date:   Wed Oct 7 14:12:49 2020 +0200

    ipa-prop: Fix multiple-target speculation resolution
    
    As the FIXME which this patch removes states, the current code does
    not work when a call with multiple speculative targets gets resolved
    through parameter tracking during inlining - it feeds the inliner an
    edge it has already dealt with.  The patch makes the code which should
    prevent it aware of the possibility that that speculation can have
    more than one target now.
    
    gcc/ChangeLog:
    
    2020-09-30  Martin Jambor  <mjambor@suse.cz>
    
            PR ipa/96394
            * ipa-prop.c (update_indirect_edges_after_inlining): Do not add
            resolved speculation edges to vector of new direct edges even in
            presence of multiple speculative direct edges for a single call.
    
    gcc/testsuite/ChangeLog:
    
    2020-09-30  Martin Jambor  <mjambor@suse.cz>
    
            PR ipa/96394
            * gcc.dg/tree-prof/pr96394.c: New test.
Comment 22 CVS Commits 2020-10-16 10:16:43 UTC
The releases/gcc-10 branch has been updated by Martin Jambor <jamborm@gcc.gnu.org>:

https://gcc.gnu.org/g:a9e64bb6d0801f29d65f357f90e6d7a2daeb6ca9

commit r10-8897-ga9e64bb6d0801f29d65f357f90e6d7a2daeb6ca9
Author: Martin Jambor <mjambor@suse.cz>
Date:   Wed Oct 7 14:12:49 2020 +0200

    ipa-prop: Fix multiple-target speculation resolution
    
    As the FIXME which this patch removes states, the current code does
    not work when a call with multiple speculative targets gets resolved
    through parameter tracking during inlining - it feeds the inliner an
    edge it has already dealt with.  The patch makes the code which should
    prevent it aware of the possibility that that speculation can have
    more than one target now.
    
    gcc/ChangeLog:
    
    2020-09-30  Martin Jambor  <mjambor@suse.cz>
    
            PR ipa/96394
            * ipa-prop.c (update_indirect_edges_after_inlining): Do not add
            resolved speculation edges to vector of new direct edges even in
            presence of multiple speculative direct edges for a single call.
    
    gcc/testsuite/ChangeLog:
    
    2020-09-30  Martin Jambor  <mjambor@suse.cz>
    
            PR ipa/96394
            * gcc.dg/tree-prof/pr96394.c: New test.
    
    (cherry picked from commit e089e43365f7f2a90979e2316aea25d44823f5a3)
Comment 23 Martin Jambor 2020-10-16 10:20:59 UTC
Fixed.