Bug 113221 - [14 Regression][aarch64]ICE in extract_insn, at recog.cc:2812 since r14-6605-gc0911c6b357ba9
Summary: [14 Regression][aarch64]ICE in extract_insn, at recog.cc:2812 since r14-6605-...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 14.0
: P1 normal
Target Milestone: 14.0
Assignee: Andrew Pinski
URL: https://gcc.gnu.org/pipermail/gcc-pat...
Keywords: ice-on-valid-code
: 113184 (view as bug list)
Depends on:
Blocks:
 
Reported: 2024-01-03 18:07 UTC by Michal Jireš
Modified: 2024-01-18 15:26 UTC (History)
4 users (show)

See Also:
Host:
Target: aarch64
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-01-03 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michal Jireš 2024-01-03 18:07:41 UTC
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)
Comment 1 Andrew Pinski 2024-01-03 18:13:12 UTC
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))
```
Comment 2 Andrew Pinski 2024-01-03 18:19:13 UTC
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 ...
Comment 3 Andrew Pinski 2024-01-16 23:24:00 UTC
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.
Comment 4 Andrew Pinski 2024-01-16 23:31:44 UTC
Actually `(match_operand 0 "register_operand")` should be used instead of the current `(match_code "reg,subreg")`.
Comment 5 Andrew Pinski 2024-01-17 00:10:14 UTC
(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.
Comment 6 Andrew Pinski 2024-01-17 03:38:33 UTC
Patch submitted:
https://gcc.gnu.org/pipermail/gcc-patches/2024-January/643190.html
Comment 7 GCC Commits 2024-01-17 22:03:58 UTC
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>
Comment 8 Andrew Pinski 2024-01-17 22:04:15 UTC
Fixed.
Comment 9 Alex Coplan 2024-01-18 15:26:48 UTC
*** Bug 113184 has been marked as a duplicate of this bug. ***