espressif / crosstool-NG

crosstool-NG with support for Xtensa
Other
115 stars 61 forks source link

Bizarre GCC ICE in IRA RTL pass on 13.2.0 (20230928) and 13.2.0 (20240530) with -Os/Og/O1/O2/O3 #59

Open MyriadBugs opened 2 weeks ago

MyriadBugs commented 2 weeks ago

The following simplified example causes an ICE in GCC for the versions listed in title, but not 12.2.0 (20230208).

Seems like there are shenanigans when GCC tries to optimize the value structure then build the SLL/SLLI and MOVI/MOVI.N instruction assignments. I am not a compiler dev so out of my league here.

Reproduction is fairly simple, compile with -Os to crash, compile with -Os -fno-tree-sra and/or -Os -fno-expensive-optimizations to workaround.

Simplified Reproduction

#include <cstdint>
struct command
{
    uint8_t address;
    uint8_t data;
};

//triggers ICE in elimination_costs_in_insn, at reload1.cc:3539 unless compiled with -fno-expensive-optimizations
command triggersICE()
{
    return command{0x01, 0b1000};
};

//Nothing below this line is necessary to reproduce, just for clarity on what does/does not trigger the bug.
command triggersICEB()
{
    return command{0xff, 0xf7};
};

command doesNotTriggerICEA()
{
    return command{0x00, 0b1000};
};
command doesNotTriggerICEB()
{
    return command{0xff, 0b100};
};
command doesNotTriggerICEC()
{
    return command{0x01, 0b111};
};
command doesNotTriggerICED()
{
    return command{0xff, 0xf8};
};

GCC Error

during RTL pass: ira
<source>: In function 'command triggersICE()':
<source>:12:1: internal compiler error: in elimination_costs_in_insn, at reload1.cc:3539
   12 | };
      | ^
0x164b716 internal_error(char const*, ...)
    ???:0
0x66c633 fancy_abort(char const*, int, char const*)
    ???:0
0xd21894 calculate_elim_costs_all_insns()
    ???:0
0xbcde8c ira_costs()
    ???:0
0xbc75b4 ira_build()
    ???:0

Failing IRA Pass Emergency Dump


EMERGENCY DUMP:
triggersICE
Dataflow summary:
;;  fully invalidated by EH      0 [a0] 8 [a8] 9 [a9] 10 [a10] 11 [a11] 12 [a12] 13 [a13] 14 [a14] 15 [a15] 18 [b0] 19 [f0] 20 [f1] 21 [f2] 22 [f3] 23 [f4] 24 [f5] 25 [f6] 26 [f7] 27 [f8] 28 [f9] 29 [f10] 30 [f11] 31 [f12] 32 [f13] 33 [f14] 34 [f15] 35 [acc]
;;  hardware regs used   1 [sp] 16 [fp] 17 [argp]
;;  regular block artificial uses    1 [sp] 7 [a7] 16 [fp] 17 [argp]
;;  eh block artificial uses     1 [sp] 7 [a7] 16 [fp] 17 [argp]
;;  entry block defs     0 [a0] 1 [sp] 2 [a2] 3 [a3] 4 [a4] 5 [a5] 6 [a6] 7 [a7] 16 [fp] 17 [argp]
;;  exit block uses      1 [sp] 2 [a2] 7 [a7] 16 [fp]
;;  regs ever live   2 [a2]
;;  ref usage   r0={1d} r1={1d,2u} r2={2d,2u} r3={1d} r4={1d} r5={1d} r6={1d} r7={1d,2u} r16={1d,2u} r17={1d,1u} 
;;    total ref usage 20{11d,9u,0e} in 3{3 regular + 0 call} insns.
(note 1 0 3 NOTE_INSN_DELETED)
;; basic block 2, loop depth 0, count 1073741824 (estimated locally), maybe hot
;;  prev block 0, next block 1, flags: (REACHABLE, RTL)
;;  pred:       ENTRY [always]  count:1073741824 (estimated locally) (FALLTHRU)
;; bb 2 artificial_defs: { }
;; bb 2 artificial_uses: { u-1(1){ }u-1(7){ }u-1(16){ }u-1(17){ }}
;; lr  in    1 [sp] 7 [a7] 16 [fp] 17 [argp]
;; lr  use   1 [sp] 7 [a7] 16 [fp] 17 [argp]
;; lr  def   2 [a2]
(note 3 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(note 2 3 5 2 NOTE_INSN_FUNCTION_BEG)
(debug_insn 5 2 11 2 (debug_marker) "/example.cpp":11:2 -1
     (nil))
(note 11 5 17 2 NOTE_INSN_DELETED)
(note 17 11 19 2 NOTE_INSN_DELETED)
(note 19 17 22 2 NOTE_INSN_DELETED)
(note 22 19 29 2 NOTE_INSN_DELETED)
(insn 29 22 30 2 (set (reg/i:HI 2 a2)
        (const_int 2049 [0x801])) "/example.cpp":12:1 -1
     (expr_list:REG_EQUAL (const_int 2049 [0x801])
        (nil)))
(insn 30 29 0 2 (use (reg/i:HI 2 a2)) "/example.cpp":12:1 -1
     (nil))
;;  succ:       EXIT [always]  count:1073741824 (estimated locally) (FALLTHRU)
;; lr  out   1 [sp] 2 [a2] 7 [a7] 16 [fp] 17 [argp]
Lapshin commented 2 days ago

@MyriadBugs , thank you for your report,

I tested it with GCC 14, and no issues were found. The new release will come soon