Re: [PATCH v3 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address

2020-11-30 Thread Jeff Law via Gcc-patches



On 11/27/20 1:50 PM, Maciej W. Rozycki wrote:
> From: Matt Thomas 
>
> 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
>  

[PATCH v3 01/31] PR target/58901: reload: Handle SUBREG of MEM with a mode-dependent address

2020-11-27 Thread Maciej W. Rozycki
From: Matt Thomas 

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