[PATCH] PR middle-end/103059: reload: Also accept ASHIFT with indexed addressing

Maciej W. Rozycki macro@embecosm.com
Wed Nov 3 13:53:58 GMT 2021

Correct a `vax-netbsdelf' target regression ultimately caused by commit 
c605a8bf9270 ("VAX: Accept ASHIFT in address expressions") (needed for 
LRA) and as of commit 4a960d548b7d ("Avoid invalid loop transformations 
in jump threading registry.") causing a build error in libgcc:

.../libgcc/libgcov-driver.c: In function 'gcov_do_dump':
.../libgcc/libgcov-driver.c:686:1: error: insn does not satisfy its constraints:
  686 | }
      | ^
(insn 2051 2050 2052 185 (set (reg/f:SI 0 %r0 [555])
        (plus:SI (ashift:SI (mem/c:SI (plus:SI (reg/f:SI 13 %fp)
                        (const_int -28 [0xffffffffffffffe4])) [40 %sfp+-28 S4 A32])
                (const_int 3 [0x3]))
            (plus:SI (reg/v/f:SI 9 %r9 [orig:176 fn_buffer ] [176])
                (const_int 24 [0x18])))) ".../libgcc/libgcov-driver.c":172:40 614 {movaddrdi}
during RTL pass: postreload
.../libgcc/libgcov-driver.c:686:1: internal compiler error: in extract_constrain_insn, at recog.c:2670
0x1122a5ff _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
0x1122a697 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
0x111b5f2f extract_constrain_insn(rtx_insn*)
0x11143eef reload_cse_simplify_operands
0x11142fdb reload_cse_simplify
0x11143533 reload_cse_regs_1
0x11142ce7 reload_cse_regs
0x1114af33 execute
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

This is because reload does not recognize the ASHIFT form of scaled 
indexed addressing that the offending commit enabled the backend to 
produce, and as seen in the RTL above lets the pseudo holding the 
index part become the original memory reference rather than reloading it 
into a hard register.

Fix it then by adding said form to reload, removing the build failure 
and numerous similar regressions throughout `vax-netbsdelf' test suites 
run with the source as at right before the build regression.

Cf. <https://gcc.gnu.org/pipermail/gcc-patches/2021-March/567256.html>, 
and commit 6b3034eaba83 ("lra: Canonicalize mult to shift in address 

	PR middle-end/103059
	* reload.c (find_reloads_address_1): Also accept the ASHIFT form 
	of indexed addressing.
	(find_reloads): Adjust accordingly.

 NB the change to `find_reloads_address_1' is one that removes the build 
error and I am fairly sure I have nailed it.  The change to `find_reloads' 
seemed a natural consequence then as surely it deals with the results from 
`find_reloads_address_1', though things appear to work regardless and I 
haven't investigated what difference it makes.

 I have not yet tracked down which change after commit c605a8bf9270 made 
regressions appear in the test suites, however clearly the commit wasn't 
as complete a change as it should have been.  I'll see if I can find it 
and will mention it in the final commit description if there is anything 
useful in that.

 As noted in the commit description this has been regression-tested with 
commit 4a960d548b7d^.  I'm running regression-testing with GCC 11 right 
now as well and expect results by the end of week.

 I was trying to chase another target I could use to regression-test this 
with that does do scaled indexed addressing while still using old reload.  
The i386 port would be a good candidate, but it has switched to LRA long 
ago with no option to use old reload, and I think there would be little 
point in adding one just for the sake of such verification.  Do we have 
any other port actually that could be affected by this change?

 OK to apply to trunk then and, as a stable regression, to GCC 11?

 gcc/reload.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

Index: gcc/gcc/reload.c
--- gcc.orig/gcc/reload.c
+++ gcc/gcc/reload.c
@@ -2846,10 +2846,11 @@ find_reloads (rtx_insn *insn, int replac
 				    i, operand_type[i], ind_levels, insn);
 	  /* If we now have a simple operand where we used to have a
-	     PLUS or MULT, re-recognize and try again.  */
+	     PLUS or MULT or ASHIFT, re-recognize and try again.  */
 	  if ((OBJECT_P (*recog_data.operand_loc[i])
 	       || GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
 	      && (GET_CODE (recog_data.operand[i]) == MULT
+		  || GET_CODE (recog_data.operand[i]) == ASHIFT
 		  || GET_CODE (recog_data.operand[i]) == PLUS))
 	      INSN_CODE (insn) = -1;
@@ -5562,7 +5563,8 @@ find_reloads_address_1 (machine_mode mod
 	    return 1;
-	if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
+	if (code0 == MULT || code0 == ASHIFT
+	    || code0 == SIGN_EXTEND || code0 == TRUNCATE
 	    || code0 == ZERO_EXTEND || code1 == MEM)
 	    find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH,
@@ -5573,7 +5575,8 @@ find_reloads_address_1 (machine_mode mod
-	else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
+	else if (code1 == MULT || code1 == ASHIFT
+		 || code1 == SIGN_EXTEND || code1 == TRUNCATE
 		 || code1 == ZERO_EXTEND || code0 == MEM)
 	    find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1,

More information about the Gcc-patches mailing list