Bug 84964 - [9/10/11/12 Regression] ICE in expand_call, at calls.c:4540
Summary: [9/10/11/12 Regression] ICE in expand_call, at calls.c:4540
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0.1
: P4 normal
Target Milestone: 9.5
Assignee: Roger Sayle
URL:
Keywords: error-recovery, ice-on-invalid-code
: 100536 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-03-19 19:43 UTC by Vegard Nossum
Modified: 2022-05-06 22:49 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 7.3.0
Known to fail: 8.0
Last reconfirmed: 2018-03-20 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vegard Nossum 2018-03-19 19:43:49 UTC
Input:

struct a {
  short b : -1ULL;
};
void c(...) { c(a()); }

Output:

$ cc1plus 
<stdin>:2:14: warning: width of 'a::b' exceeds its type
 void c(...)
Analyzing compilation unit
Performing interprocedural optimizations
 <*free_lang_data> <visibility> <build_ssa_passes> <opt_local_passes> <targetclone> <free-fnsummary> <whole-program> <fnsummary> <inline> <free-fnsummary> <single-use> <comdats>Assembling functions:
 <materialize-all-clones> <simdclone> void c(...)
<stdin>: In function 'void c(...)':
<stdin>:4:16: sorry, unimplemented: passing too large argument on stack
during RTL pass: expand
<stdin>:4:16: internal compiler error: in expand_call, at calls.c:4540
0x17b719f expand_call(tree_node*, rtx_def*, int)
        /home/vegard/git/gcc/gcc/calls.c:4537
0x1e78955 expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool)
        /home/vegard/git/gcc/gcc/expr.c:11002
0x181e6d4 expand_expr
        /home/vegard/git/gcc/gcc/expr.h:276
0x181e6d4 expand_call_stmt
        /home/vegard/git/gcc/gcc/cfgexpand.c:2690
0x181e6d4 expand_gimple_stmt_1
        /home/vegard/git/gcc/gcc/cfgexpand.c:3624
0x181e6d4 expand_gimple_stmt
        /home/vegard/git/gcc/gcc/cfgexpand.c:3790
0x1824c48 expand_gimple_basic_block
        /home/vegard/git/gcc/gcc/cfgexpand.c:5819
0x18443d7 execute
        /home/vegard/git/gcc/gcc/cfgexpand.c:6425
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.

Version:

GNU C++14 (GCC) version 8.0.1 20180306 (experimental) (x86_64-pc-linux-gnu)
Comment 1 Martin Liška 2018-03-20 08:30:40 UTC
Confirmed, started with r255921.

Before that:

pr84964.cpp:3:14: warning: width of ‘a::b’ exceeds its type
   short b : -1ULL;
              ^~~~
pr84964.cpp: In function ‘void c(...)’:
pr84964.cpp:5:16: sorry, unimplemented: passing too large argument on stack
 void c(...) { c(a()); }
               ~^~~~~
Comment 2 Richard Biener 2018-03-20 09:03:03 UTC
I think sorry () triggers error-recovery
Comment 3 Richard Sandiford 2018-03-20 09:17:43 UTC
Mine
Comment 4 Richard Sandiford 2018-03-20 10:47:46 UTC
I think the difference is that pending_stack_adjust and stack_pointer_delta used to be int-based rather than HWI-based, so the size of the stack allocation was previously truncated to from 1<<61 to 0.
Comment 5 Paolo Carlini 2018-03-28 09:50:45 UTC
Richard, you are on it, right?
Comment 6 Jakub Jelinek 2018-05-02 10:10:53 UTC
GCC 8.1 has been released.
Comment 7 Jakub Jelinek 2018-07-26 11:23:25 UTC
GCC 8.2 has been released.
Comment 8 Jakub Jelinek 2019-02-22 15:25:38 UTC
GCC 8.3 has been released.
Comment 9 Jakub Jelinek 2020-03-04 09:46:37 UTC
GCC 8.4.0 has been released, adjusting target milestone.
Comment 10 Jakub Jelinek 2021-05-14 09:50:15 UTC
GCC 8 branch is being closed.
Comment 11 Richard Biener 2021-06-01 08:10:52 UTC
GCC 9.4 is being released, retargeting bugs to GCC 9.5.
Comment 12 Andrew Pinski 2021-09-23 01:43:07 UTC
A little history here:

