Compiling reduced testcase gcc.dg/debug/pr43972.c results in ICE since r14-6605-gc0911c6b357ba9. $ cat pr43972.c void bar(); void foo(int* b) { for (;;) *b++ = (long)bar; } $ aarch64-linux-gnu-gcc pr43972.c -O1 -fno-move-loop-invariants -funroll-all-loops pr43972.c: In function ‘foo’: pr43972.c:5:1: error: unrecognizable insn: 5 | } | ^ (insn 80 0 0 (set (reg:SI 130) (subreg:SI (lo_sum:DI (reg/f:DI 105) (symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7ffff7518100 bar>)) 0)) -1 (nil)) during RTL pass: reload pr43972.c:5:1: internal compiler error: in extract_insn, at recog.cc:2812 0x16e9be0 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*) /home/mjires/git/GCC/master/gcc/rtl-error.cc:108 0x16e9c21 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*) /home/mjires/git/GCC/master/gcc/rtl-error.cc:116 0x169a764 extract_insn(rtx_insn*) /home/mjires/git/GCC/master/gcc/recog.cc:2812 0x147d140 ira_remove_insn_scratches(rtx_insn*, bool, _IO_FILE*, rtx_def* (*)(rtx_def*)) /home/mjires/git/GCC/master/gcc/ira.cc:5381 0x14d574a remove_insn_scratches /home/mjires/git/GCC/master/gcc/lra.cc:2154 0x14d112b lra_emit_move(rtx_def*, rtx_def*) /home/mjires/git/GCC/master/gcc/lra.cc:513 0x14eb151 curr_insn_transform /home/mjires/git/GCC/master/gcc/lra-constraints.cc:4669 0x14ed78c lra_constraints(bool) /home/mjires/git/GCC/master/gcc/lra-constraints.cc:5414 0x14d6064 lra(_IO_FILE*, int) /home/mjires/git/GCC/master/gcc/lra.cc:2442 0x147e4d3 do_reload /home/mjires/git/GCC/master/gcc/ira.cc:5973 0x147e970 execute /home/mjires/git/GCC/master/gcc/ira.cc:6161 Please submit a full bug report, with preprocessed source (by using -freport-bug). Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. $ aarch64-linux-gnu-gcc -v Using built-in specs. COLLECT_GCC=aarch64-linux-gnu-gcc COLLECT_LTO_WRAPPER=/home/mjires/built/master/libexec/gcc/aarch64-linux-gnu/14.0.0/lto-wrapper Target: aarch64-linux-gnu Configured with: /home/mjires/git/GCC/master/configure --prefix=/home/mjires/built/master --target=aarch64-linux-gnu --disable-bootstrap --enable-languages=c,c++,fortran --disable-multilib --disable-libsanitizer --enable-checking : (reconfigured) /home/mjires/git/GCC/master/configure --prefix=/home/mjires/built/master --target=aarch64-linux-gnu --disable-bootstrap --enable-languages=c,c++,fortran --disable-multilib --disable-libsanitizer --enable-checking Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 14.0.0 20240103 (experimental) (GCC)
Confirmed, but the IR from the ldp_fusion pass looks ok: ``` (insn 30 29 15 3 (set (reg/f:DI 110) (lo_sum:DI (reg/f:DI 109) (symbol_ref:DI ("_Z3barv") [flags 0x41] <function_decl 0x7f1f0f047e00 bar>))) "/app/example.cpp":5:10 discrim 1 -1 (expr_list:REG_DEAD (reg/f:DI 109) (expr_list:REG_EQUAL (symbol_ref:DI ("_Z3barv") [flags 0x41] <function_decl 0x7f1f0f047e00 bar>) (nil)))) (insn 15 30 32 3 (parallel [ (set (reg:DI 106) (plus:DI (reg:DI 106) (const_int 4 [0x4]))) (set (mem:SI (reg:DI 106) [0 S4 A8]) (subreg:SI (reg/f:DI 104) 0)) (set (mem:SI (plus:DI (reg:DI 106) (const_int 4 [0x4])) [0 S4 A8]) (subreg:SI (reg/f:DI 110) 0)) ]) "/app/example.cpp":5:10 discrim 1 102 {*storewb_post_pair_4} (nil)) ```
IRA decided to combine: ``` (insn 9 8 19 3 (set (reg/f:DI 104) (lo_sum:DI (reg/f:DI 105) (symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7ff639b05f00 bar>))) "t.c":5:10 discrim 1 -1 (expr_list:REG_DEAD (reg/f:DI 105) (expr_list:REG_EQUAL (symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7ff639b05f00 bar>) (nil)))) ... (insn 21 20 11 3 (set (reg/f:DI 110) (lo_sum:DI (reg/f:DI 109) (symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7ff639b05f00 bar>))) "t.c":5:10 discrim 1 -1 (expr_list:REG_DEAD (reg/f:DI 109) (expr_list:REG_EQUAL (symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7ff639b05f00 bar>) (nil)))) (insn 11 21 27 3 (parallel [ (set (reg:DI 106) (plus:DI (reg:DI 106) (const_int 4 [0x4]))) (set (mem:SI (reg:DI 106) [0 S4 A8]) (subreg:SI (reg/f:DI 104) 0)) (set (mem:SI (plus:DI (reg:DI 106) (const_int 4 [0x4])) [0 S4 A8]) (subreg:SI (reg/f:DI 110) 0)) ]) "t.c":5:10 discrim 1 102 {*storewb_post_pair_4} (nil)) ``` to: ``` (insn 11 20 27 3 (parallel [ (set (reg:DI 106) (plus:DI (reg:DI 106) (const_int 4 [0x4]))) (set (mem:SI (reg:DI 106) [0 S4 A8]) (subreg:SI (lo_sum:DI (reg/f:DI 105) (symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7ff639b05f00 bar>)) 0)) (set (mem:SI (plus:DI (reg:DI 106) (const_int 4 [0x4])) [0 S4 A8]) (subreg:SI (lo_sum:DI (reg/f:DI 109) (symbol_ref:DI ("bar") [flags 0x41] <function_decl 0x7ff639b05f00 bar>)) 0)) ]) "t.c":5:10 discrim 1 102 {*storewb_post_pair_4} (expr_list:REG_DEAD (reg/f:DI 109) (expr_list:REG_DEAD (reg/f:DI 105) (nil)))) ``` But I have no idea why though ...
So I think aarch64_ldp_reg_operand allows too much, it allows `(subreg:SI (lo_sum:DI` when it should have just allowed `(subreg:SI (reg:`. I am going to see if that fixes the issue.
Actually `(match_operand 0 "register_operand")` should be used instead of the current `(match_code "reg,subreg")`.
(In reply to Andrew Pinski from comment #4) > Actually `(match_operand 0 "register_operand")` should be used instead of > the current `(match_code "reg,subreg")`. Except that does not work since register_operand checks the mode ... and then we fail to match: ``` (insn 46 45 47 2 (parallel [ (set (reg:V4SI 148) (unspec:V4SI [ (mem/c:V2x16QI (reg:DI 147) [0 +0 S32 A128]) ] UNSPEC_LDP_FST)) (set (reg:V4SI 149) (unspec:V4SI [ (mem/c:V2x16QI (reg:DI 147) [0 +0 S32 A128]) ] UNSPEC_LDP_SND)) ]) "../../../libgcc/libgcov-interface.c":211:2 -1 (nil)) ``` Because we only define the load_pair_16 for TImode and TImode != V4SImode here ... So Back to changing it to only test for reg and subreg of a reg then.
Patch submitted: https://gcc.gnu.org/pipermail/gcc-patches/2024-January/643190.html
The trunk branch has been updated by Andrew Pinski <pinskia@gcc.gnu.org>: https://gcc.gnu.org/g:7a8124e341aebcc544b4720e920b625f4ffe4e8a commit r14-8194-g7a8124e341aebcc544b4720e920b625f4ffe4e8a Author: Andrew Pinski <quic_apinski@quicinc.com> Date: Tue Jan 16 15:37:49 2024 -0800 aarch64: Fix aarch64_ldp_reg_operand predicate not to allow all subreg [PR113221] So the problem here is that aarch64_ldp_reg_operand will all subreg even subreg of lo_sum. When LRA tries to fix that up, all things break. So the fix is to change the check to only allow reg and subreg of regs. Note the tendancy here is to use register_operand but that checks the mode of the register but we need to allow a mismatch modes for this predicate for now. Built and tested for aarch64-linux-gnu with no regressions (Also tested with the LD/ST pair pass back on). PR target/113221 gcc/ChangeLog: * config/aarch64/predicates.md (aarch64_ldp_reg_operand): For subreg, only allow REG operands instead of allowing all. gcc/testsuite/ChangeLog: * gcc.c-torture/compile/pr113221-1.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Fixed.
*** Bug 113184 has been marked as a duplicate of this bug. ***