[PATCH] lra: clear lra_insn_recog_data after simplifying a mem subreg

Ilya Leoshkevich iii@linux.ibm.com
Thu Jan 14 00:55:11 GMT 2021


Hello,

I ran into this problem when writing new patterns for s390.  I'm not
100% sure this fix is correct, but it resolves my issue and survives
bootstrap and regtest on x86_64-redhat-linux, ppc64le-redhat-linux and
s390x-redhat-linux.  Could you please take a look?

Best regards,
Ilya




Suppose we have:

    (insn (set (reg:FPRX2 70) (subreg:FPRX2 (reg/v:TF 63) 0)))

where operand_loc[0] points to r70 and operand_loc[1] points to r63.
If r63 is spilled, remove_pseudos() will change this insn to:

  (insn (set (reg:FPRX2 70)
             (subreg:FPRX2 (mem/c:TF (plus:DI (reg:DI %fp)
	                                      (const_int 144))))))

This is fine so far: rtx pointed to by operand_loc[1] has been changed
from (reg) to (mem), but its slot is still under (subreg).  However,
alter_subreg() will simplify this insn to:

  (insn (set (reg:FPRX2 70)
             (mem/c:FPRX2 (plus:DI (reg:DI %fp) (const_int 144)))))

The (subreg) is gone, and therefore operand_loc[1] is no longer valid.
This will prevent process_insn_for_elimination() from updating the spill
slot offset, causing miscompilation: different instructions will refer
to the same spill slot using different offsets.

Fix by clearing all the cached data, and not just used_insn_alternative.

gcc/ChangeLog:

2021-01-13  Ilya Leoshkevich  <iii@linux.ibm.com>

	* lra-spills.c (remove_pseudos): Call lra_update_insn_recog_data()
	after calling alter_subreg() on a (mem).
---
 gcc/lra-spills.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index 26f56b2df02..01bd82574e7 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -431,7 +431,7 @@ remove_pseudos (rtx *loc, rtx_insn *insn)
 	  alter_subreg (loc, false);
 	  if (GET_CODE (*loc) == MEM)
 	    {
-	      lra_get_insn_recog_data (insn)->used_insn_alternative = -1;
+	      lra_update_insn_recog_data (insn);
 	      if (lra_dump_file != NULL)
 		fprintf (lra_dump_file,
 			 "Memory subreg was simplified in insn #%u\n",
-- 
2.26.2



More information about the Gcc-patches mailing list