4.1.2 accepted the code without an ICE.

4.4-4.7 had an ICE:
<source>:2:8: internal compiler error: in tree_low_cst, at tree.h:4435

4.8 accepted the code without an ICE.

4.9-7 had the sorry:
<source>:5:16: sorry, unimplemented: passing too large argument on stack

8+ had the ICE after the sorry:
<source>:5:16: internal compiler error: in expand_call, at calls.c:3919
Comment 13 Andrew Pinski 2021-09-23 01:46:47 UTC
The sorry was added by r0-126979 (aka PR 56344).
Comment 14 Roger Sayle 2022-02-28 08:03:03 UTC
Patch proposed.
https://gcc.gnu.org/pipermail/gcc-patches/2022-February/590961.html
Comment 15 Roger Sayle 2022-02-28 08:07:43 UTC
*** Bug 100536 has been marked as a duplicate of this bug. ***
Comment 16 GCC Commits 2022-03-10 23:50:11 UTC
The master branch has been updated by Roger Sayle <sayle@gcc.gnu.org>:

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

commit r12-7607-ga717376e99fb33ba3b06bd8122e884f4b63a60c9
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Thu Mar 10 23:49:15 2022 +0000

    PR c++/84964: Middle-end patch to expand_call for ICE after sorry.
    
    This patch resolves PR c++/84969 which is an ICE in the middle-end after
    emitting a "sorry, unimplemented" message, and is a regression from
    earlier releases of GCC.  This issue is that after encountering a
    function call requiring an unreasonable amount of stack space, the
    code continues and falls foul of an assert checking that stack pointer
    has been correctly updated.  The fix is to (locally) consider aborted
    function calls as "no return", which skips this downstream sanity check.
    
    2022-03-10  Roger Sayle  <roger@nextmovesoftware.com>
    
    gcc/ChangeLog
            PR c++/84964
            * calls.cc (expand_call): Ignore stack adjustments after sorry.
    
    gcc/testsuite/ChangeLog
            PR c++/84964
            * g++.dg/other/pr84964.C: New test case.
Comment 17 GCC Commits 2022-03-11 17:39:00 UTC
The master branch has been updated by Roger Sayle <sayle@gcc.gnu.org>:

https://gcc.gnu.org/g:098c538ae8c0c5e281d9191a6b54ffe38b624ef3

commit r12-7614-g098c538ae8c0c5e281d9191a6b54ffe38b624ef3
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Fri Mar 11 17:35:21 2022 +0000

    [Committed] Update g++.dg/other/pr84964.C for ia32 (and similar) targets.
    
    The "sorry, unimplemented" message in the new g++.dg/other/pr84964.C is
    apparently dependent upon whether the target passes multi-gigabyte
    arguments on the stack.  This tweaks the testcase to just confirm that
    it no longer ICEs, not the specific set of warnings/errors triggered.
    
    2022-03-11  Roger Sayle  <roger@nextmovesoftware.com>
    
    gcc/testsuite/ChangeLog
            PR c++/84964
            * g++.dg/other/pr84964.C: Tweak test to check for the ICE, not for
            the (target-dependent) sorry.
Comment 18 GCC Commits 2022-03-22 07:40:18 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:6adbb51eaa85f5bfed1ee06327daca306d48986d

commit r12-7749-g6adbb51eaa85f5bfed1ee06327daca306d48986d
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Mar 22 08:39:40 2022 +0100

    calls: Fix error recovery after sorry differently [PR104989]
    
    On Mon, Feb 28, 2022 at 07:52:56AM -0000, Roger Sayle wrote:
    > This patch resolves PR c++/84964 which is an ICE in the middle-end after
    > emitting a "sorry, unimplemented" message, and is a regression from
    > earlier releases of GCC.  This issue is that after encountering a
    > function call requiring an unreasonable amount of stack space, the
    > code continues and falls foul of an assert checking that stack pointer
    > has been correctly updated.  The fix is to (locally) consider aborted
    > function calls as "no return", which skips this downstream sanity check.
    
    As can be seen on PR104989, just setting ECF_NORETURN after sorry is quite
    risky and leads to other ICEs.  The problem is that ECF_NORETURN calls
    better should be at the end of basic blocks that don't have any fallthru
    successor edges, otherwise we can ICE later.
    
    This patch instead sets sibcall_failure if in pass == 0 (sibcall_failure
    means that the tail call sequence is not useful/not desirable and throws
    it away) and otherwise sets a new bool variable that will let us pass
    the assertion and also throws away the whole call sequence, I think that is
    best for error recovery.
    
    2022-03-22  Jakub Jelinek  <jakub@redhat.com>
    
            PR rtl-optimization/104989
            * calls.cc (expand_call): Don't set ECF_NORETURN in flags after
            sorry for passing too large argument, instead set sibcall_failure
            for pass == 0, or a new normal_failure flag otherwise.  If
            normal_failure is set, don't assert all stack has been deallocated
            at the end and throw away the whole insn sequence.
    
            * g++.dg/other/pr104989.C: New test.
