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
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
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!
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))
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])
Created attachment 31275 [details] .i file from the failing compile
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)
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."
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.
Fixed as per the commit message automatically entered.