https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114184
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P2 Summary|ICE: in extract_insn, at |[12/13/14 Regression] ICE: |recog.cc:2812 |in extract_insn, at |(unrecognizable insn ) with |recog.cc:2812 |-Og -mavx512f and |(unrecognizable insn ) with |__builtin_memmove() |_Complex long double and |_BitInt(256) |vector VCE Target Milestone|--- |12.4 --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Seems unrelated to _BitInt. E.g. following testcase ICEs with -O2 -mavx2 since r14-4537-g70b5c6981fcdff246f90e57e91f3e1667eab2eb3 typedef unsigned char V __attribute__((vector_size (32))); _Complex long double foo (void) { _Complex long double d; *(V *)&d = (V) { 149, 136, 89, 42, 38, 240, 196, 194 }; return d; } and the same with -Og -mavx2 since r12-7240-g2801f23fb82a5ef51c8b460a500786797943e1e9 I don't see bugs in either of those commits. What I see happing is that expand_assignment, because the destination is complex, does 6211 emit_move_insn (XEXP (to_rtx, 0), 6212 read_complex_part (from_rtx, false)); 6213 emit_move_insn (XEXP (to_rtx, 1), 6214 read_complex_part (from_rtx, true)); where from_rtx at that point is (subreg:XC (const_vector:V32QI [ (const_int -107 [0xffffffffffffff95]) (const_int -120 [0xffffffffffffff88]) (const_int 89 [0x59]) (const_int 42 [0x2a]) (const_int 38 [0x26]) (const_int -16 [0xfffffffffffffff0]) (const_int -60 [0xffffffffffffffc4]) (const_int -62 [0xffffffffffffffc2]) (const_int 0 [0]) repeated x24 ]) 0) which is supposedly a valid subreg, reinterpretation of a vector as complex extended double, which is not foldable to constant because it isn't a valid IEEE value which the compiler can express. Or should this have been a concat? Anyway, read_complex_part returns for that (const_double:XF 0.0 [0x0.0p+0]) for the imag part and (subreg:XF (const_vector:V32QI [ (const_int -107 [0xffffffffffffff95]) (const_int -120 [0xffffffffffffff88]) (const_int 89 [0x59]) (const_int 42 [0x2a]) (const_int 38 [0x26]) (const_int -16 [0xfffffffffffffff0]) (const_int -60 [0xffffffffffffffc4]) (const_int -62 [0xffffffffffffffc2]) (const_int 0 [0]) repeated x24 ]) 0) for the real part. The latter makes it through validate_subreg due to the /* ??? Similarly, e.g. with (subreg:DF (reg:TI)). Though store_bit_field is the culprit here, and not the backends. */ else if (known_ge (osize, regsize) && known_ge (isize, osize)) ; - osize is 16, isize is 32 and regsize is 8. If that wasn't for that rule, there would be the /* Subregs involving floating point modes are not allowed to change size unless it's an insert into a complex mode. Therefore (subreg:DI (reg:DF) 0) and (subreg:CS (reg:SF) 0) are fine, but (subreg:SI (reg:DF) 0) isn't. */ rule which would reject it.