Bug 58901 - vax bootstrap fails on subreg reload
Summary: vax bootstrap fails on subreg reload
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.8.2
: P3 normal
Target Milestone: 11.0
Assignee: Maciej W. Rozycki
URL:
Keywords: build
Depends on:
Blocks:
 
Reported: 2013-10-28 10:36 UTC by Martin Husemann
Modified: 2022-01-10 10:29 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
.i file from the failing compile (30.13 KB, text/plain)
2013-11-22 18:47 UTC, Martin Husemann
Details
matt's changes, synced by other matt, against trunk. (833 bytes, text/plain)
2019-09-15 12:30 UTC, coypu
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Husemann 2013-10-28 10:36:56 UTC
Trying a native bootstrap on VAX fails when compiling libdecnumber with a failed assertion here:

#0  0x0085637c in fancy_abort (file=0x8dae4d "../../gcc-4.8.2/gcc/emit-rtl.c", 
    line=2019, 
    function=0x8db1e3 <change_address_1(rtx_def*, machine_mode, rtx_def*, int)::__FUNCTION__> "change_address_1", 9285197, 2019, 9286115)
    at ../../gcc-4.8.2/gcc/diagnostic.c:1146
#1  0x00295470 in change_address_1 (memref=0x7ea2d560, mode=HImode, 
    addr=0x7ea0fd2c, validate=1, 2124600672, 5, 2124479788, 1)
    at ../../gcc-4.8.2/gcc/emit-rtl.c:2019
#2  0x00295f54 in adjust_address_1 (memref=0x7ea2d560, mode=HImode, offset=0, 
    validate=1, adjust_address=1, adjust_object=0, 
    size=2, 2124600672, 5, 0, 1, 1, 0, 2)
    at ../../gcc-4.8.2/gcc/emit-rtl.c:2151
#3  0x002d1a06 in alter_subreg (xp=0x7f0e8bc8, final_p=true, 2131659720, 1)
    at ../../gcc-4.8.2/gcc/final.c:3072
#4  0x002d2231 in cleanup_subreg_operands (insn=0x7f2d6360, 2133680992)
    at ../../gcc-4.8.2/gcc/final.c:3018
#5  0x004e5810 in reload (first=0x7ea58620, global=1, 2124776992, 1)
    at ../../gcc-4.8.2/gcc/reload1.c:1240
#6  0x003dc5e2 in do_reload () at ../../gcc-4.8.2/gcc/ira.c:4679
#7  0x003dc7aa in rest_of_handle_reload () at ../../gcc-4.8.2/gcc/ira.c:4779
#8  0x00483bf5 in execute_one_pass (pass=0xc6fda4 <pass_reload>, 13041060)
    at ../../gcc-4.8.2/gcc/passes.c:2333

(gdb) p debug_rtx(memref)
(mem/u/c:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:81 count ] [81])
            (const_int 4 [0x4]))
        (symbol_ref:SI ("DECPOWERS") [flags 0x40] <var_decl 0x7f22fe60 DECPOWERS>)) [3 DECPOWERS S4 A32])

The invocation was:

/usr/pkgobj/lang/gcc48/work/build/./prev-gcc/cc1 -quiet -v -I ../../gcc-4.8.2/libdecnumber -I . -I /usr/pkg/include -I /usr/include -I ../../gcc-4.8.2/libdecnumber -I . -I /usr/pkg/include -I /usr/include -iprefix /usr/pkgobj/lang/gcc48/work/build/prev-gcc/../lib/gcc/vax--netbsdelf/4.8.2/ -isystem /usr/pkgobj/lang/gcc48/work/build/./prev-gcc/include -isystem /usr/pkgobj/lang/gcc48/work/build/./prev-gcc/include-fixed -isystem /usr/pkg/gcc48/vax--netbsdelf/include -isystem /usr/pkg/gcc48/vax--netbsdelf/sys-include ../../gcc-4.8.2/libdecnumber/decNumber.c -fPIC -quiet -dumpbase decNumber.c -auxbase decNumber -g -gtoggle -O2 -Wextra -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wsuggest-attribute=format -Wcast-qual -Wpedantic -Wno-long-long -version -o /var/tmp//ccfituj1.s
Comment 1 Martin Husemann 2013-10-30 19:59:23 UTC
The real question is: why does memory_address_addr_space_p() return false for this rtx. Stepping into it results in:

0x007618be in vax_legitimate_address_p (mode=HImode, x=0x7ea0fd2c, 
    strict=20, 5, 2124479788, 0) at ../../gcc-4.8.2/gcc/config/vax/vax.c:1801
