Bug 119613 - [15 regression] ICE when building protobuf-29.4 with -O0 (purge_dead_edges, at cfgrtl.cc:3356)
Summary: [15 regression] ICE when building protobuf-29.4 with -O0 (purge_dead_edges, a...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 15.0
: P3 normal
Target Milestone: 15.0
Assignee: Jakub Jelinek
URL:
Keywords: EH, ice-on-valid-code, tail-call
Depends on:
Blocks:
 
Reported: 2025-04-03 19:15 UTC by Sam James
Modified: 2026-01-30 12:01 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2025-04-03 00:00:00


Attachments
generated_message_tctable_lite.cc.ii.xz (504.05 KB, application/x-xz)
2025-04-03 19:15 UTC, Sam James
Details
Reduced testcase (161 bytes, text/plain)
2025-04-03 21:28 UTC, Andrew Pinski
Details
Add back inline not to get warning about always_inline (163 bytes, text/plain)
2025-04-03 21:30 UTC, Andrew Pinski
Details
gcc15-pr119613.patch (918 bytes, patch)
2025-04-04 07:21 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sam James 2025-04-03 19:15:07 UTC
I have another bug coming (with explicit musttail error), but hit this along the way. I'll reduce this one when I have the other done.

```
$ g++ -c generated_message_tctable_lite.cc.ii
during RTL pass: expand
/var/tmp/portage/dev-libs/protobuf-29.4/work/protobuf-29.4/src/google/protobuf/generated_message_tctable_lite.cc: In static member function ‘static const char* google::protobuf::internal::TcParser::MiniParse(google::protobuf::MessageLite*, const char*, google::protobuf::internal::ParseContext*, google::protobuf::internal::TcFieldData, const google::protobuf::internal::TcParseTableBase*, uint64_t)’:
/var/tmp/portage/dev-libs/protobuf-29.4/work/protobuf-29.4/src/google/protobuf/generated_message_tctable_lite.cc:324:1: internal compiler error: in purge_dead_edges, at cfgrtl.cc:3356
  324 | }
      | ^
0x5bc08a159a0c internal_error(char const*, ...)
        /usr/src/debug/sys-devel/gcc-15.0.9999/gcc-15.0.9999/gcc/diagnostic-global-context.cc:517
0x5bc08a159ba7 fancy_abort(char const*, int, char const*)
        /usr/src/debug/sys-devel/gcc-15.0.9999/gcc-15.0.9999/gcc/diagnostic.cc:1749
0x5bc088ca0ac9 purge_dead_edges(basic_block_def*)
        /usr/src/debug/sys-devel/gcc-15.0.9999/gcc-15.0.9999/gcc/cfgrtl.cc:3356
0x5bc08a793200 find_bb_boundaries
        /usr/src/debug/sys-devel/gcc-15.0.9999/gcc-15.0.9999/gcc/cfgbuild.cc:635
0x5bc08a7922ab find_many_sub_basic_blocks(simple_bitmap_def*)
        /usr/src/debug/sys-devel/gcc-15.0.9999/gcc-15.0.9999/gcc/cfgbuild.cc:755
0x5bc08a69a391 execute
        /usr/src/debug/sys-devel/gcc-15.0.9999/gcc-15.0.9999/gcc/cfgexpand.cc:7278
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <https://bugs.gentoo.org/> for instructions.
```

---

```

Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-pc-linux-gnu/15/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-pc-linux-gnu
Configured with: /var/tmp/portage/sys-devel/gcc-15.0.9999/work/gcc-15.0.9999/configure --host=x86_64-pc-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --bindir=/usr/x86_64-pc-linux-gnu/gcc-bin/15 --includedir=/usr/lib/gcc/x86_64-pc-linux-gnu/15/include --datadir=/usr/share/gcc-data/x86_64-pc-linux-gnu/15 --mandir=/usr/share/gcc-data/x86_64-pc-linux-gnu/15/man --infodir=/usr/share/gcc-data/x86_64-pc-linux-gnu/15/info --with-gxx-include-dir=/usr/lib/gcc/x86_64-pc-linux-gnu/15/include/g++-v15 --disable-silent-rules --disable-dependency-tracking --with-python-dir=/share/gcc-data/x86_64-pc-linux-gnu/15/python --enable-libphobos --enable-objc-gc --enable-languages=c,c++,d,go,objc,obj-c++,fortran,ada,cobol,m2,rust --enable-obsolete --enable-secureplt --disable-werror --with-system-zlib --enable-nls --without-included-gettext --disable-libunwind-exceptions --enable-checking=yes,extra,rtl --with-bugurl=https://bugs.gentoo.org/ --with-pkgversion='Gentoo Hardened 15.0.9999 p, commit 43e87541519c3e496094d7febd6b772ce0fb33b9' --with-gcc-major-version-only --enable-libstdcxx-time --enable-lto --disable-libstdcxx-pch --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-multilib --with-multilib-list=m32,m64 --disable-fixed-point --enable-targets=all --enable-offload-defaulted --enable-offload-targets=nvptx-none --enable-libgomp --disable-libssp --enable-libada --disable-cet --disable-systemtap --enable-valgrind-annotations --disable-vtable-verify --disable-libvtv --with-zstd --with-isl --disable-isl-version-check --enable-default-pie --enable-host-pie --enable-host-bind-now --enable-default-ssp --disable-fixincludes --with-gxx-libcxx-include-dir=/usr/include/c++/v1 --with-build-config='bootstrap-O3 bootstrap-lto'
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 15.0.1 20250403 (experimental) 92ca72b41a74aef53978cadbda33dd38b69d3ed3 (Gentoo Hardened 15.0.9999 p, commit 43e87541519c3e496094d7febd6b772ce0fb33b9)
```
Comment 1 Sam James 2025-04-03 19:15:25 UTC
Created attachment 60976 [details]
generated_message_tctable_lite.cc.ii.xz
Comment 2 Andrew Pinski 2025-04-03 19:24:27 UTC
;;   basic block 36, loop depth 0
;;    pred:       35
  tag.31_133 = tag;
  _134 = (long unsigned int) tag.31_133;
  data.D.190490.data = _134;
  _135 = table_15->fallback;
  _136 = _135 (msg_12, ptr_123, ctx_14, data, table_15, hasbits_16); [tail call] [must tail call]
;;    succ:       37
;;                43

...
;;   basic block 43, loop depth 0
;;    pred:       34
;;                36
;;                39
;;                31
<L14>:
  D.340774 ={v} {CLOBBER(eos)};
  tag ={v} {CLOBBER(eos)};
  _175 = __builtin_eh_pointer (1);
  __builtin_unwind_resume (_175);
;;    succ:


The ICE I think might be due to that musttail ...
Comment 3 Andrew Pinski 2025-04-03 21:28:34 UTC
Created attachment 60978 [details]
Reduced testcase
Comment 4 Andrew Pinski 2025-04-03 21:29:12 UTC
Confirmed. My reduced testcase still works with clang too (had to add back the b argument to j to get that working.
Comment 5 Andrew Pinski 2025-04-03 21:30:11 UTC
Created attachment 60979 [details]
Add back inline not to get warning about always_inline
Comment 6 Andrew Pinski 2025-04-03 21:32:34 UTC
;; _9 = d (D.2936); [tail call] [must tail call]

(call_insn/j 14 13 15 3 (set (reg:DI 0 ax)
        (call (mem:QI (symbol_ref:DI ("_Z1d1b") [flags 0x41]  <function_decl 0x7b1ef09d9100 d>) [0 _Z1d1bD.2875 S1 A8])
            (const_int 0 [0]))) "/app/example.cpp":12:31 -1
     (expr_list:REG_EH_REGION (const_int 2 [0x2])
        (nil))
    (nil))

Maybe the REG_EH_REGION  here?
Comment 7 Jakub Jelinek 2025-04-04 07:21:06 UTC
Created attachment 60992 [details]
gcc15-pr119613.patch

Untested fix.
Comment 8 GCC Commits 2025-04-04 18:53:50 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:77e0c0df0907657a7d72bbba9e6329d93ec65edb

commit r15-9207-g77e0c0df0907657a7d72bbba9e6329d93ec65edb
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Apr 4 20:51:50 2025 +0200

    cfgrtl: Remove REG_EH_REGION notes from tail calls [PR119613]
    
    In PR119491 r15-9154 I've allowed some useless EH regions for musttail
    calls (if there are no non-debug/clobber stmts before resx which resumes
    external throwing).
    Now, for -O1+ (but not -O0/-Og) there is a cleanup_eh pass after it
    which should optimize that way.
    The following testcase ICEs at -O0 though, the cleanup_eh in that case
    is before the musttail pass and dunno why it didn't actually optimize
    it away.
    
    The following patch catches that during expansion and just removes the note,
    which causes EH cleanups to do the rest.  A tail call, even when it throws,
    will not throw while the musttail caller's frame is still on the stack,
    will throw after that and so REG_EH_REGION for it is irrelevant (like it
    would be never set before the r15-9154 changes).
    
    2025-04-04  Jakub Jelinek  <jakub@redhat.com>
    
            PR middle-end/119613
            * cfgrtl.cc (purge_dead_edges): Remove REG_EH_REGION notes from
            tail calls.
    
            * g++.dg/opt/pr119613.C: New test.
Comment 9 Jakub Jelinek 2025-04-04 19:01:50 UTC
Should be fixed now.
Comment 10 Martin Nyhus 2026-01-30 12:01:44 UTC
I came across the patch for this bug while looking into an ICE [0] with the AFL instrumentation plugin. In that case the same assert fails due to an EH block, but instead of musttail the cause appears to be a combination of coroutines and instrumentation that was inserted by the fuzzer plugin pass. The patch for this bug also fixes that issue, so I was wondering if this change (commit 77e0c0df09) could be backported to the gcc-14 branch? It applies cleanly, but I'm not familiar enough with the GCC codebase to know if there are other downsides.

[0] https://github.com/AFLplusplus/AFLplusplus/issues/2684