This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH/RFC] force_reg() doesn't propagate MEM_POINTER flag to REG_POINTER


While working on PR28690 in which we use the REG_POINTER flag in
rs6000_legitimize_address() to force "base" pointers to objects
to be the first operand of indexed load/store instructions for
performance reasons, we came across a test case in which the
REG_POINTER flag was being lost.  The problem is the call to
force_reg() in break_out_memory_refs(). In this case, we pass
force_reg():

    (mem/f:SI (plus:SI (reg/v/f:SI 120 [ base ])
            (reg:SI 125)) [0 S4 A32])

and get back a normal:

    (reg:SI 126)

when we really wanted:

    (reg/f:SI 126)

This is particularly bad for multidimensional arrays like:

    int indexedload(int ***base, int idx0, int idx1, int idx2)
    {
      return base[idx0][idx1][idx2];
    }

In this case, we'll generate 3 indexed loads, but we'll only be
able to transform the first since the other two base pointers will
have lost their REG_POINTER flags.  Using the patch below propagates
the MEM_POINTER flag to the reg we generate in force_reg(), so that
we're able to transform all of the indexed loads.

Does anyone see any problems with the patch below?  If not, I'll
submit it along with the rest of the patch from PR28690.  I'll note
that it survived bootstrap and regression tests on powerpc64-linux
(32-bit and 64-bit) using all languages except Ada, which I'm not
setup to handle.


Peter

	* explow.c (force_reg): Set REG_POINTER flag according to
	MEM_POINTER flag.

Index: explow.c
===================================================================
--- explow.c	(revision 116698)
+++ explow.c	(working copy)
@@ -710,6 +710,8 @@ force_reg (enum machine_mode mode, rtx x
 
 	align = MIN (sa, ca);
       }
+    else if (MEM_P (x) && MEM_POINTER (x))
+      align = MEM_ALIGN (x);
 
     if (align)
       mark_reg_pointer (temp, align);



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]