1801    vax_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
(gdb) n
1805      if (nonindexed_address_p (x, strict))
(gdb) print mode
$4 = HImode
(gdb) p debug_rtx(x)
(plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:81 count ] [81])
        (const_int 4 [0x4]))
    (symbol_ref:SI ("DECPOWERS") [flags 0x40] <var_decl 0x7f22fe60 DECPOWERS>))
$5 = void
(gdb) p strict
$6 = false
(gdb) n
1808      if (GET_CODE (x) != PLUS)
(gdb) 
1813      xfoo0 = XEXP (x, 0);
(gdb) 
1814      xfoo1 = XEXP (x, 1);
(gdb) 
1816      if (index_term_p (xfoo0, mode, strict)
(gdb) 
1826      if (indexable_address_p (xfoo0, xfoo1, mode, strict)
(gdb) 
1830      return false;

with a backtrace:

#0  vax_legitimate_address_p (mode=HImode, x=0x7ea0fd2c, 
    strict=false, 5, 2124479788, 0)
    at ../../gcc-4.8.2/gcc/config/vax/vax.c:1830
#1  0x0052049a in default_addr_space_legitimate_address_p (mode=HImode, 
    mem=0x7ea0fd2c, strict=false, as=0 '\000', 5, 2124479788, 0, 0)
    at ../../gcc-4.8.2/gcc/targhooks.c:1175
#2  0x004aa683 in memory_address_addr_space_p (mode=HImode, addr=0x7ea0fd2c, 
    as=0 '\000', 5, 2124479788, 0) at ../../gcc-4.8.2/gcc/recog.c:1299
#3  0x00295454 in change_address_1 (memref=0x7ea2d560, mode=HImode, 
    addr=0x7ea0fd2c, validate=1, 2124600672, 5, 2124479788, 1)
    at ../../gcc-4.8.2/gcc/emit-rtl.c:2019

and, as expected:
(gdb) p debug_rtx(xfoo0)
(mult:SI (reg/v:SI 0 %r0 [orig:81 count ] [81])
    (const_int 4 [0x4]))
$7 = void
(gdb) p debug_rtx(xfoo1)
(symbol_ref:SI ("DECPOWERS") [flags 0x40] <var_decl 0x7f22fe60 DECPOWERS>)
$8 = void
Comment 2 Martin Husemann 2013-10-30 20:43:40 UTC
indexable_address_p() returns false for

(symbol_ref:SI ("DECPOWERS") [flags 0x40] <var_decl 0x7f22fe60 DECPOWERS>)

because flag_pic is true and symbolic_operand (xfoo0, SImode)) returns true:

/* Return true if xfoo0 and xfoo1 constitute a valid indexed address.  */
static bool
indexable_address_p (rtx xfoo0, rtx xfoo1, enum machine_mode mode, bool strict)
{
  if (!CONSTANT_ADDRESS_P (xfoo0))
    return false;
  if (BASE_REGISTER_P (xfoo1, strict))
    return !flag_pic || mode == QImode;
  if (flag_pic && symbolic_operand (xfoo0, SImode))
    return false;
  return reg_plus_index_p (xfoo1, mode, strict);
}

I don't know vax addressing modes - help!
Comment 3 Martin Husemann 2013-10-31 10:03:18 UTC
Matt asked for the instruction involved - I think it is this:

(insn 245 244 246 51 (set (mem:HI (reg/v/f:SI 1 %r1 [orig:67 sup ] [67]) [2 *sup_104+0 S2 A16])
        (plus:HI (subreg:HI (mem/u/c:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:81 count ] [81])
                            (const_int 4 [0x4]))
                        (symbol_ref:SI ("DECPOWERS") [flags 0x40] <var_decl 0x7f22fe60 DECPOWERS>)) [3 DECPOWERS S4 A32]) 0)
            (const_int -1 [0xffffffff]))) ../../gcc-4.8.2/libdecnumber/decNumber.c:7183 48 {addhi3}
     (nil))
Comment 4 Martin Husemann 2013-10-31 14:42:07 UTC
I got a quick lesson in addressing modes for vax ;-)
It seems the mode = HImode passed to the upper functions in the call stack is the problem - with HImode we can only use index operands with a factor of 2, but this rtx has a factor of 4.

The problem starts in alter_subreg(), where the call to adjust_address_1 is done:

#6  0x002d1a06 in alter_subreg (xp=0x7f0e8bc8, final_p=true, 2131659720, 1)
    at ../../gcc-4.8.2/gcc/final.c:3072
3072            *xp = adjust_address (y, GET_MODE (x), offset);

and x has (due to subreg) HImode:

(gdb) p debug_rtx(x)
(subreg:HI (mem/u/c:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:81 count ] [81])
                (const_int 4 [0x4]))
            (symbol_ref:SI ("DECPOWERS") [flags 0x40] <var_decl 0x7f22fe60 DECPOWERS>)) [3 DECPOWERS S4 A32]) 0)
