The function instantiate_virtual_regs_in_insn does not handle the case if an
address with offset is taken. Then a virtual register may appear (e.g
argptr) inside a PLUS.

 

This patch adds the handling for PLUS.

 

Stefan

 

--- a/gcc/function.c

+++ b/gcc/function.c

@@ -1,5 +1,5 @@

/* Expands front end tree to back end RTL for GCC.

-   Copyright (C) 1987-2019 Free Software Foundation, Inc.

+   Copyright (C) 1987-2020 Free Software Foundation, Inc.

 This file is part of GCC.

@@ -1658,9 +1658,12 @@ instantiate_virtual_regs_in_insn (rtx_insn *insn)

     }

   /* In the general case, we expect virtual registers to appear only in

-     operands, and then only as either bare registers or inside memories.
*/

+     operands, and then only as either bare registers or inside memories.

+     SBF: ... and sometimes - taking an address - inside a PLUS. */

   for (i = 0; i < recog_data.n_operands; ++i)

     {

+      poly_int64 old_offset = 0;

+

       x = recog_data.operand[i];

       switch (GET_CODE (x))

        {

@@ -1694,10 +1697,19 @@ instantiate_virtual_regs_in_insn (rtx_insn *insn)

          }

          break;

+       case PLUS:

+         if (!REG_P (XEXP (x, 0)) || !CONST_INT_P (XEXP (x, 1)))

+           continue;

+

+         old_offset = INTVAL (XEXP (x, 1));

+         x = XEXP (x, 0);

+         /* no break */

        case REG:

          new_rtx = instantiate_new_reg (x, &offset);

          if (new_rtx == NULL)

            continue;

+

+         offset += old_offset;

          if (known_eq (offset, 0))

            x = new_rtx;

          else

Reply via email to