struct A { unsigned long a; }; struct B { unsigned short b, c, d; }; struct B bar (unsigned long); char * foo (char *a, struct A *x) { struct B b = bar (x->a); unsigned char c; unsigned short d; a[3] = ((unsigned char) (b.b % 10) + 48); d = b.b / 10; a[2] = ((unsigned char) (d % 10) + 48); d = d / 10; a[1] = ((unsigned char) (d % 10) + 48); a[0] = ((unsigned char) ((d / 10) % 10) + 48); a[4] = 46; c = (unsigned char) b.c; a[6] = (c % 10 + 48); a[5] = ((c / 10) % 10 + 48); a[7] = 46; c = b.d; a[9] = (c % 10 + 48); a[8] = ((c / 10) % 10 + 48); return a + 10; }
ICEs with -O2 on x86_64-linux: /tmp/tt.c: In function 'foo': /tmp/tt.c:25:1: error: unable to find a register to spill in class 'AREG' /tmp/tt.c:25:1: error: this is the insn: (insn 82 81 83 2 /tmp/tt.c:18 (parallel [ (set (reg:HI 1 dx [170]) (mult:HI (zero_extend:HI (reg/v:QI 4 si [orig:82 c ] [82])) (zero_extend:HI (reg:QI 2 cx [169])))) (clobber (reg:CC 17 flags)) ]) 337 {*umulqihi3_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_EQUAL (mult:HI (zero_extend:HI (reg/v:QI 4 si [orig:82 c ] [82])) (const_int 205 [0xcd])) (nil)))) /tmp/tt.c:25:1: internal compiler error: in spill_failure, at reload1.c:2151 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. Worked in 3.4/4.0, ICEs from 4.1 onwards up to current trunk. The problem seems to be in the combiner, it extremely lengthens the lifetime of hard register (%rax): in *.dce: ... (insn 13 12 14 2 /tmp/tt.c:7 (parallel [ (set (reg:DI 113) (lshiftrt:DI (reg:DI 0 ax) (const_int 32 [0x20]))) (clobber (reg:CC 17 flags)) ]) 549 {*lshrdi3_1_rex64} (expr_list:REG_DEAD (reg:DI 0 ax) (expr_list:REG_UNUSED (reg:CC 17 flags) (nil)))) (insn 14 13 16 2 /tmp/tt.c:7 (set (reg:HI 114) (subreg:HI (reg:DI 113) 0)) 53 {*movhi_1} (expr_list:REG_DEAD (reg:DI 113) (nil))) ... 49 insns ... (insn 82 81 83 2 /tmp/tt.c:18 (parallel [ (set (reg:HI 168) (mult:HI (zero_extend:HI (reg/v:QI 82 [ c ])) (zero_extend:HI (reg:QI 169)))) (clobber (reg:CC 17 flags)) ]) 337 {*umulqihi3_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_EQUAL (mult:HI (zero_extend:HI (reg/v:QI 82 [ c ])) (const_int 205 [0xcd])) (nil)))) ... 18 insns ... (insn 108 107 110 2 /tmp/tt.c:21 (set (reg/v:QI 93 [ c ]) (subreg:QI (reg:HI 114) 0)) 62 {*movqi_1} (expr_list:REG_DEAD (reg:HI 114) (nil))) ... in *.combine: ... (note 13 12 14 2 NOTE_INSN_DELETED) (note 14 13 16 2 NOTE_INSN_DELETED) ... many insns ... (insn 82 81 83 2 /tmp/tt.c:18 (parallel [ (set (reg:HI 168) (mult:HI (zero_extend:HI (reg/v:QI 82 [ c ])) (zero_extend:HI (reg:QI 169)))) (clobber (reg:CC 17 flags)) ]) 337 {*umulqihi3_1} (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_EQUAL (mult:HI (zero_extend:HI (reg/v:QI 82 [ c ])) (const_int 205 [0xcd])) (nil)))) ... many insns ... (insn 108 107 110 2 /tmp/tt.c:21 (parallel [ (set (subreg:DI (reg/v:QI 93 [ c ]) 0) (lshiftrt:DI (reg:DI 0 ax) (const_int 32 [0x20]))) (clobber (reg:CC 17 flags)) ]) 549 {*lshrdi3_1_rex64} (expr_list:REG_UNUSED (reg:CC 17 flags) (expr_list:REG_DEAD (reg:DI 0 ax) (nil)))) ... -- Summary: [4.3/4.4/4.5 Regression] Reload ICE due to combiner extending life time of a hard register Product: gcc Version: 4.4.1 Status: UNCONFIRMED Keywords: ice-on-valid-code Severity: normal Priority: P3 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jakub at gcc dot gnu dot org GCC target triplet: x86_64-linux http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41646