$12 = void
(gdb) p debug_rtx(y)
(mem/u/c:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:81 count ] [81])
            (const_int 4 [0x4]))
        (symbol_ref:SI ("DECPOWERS") [flags 0x40] <var_decl 0x7f22fe60 DECPOWERS>)) [3 DECPOWERS S4 A32])
Comment 5 Martin Husemann 2013-11-22 18:47:06 UTC
Created attachment 31275 [details]
.i file from the failing compile
Comment 6 Martin Husemann 2013-11-22 18:54:33 UTC
This is beyound my gcc capabilities: the rtx in question is wrong for vax, but the bug seems to be at a higher level: an indexed memory access can not be wrapped into a subreg with offset in the same statement - the rtx needs to be split into a register load and then subreg extraction (or so I think, not an expert in vax addressing modes)
Comment 7 coypu 2019-09-15 12:30:35 UTC
Created attachment 46884 [details]
matt's changes, synced by other matt, against trunk.

Confirming as still occurring in gcc-trunk as of:
xgcc (GCC) 10.0.0 20190907 (experimental)

NetBSD has a local diff to avoid this crash.
I attached it (updated for trunk) for reference.

The commit message for it (by Matt Thomas):
https://github.com/NetBSD/src/commit/e437e96750193b86d0464965661f616e011056fa

"Fix a problem with reloading the inner reg of a subreg when it's a mode dependent address."
Comment 8 GCC Commits 2020-12-05 18:27:23 UTC
The master branch has been updated by Maciej W. Rozycki <macro@gcc.gnu.org>:

https://gcc.gnu.org/g:a27d5f9a73978f20cfef1796a94f6a1a82438146

