g++-10.0.0-alpha20191201 snapshot (r278886), 9.2, 8.3, 7.5 all ICE when compiling the following testcase reduced from libgomp/testsuite/libgomp.c++/udr-21.C w/ -O1 -fopenmp -fno-var-tracking-assignments -g: struct A { typedef int T; #pragma omp declare reduction (y : T : [&omp_out, &omp_in]() { omp_out += omp_in; return 0; }()) initializer (omp_priv = [omp_orig]() { return omp_orig; }()) static void foo (); }; void A::foo () { int r = 0, s = 0; #pragma omp parallel for reduction (y : r, s) for (int i = 0; i < 1; i++) { } } % g++-10.0.0-alpha20191201 -O1 -fopenmp -fno-var-tracking-assignments -g -c k1pjvw8c.C during GIMPLE pass: einline k1pjvw8c.C: In function '_ZN1A3fooEv._omp_fn.0': k1pjvw8c.C:4:157: internal compiler error: in dwarf2out_abstract_function, at dwarf2out.c:22659 4 | : [&omp_out, &omp_in]() { omp_out += omp_in; return 0; }()) initializer (omp_priv = [omp_orig]() { return omp_orig; }()) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~ 0xb846e7 dwarf2out_abstract_function /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:22659 0xfbd65e expand_call_inline /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/tree-inline.c:5182 0xfbe56c gimple_expand_calls_inline /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/tree-inline.c:5214 0xfbe56c optimize_inline_calls(tree_node*) /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/tree-inline.c:5356 0x17d7ec6 early_inliner(function*) /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/ipa-inline.c:2974 Omitting -O1 yields the following ICE instead: % g++-10.0.0-alpha20191201 -fopenmp -fno-var-tracking-assignments -g -c k1pjvw8c.C during RTL pass: final k1pjvw8c.C: In lambda function: k1pjvw8c.C:4:95: internal compiler error: in force_type_die, at dwarf2out.c:26224 4 | #pragma omp declare reduction (y : T : [&omp_out, &omp_in]() { omp_out += omp_in; return 0; }()) initializer (omp_priv = [omp_orig]() { return omp_orig; }()) | ^ 0x6ad480 force_type_die /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:26224 0xb9ea99 force_type_die /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:26218 0xb9ea99 get_context_die /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:26138 0xb9ea99 get_context_die /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:26130 0xb9ea99 force_decl_die /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:26157 0xb955dd gen_subprogram_die /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:22914 0xb973c3 gen_decl_die /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:26453 0xb98964 dwarf2out_decl /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:27017 0xb9929b dwarf2out_function_decl /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/dwarf2out.c:27032 0xc167fc rest_of_handle_final /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/final.c:4694 0xc167fc execute /var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191201/work/gcc-10-20191201/gcc/final.c:4736
Confirmed, started with Richi's r240578.
I'll eventually look into it.
So we're inlining A::omp declare reduction y~i(A::T&)::<lambda()>::operator() (const struct ._anon_1 * const __closure) which has no abstract origin. For the -fno-var-tracking-assignments case we are pruning the early DIE of the function as unused as part of prune_unused_types_prune while we don't when VTA is enabled. That's because: /* For -fvar-tracking-assignments, also set the mark on nodes that could be referenced by DW_TAG_call_site DW_AT_call_origin (i.e. direct call callees). */ cgraph_node *cnode; FOR_EACH_FUNCTION (cnode) if (cnode->referred_to_p (false)) { dw_die_ref die = lookup_decl_die (cnode->decl); if (die == NULL || die->die_mark) continue; for (cgraph_edge *e = cnode->callers; e; e = e->next_caller) if (e->caller != cnode && opt_for_fn (e->caller->decl, flag_var_tracking_assignments)) { prune_unused_types_mark (die, 1); break; } } I'm not sure why this code shouldn't apply to DW_TAG_inlined_subroutine which is needed independently of -fvar-tracking-assignments ...
(In reply to Richard Biener from comment #3) > So we're inlining A::omp declare reduction > y~i(A::T&)::<lambda()>::operator() (const struct ._anon_1 * const __closure) > which has no abstract origin. > > For the -fno-var-tracking-assignments case we are pruning the early DIE of > the > function as unused as part of prune_unused_types_prune while we don't when > VTA is enabled. That's because: > > /* For -fvar-tracking-assignments, also set the mark on nodes that could be > referenced by DW_TAG_call_site DW_AT_call_origin (i.e. direct call > callees). */ > cgraph_node *cnode; > FOR_EACH_FUNCTION (cnode) > if (cnode->referred_to_p (false)) > { > dw_die_ref die = lookup_decl_die (cnode->decl); > if (die == NULL || die->die_mark) > continue; > for (cgraph_edge *e = cnode->callers; e; e = e->next_caller) > if (e->caller != cnode > && opt_for_fn (e->caller->decl, flag_var_tracking_assignments)) > { > prune_unused_types_mark (die, 1); > break; > } > } > > I'm not sure why this code shouldn't apply to DW_TAG_inlined_subroutine > which is needed independently of -fvar-tracking-assignments ... I think the reason for the -fvar-tracking-assignments check is, as the comment says, to avoid pruning info that the call site info will need, and the call site info is only emitted if -fvar-tracking-assignments. DW_TAG_call_site is only emitted for the calls that remain as calls in the IL till the end, so if something is inlined, that isn't a call. we do not want
Fixed on trunk sofar.
The master branch has been updated by Richard Guenther <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:991b91497fd50f6e70e5f2c0cfa96e1b74157bdc commit r10-6087-g991b91497fd50f6e70e5f2c0cfa96e1b74157bdc Author: Richard Biener <rguenther@suse.de> Date: Mon Jan 20 10:36:09 2020 +0100 debug/92763 keep DIEs that might be used in DW_TAG_inlined_subroutine We were pruning type-local subroutine DIEs if their context is unused despite us later needing those DIEs as abstract origins for inlines. The patch makes code already present for -fvar-tracking-assignments unconditional. 2020-01-20 Richard Biener <rguenther@suse.de> PR debug/92763 * dwarf2out.c (prune_unused_types): Unconditionally mark called function DIEs. * g++.dg/debug/pr92763.C: New testcase.
The master branch has been updated by Christophe Lyon <clyon@gcc.gnu.org>: https://gcc.gnu.org/g:ad8e2415d6e2dc7c6f1206e78d48f999ff6b0bc4 commit r10-6199-gad8e2415d6e2dc7c6f1206e78d48f999ff6b0bc4 Author: Christophe Lyon <christophe.lyon@linaro.org> Date: Fri Jan 24 09:07:58 2020 +0000 debug/92763 Fix testcase to require fopenmp The testcase fails to link on targets without -pthread which is implied by -fopenmp. Use dg-require-effective-target fopenmp to avoid this problem. 2020-01-24 Christophe Lyon <christophe.lyon@linaro.org> PR debug/92763 * g++.dg/debug/pr92763.C: Require fopenmp.
The releases/gcc-9 branch has been updated by Richard Guenther <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:794bb8c2f5d328d9d4cfa55efd41cdd420ebb13a commit r9-8232-g794bb8c2f5d328d9d4cfa55efd41cdd420ebb13a Author: Richard Biener <rguenther@suse.de> Date: Fri Feb 14 09:17:57 2020 +0100 debug/92763 keep DIEs that might be used in DW_TAG_inlined_subroutine We were pruning type-local subroutine DIEs if their context is unused despite us later needing those DIEs as abstract origins for inlines. The patch makes code already present for -fvar-tracking-assignments unconditional. 2020-02-14 Richard Biener <rguenther@suse.de> Backport from mainline 2020-01-20 Richard Biener <rguenther@suse.de> PR debug/92763 * dwarf2out.c (prune_unused_types): Unconditionally mark called function DIEs. * g++.dg/debug/pr92763.C: New testcase.
Fixed.
The releases/gcc-8 branch has been updated by Richard Guenther <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:0727fae83508fe21bd510ae380d6a361ac632680 commit r8-10031-g0727fae83508fe21bd510ae380d6a361ac632680 Author: Richard Biener <rguenther@suse.de> Date: Fri Feb 14 09:17:57 2020 +0100 debug/92763 keep DIEs that might be used in DW_TAG_inlined_subroutine We were pruning type-local subroutine DIEs if their context is unused despite us later needing those DIEs as abstract origins for inlines. The patch makes code already present for -fvar-tracking-assignments unconditional. 2020-02-14 Richard Biener <rguenther@suse.de> Backport from mainline 2020-01-20 Richard Biener <rguenther@suse.de> PR debug/92763 * dwarf2out.c (prune_unused_types): Unconditionally mark called function DIEs. * g++.dg/debug/pr92763.C: New testcase.