https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68618
Bug ID: 68618 Summary: interrupt fails on ICE in some call cases with miamcu with -O2/3 Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: vaalfreja at gmail dot com Target Milestone: --- Reproduce: bash-4.2$ cat ../i2.c struct interrupt_frame; void (*foo1[1])(int a, int b); void foo2(int c) { foo1[c](1,2); } static __attribute__((interrupt)) void my_isr(struct interrupt_frame *frame) { int c; foo2(c); } int main() { } bash-4.2$ ./../gcc_trunk_64bit_old_interrupt/install/bin/gcc -m32 -miamcu -O3 -DU ../i2.c ../i2.c: In function ‘foo2’: ../i2.c:8:1: error: unable to find a register to spill } ^ ../i2.c:8:1: error: this is the insn: (call_insn/j 10 19 11 2 (call (mem:QI (reg/f:SI 91 [90]) [0 *_3 S1 A8]) (const_int 0 [0])) ../i2.c:7 662 {*sibcall} (expr_list:REG_DEAD (reg/f:SI 91 [90]) (expr_list:REG_DEAD (reg:SI 1 dx) (expr_list:REG_DEAD (reg:SI 0 ax) (expr_list:REG_CALL_DECL (nil) (nil))))) (expr_list:SI (use (reg:SI 0 ax)) (expr_list:SI (use (reg:SI 1 dx)) (nil)))) ../i2.c:8:1: internal compiler error: in assign_by_spills, at lra-assigns.c:1431 0xa6f4a8 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*) .././../TRUNK/gcc6/gcc/rtl-error.c:109 0x970019 assign_by_spills .././../TRUNK/gcc6/gcc/lra-assigns.c:1431 0x970a53 lra_assign() .././../TRUNK/gcc6/gcc/lra-assigns.c:1606 0x96c459 lra(_IO_FILE*) .././../TRUNK/gcc6/gcc/lra.c:2344 0x922919 do_reload .././../TRUNK/gcc6/gcc/ira.c:5392 0x922919 execute .././../TRUNK/gcc6/gcc/ira.c:5563 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <http://gcc.gnu.org/bugs.html> for instructions. This bug can be fixed with: diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cb6f8f4..b1523e0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5339,8 +5339,8 @@ ix86_set_current_function (tree fndecl) reinit_regs (); /* AX register is only preserved if there are no caller-saved registers. */ - else if (cfun->machine->no_caller_saved_registers - == call_used_regs[AX_REG]) + else if ((cfun->machine->no_caller_saved_registers + == call_used_regs[AX_REG]) || TARGET_IAMCU) reinit_regs (); } However, unconditional calling of reinit_regs is bad.