commit r11-5761-ga27d5f9a73978f20cfef1796a94f6a1a82438146
Author: Matt Thomas <matt@3am-software.com>
Date:   Sat Dec 5 18:26:23 2020 +0000

    PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address
    
    Fix an ICE with the handling of RTL expressions like:
    
    (subreg:QI (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 0 %r0 [orig:67 i ] [67])
                        (const_int 4 [0x4]))
                    (reg/v/f:SI 7 %r7 [orig:59 doacross ] [59]))
                (const_int 40 [0x28])) [1 MEM[(unsigned int *)doacross_63 + 40B + i_106 * 4]+0 S4 A32]) 0)
    
    that causes the compilation of libgomp to fail:
    
    during RTL pass: reload
    .../libgomp/ordered.c: In function 'GOMP_doacross_wait':
    .../libgomp/ordered.c:507:1: internal compiler error: in change_address_1, at emit-rtl.c:2275
      507 | }
          | ^
    0x10a3462b change_address_1
            .../gcc/emit-rtl.c:2275
    0x10a353a7 adjust_address_1(rtx_def*, machine_mode, poly_int<1u, long>, int, int, int, poly_int<1u, long>)
            .../gcc/emit-rtl.c:2409
    0x10ae2993 alter_subreg(rtx_def**, bool)
            .../gcc/final.c:3368
    0x10ae25cf cleanup_subreg_operands(rtx_insn*)
            .../gcc/final.c:3322
    0x110922a3 reload(rtx_insn*, int)
            .../gcc/reload1.c:1232
    0x10de2bf7 do_reload
            .../gcc/ira.c:5812
    0x10de3377 execute
            .../gcc/ira.c:5986
    
    in a `vax-netbsdelf' build, where an attempt is made to change the mode
    of the contained memory reference to the mode of the containing SUBREG.
    Such RTL expressions are produced by the VAX shift and rotate patterns
    (`ashift', `ashiftrt', `rotate', `rotatert') where the count operand
    always has the QI mode regardless of the mode, either SI or DI, of the
    datum shifted or rotated.
    
    Such a mode change cannot work where the memory reference uses the
    indexed addressing mode, where a multiplier is implied that in the VAX
    ISA depends on the width of the memory access requested and therefore
    changing the machine mode would change the address calculation as well.
    
    Avoid the attempt then by forcing the reload of any SUBREGs containing
    a mode-dependent memory reference, also fixing these regressions:
    
    FAIL: gcc.c-torture/compile/pr46883.c   -Os  (internal compiler error)
    FAIL: gcc.c-torture/compile/pr46883.c   -Os  (test for excess errors)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (internal compiler error)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O2  (test for excess errors)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (internal compiler error)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions  (test for excess errors)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (internal compiler error)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O3 -g  (test for excess errors)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (internal compiler error)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (internal compiler error)
    FAIL: gcc.c-torture/execute/20120808-1.c   -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects  (test for excess errors)
    FAIL: gcc.dg/20050629-1.c (internal compiler error)
    FAIL: gcc.dg/20050629-1.c (test for excess errors)
    FAIL: c-c++-common/torture/pr53505.c   -Os  (internal compiler error)
    FAIL: c-c++-common/torture/pr53505.c   -Os  (test for excess errors)
    FAIL: gfortran.dg/coarray_failed_images_1.f08   -Os  (internal compiler error)
    FAIL: gfortran.dg/coarray_stopped_images_1.f08   -Os  (internal compiler error)
    
    With test case #0 included it causes a reload with:
    
    (insn 15 14 16 4 (set (reg:SI 31)
            (ashift:SI (const_int 1 [0x1])
                (subreg:QI (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ]) 0))) "pr58901-0.c":15:12 94 {ashlsi3}
         (expr_list:REG_DEAD (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
            (nil)))
    
    as follows:
    
    Reloads for insn # 15
    Reload 0: reload_in (SI) = (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
            ALL_REGS, RELOAD_FOR_INPUT (opnum = 2)
            reload_in_reg: (reg:SI 30 [ MEM[(int *)s_8(D) + 4B + _5 * 4] ])
            reload_reg_rtx: (reg:SI 5 %r5)
    
    resulting in:
    
    (insn 37 14 15 4 (set (reg:SI 5 %r5)
            (mem/c:SI (plus:SI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:25 i ] [25])
                            (const_int 4 [0x4]))
                        (reg/v/f:SI 4 %r4 [orig:29 s ] [29]))
                    (const_int 4 [0x4])) [1 MEM[(int *)s_8(D) + 4B + _5 * 4]+0 S4 A32])) "pr58901-0.c":15:12 12 {movsi_2}
         (nil))
    (insn 15 37 16 4 (set (reg:SI 2 %r2 [31])
            (ashift:SI (const_int 1 [0x1])
                (reg:QI 5 %r5))) "pr58901-0.c":15:12 94 {ashlsi3}
         (nil))
    
    and assembly like:
    
    .L3:
            movl 4(%r4)[%r1],%r5
            ashl %r5,$1,%r2
            xorl2 %r2,%r0
            incl %r1
            cmpl %r1,%r3
            jneq .L3
    
    produced for the loop, providing optimization has been enabled.
    
    Likewise with test case #1 the reload of:
    
    (insn 17 16 18 4 (set (reg:SI 34)
            (and:SI (subreg:SI (reg/v:DI 27 [ t ]) 4)
                (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int}
         (expr_list:REG_DEAD (reg/v:DI 27 [ t ])
            (nil)))
    
    is as follows:
    
    Reloads for insn # 17
    Reload 0: reload_in (DI) = (reg/v:DI 27 [ t ])
            reload_out (SI) = (reg:SI 2 %r2 [34])
            ALL_REGS, RELOAD_OTHER (opnum = 0)
            reload_in_reg: (reg/v:DI 27 [ t ])
            reload_out_reg: (reg:SI 2 %r2 [34])
            reload_reg_rtx: (reg:DI 4 %r4)
    
    resulting in:
    
    (insn 40 16 17 4 (set (reg:DI 4 %r4)
            (mem/c:DI (plus:SI (mult:SI (reg/v:SI 1 %r1 [orig:26 i ] [26])
                        (const_int 8 [0x8]))
                    (reg/v/f:SI 3 %r3 [orig:30 s ] [30])) [1 MEM[(const struct s *)s_13(D) + _7 * 8]+0 S8 A32])) "pr58901-1.c":18:20 11 {movdi}
         (nil))
    (insn 17 40 41 4 (set (reg:SI 4 %r4)
            (and:SI (reg:SI 5 %r5 [+4 ])
                (const_int 1 [0x1]))) "pr58901-1.c":18:20 77 {*andsi_const_int}
         (nil))
    
    and assembly like:
    
    .L3:
            movq (%r3)[%r1],%r4
            bicl3 $-2,%r5,%r4
            addl2 %r4,%r0
            jaoblss %r0,%r1,.L3
    
    First posted at: <https://gcc.gnu.org/ml/gcc/2014-06/msg00060.html>.
    
    2020-12-05  Matt Thomas  <matt@3am-software.com>
                Maciej W. Rozycki  <macro@linux-mips.org>
    
            gcc/
            PR target/58901
            * reload.c (push_reload): Also reload the inner expression of a
            SUBREG for pseudos associated with a mode-dependent memory
            reference.
            (find_reloads): Force a reload likewise.
    
    2020-12-05  Maciej W. Rozycki  <macro@linux-mips.org>
    
            gcc/testsuite/
            PR target/58901
            * gcc.c-torture/compile/pr58901-0.c: New test.
            * gcc.c-torture/compile/pr58901-1.c: New test.
Comment 9 Maciej W. Rozycki 2020-12-05 18:35:55 UTC
Fixed as per the commit message automatically entered.