Comment 19 Segher Boessenkool 2022-03-22 16:07:07 UTC
This now ICEs with a segfault on powerpc64-linux.
Comment 20 Segher Boessenkool 2022-03-22 16:08:13 UTC
FAIL: g++.dg/other/pr84964.C  -std=c++14 (internal compiler error: Aborted signal terminated program cc1plus)
Comment 21 Jakub Jelinek 2022-03-22 19:04:00 UTC
It did so even before my or Roger's patch.
As I wrote in PR105023, the problem is that the rs6000 backend decides to pass that huge (2 Exabytes long) argument partially in registers (reg:BLK 3 3) and partially on the stack, while on most other backends it is passed just on the stack and we sorry at that point instead of trying to overwrite compiler's memory.  (reg:BLK 3 3) looks just way too suspect to me, do we pass say 256 byte long homogenous structures that way too?
Comment 22 Segher Boessenkool 2022-03-22 22:28:23 UTC
(In reply to Jakub Jelinek from comment #21)
> It did so even before my or Roger's patch.

It was my first successful bootstrap in a few days, and I replied to this old PR
without looking everywhere else first.

> As I wrote in PR105023, the problem is that the rs6000 backend decides to
> pass that huge (2 Exabytes long) argument partially in registers (reg:BLK 3
> 3) and partially on the stack,

It isn't the backend that decides to do that.  The backend correctly does what
the ABI requires here: pass up to eight things in GPRs, and the rest in the
parameter save area (on the stack) (this is ignoring FPRs and the like, for
simplicity).

> while on most other backends it is passed
> just on the stack and we sorry at that point instead of trying to overwrite
> compiler's memory.  (reg:BLK 3 3) looks just way too suspect to me, do we
> pass say 256 byte long homogenous structures that way too?

reg:BLK is invalid always, :BLK is valid on memory only.
Comment 23 GCC Commits 2022-03-26 18:11:30 UTC
The master branch has been updated by Roger Sayle <sayle@gcc.gnu.org>:

https://gcc.gnu.org/g:41d1f11f5f693a2a06c65c9467a28dfeb02aed85

commit r12-7833-g41d1f11f5f693a2a06c65c9467a28dfeb02aed85
Author: Roger Sayle <roger@nextmovesoftware.com>
Date:   Sat Mar 26 08:10:27 2022 -1000

    PR middle-end/104885: Fix ICE with large stack frame on powerpc64.
    
    My recent testcase for PR c++/84964.C stress tests the middle-end by
    attempting to pass a UINT_MAX sized structure on the stack.  Although
    my fix to PR84964 avoids the ICE after sorry on x86_64 and similar
    targets, a related issue still exists on powerpc64 (and similar
    ACCUMULATE_OUTGOING_ARGS/ARGS_GROW_DOWNWARD targets) which don't
    issue a "sorry, unimplemented" message, but instead ICE elsewhere.
    
    After attempting several alternate fixes, the simplest solution is
    to just defensively check in mark_stack_region_used that the upper
    bound of the region lies within the allocated stack_usage_map
    array, which is of size highest_outgoing_arg_in_use.  When this isn't
    the case, the code now follows the same path as for variable sized
    regions, and uses stack_usage_watermark rather than a map.
    
    2022-03-26  Roger Sayle  <roger@nextmovesoftware.com>
    
    gcc/ChangeLog
            PR middle-end/104885
            * calls.cc (mark_stack_region_used): Check that the region
            is within the allocated size of stack_usage_map.
Comment 24 Roger Sayle 2022-04-14 11:35:47 UTC
This should now be fixed on mainline.