Noticed new ICE on this week's gcc snapshot on ilmbase-2.5.7. Here is minimized source: void abs(float *); struct Matrix33 { float x[3][3]; float *operator[](int i) { return x[i]; } Matrix33(); Matrix33(float f, float g) { x[1][0] = x[1][1] = x[1][2] = f; x[2][0] = g; } void equalWithAbsError(); Matrix33 inverse() { Matrix33 s(x[1][2] - x[1][2], x[1][1] - x[1][1]); float r = s[2][0]; if (r) for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) s[i][j] /= r; for (int i = 0;;) { float *__trans_tmp_2 = s[i]; abs(__trans_tmp_2); } } }; void __assert_fail() { Matrix33 m, inv1 = m.inverse(), ident1 = inv1; ident1.equalWithAbsError(); } $ g++-12.0.0 -O3 -c bug.cpp.cpp during RTL pass: expand bug.cpp.cpp: In function 'void __assert_fail()': bug.cpp.cpp:27:5: internal compiler error: Segmentation fault 27 | } | ^ 0x21196c6 internal_error(char const*, ...) ???:0 $ g++-12.0.0 -v Using built-in specs. COLLECT_GCC=/nix/store/hw64v14l9lzircg596kmj1bjiy76wcih-gcc-12.0.0/bin/g++ COLLECT_LTO_WRAPPER=/nix/store/hw64v14l9lzircg596kmj1bjiy76wcih-gcc-12.0.0/libexec/gcc/x86_64-unknown-linux-gnu/12.0.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.0.0 20211226 (experimental) (GCC) Also attaching the unminimized preprocessed file in case it introduced unrelated uninitialized values as `bug.cpp.cpp.orig`.
Created attachment 52065 [details] bug.cpp.cpp.orig.gz bug.cpp.cpp.orig.gz - unreduced file (had to compress to get past 1MB limit)
This was exposed/caused by r12-6113 as far as I can tell. We didn't do SLP of the divide before and now we do and it caused the ICE somehow.
(insn 56 55 57 (set (subreg:V4SF (reg:V2SF 124 [ vect__35.17 ]) 0) (div:V4SF (nil) (reg:V4SF 126))) "t.c":18:23 -1 (nil)) Yes that nill there is wrong.
(gdb) n 534 rtx op1 = lowpart_subreg (V4SFmode, operands[1], 1: debug_rtx(operands[1]) = (subreg:V2SF (reg:DI 123) 0) void (gdb) n 536 rtx op2 = gen_rtx_VEC_CONCAT (V4SFmode, operands[2], 1: debug_rtx(operands[1]) = (subreg:V2SF (reg:DI 123) 0) void (gdb) p op1 $7 = (rtx) 0x0
Created attachment 52068 [details] gcc12-pr103842.patch Untested fix.
(In reply to Jakub Jelinek from comment #5) > Created attachment 52068 [details] > gcc12-pr103842.patch > > Untested fix. The patch is OK. Thanks, Uros.
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:242783c52c22ed96eae722b2fa9847711ac84699 commit r12-6129-g242783c52c22ed96eae722b2fa9847711ac84699 Author: Jakub Jelinek <jakub@redhat.com> Date: Tue Dec 28 10:58:43 2021 +0100 i386: Fix handling of SUBREGs in divv2sf3 [PR103842] register_operand predicate allows not just REGs, but also SUBREGs of REGs, and for the latter lowpart_subreg might FAIL when trying to create paradoxical SUBREG in some cases. For the input operand fixed by force_reg on it first, for the output operand handled by always dividing into a fresh V4SFmode temporary and emit_move_insn into the destination afterwards, that is also beneficial for combine. 2021-12-28 Jakub Jelinek <jakub@redhat.com> PR target/103842 * config/i386/mmx.md (divv2sf3): Use force_reg on op1. Always perform divv4sf3 into a pseudo and emit_move_insn into operands[0]. * g++.dg/opt/pr103842.C: New test.
Fixed.