diff mbox

[2/6] rs6000: Do not allow lo_sum accesses >= 4 bytes if unaligned

Message ID 56efdbfb9f698d499feb87587d98c7cb47185d1b.1421482716.git.segher@kernel.crashing.org
State New
Headers show

Commit Message

Segher Boessenkool Jan. 17, 2015, 8:48 a.m. UTC
This fixes 29 FAILs.

The ld, lwa etc. insns do not encode the low two bits of the offset in
the opcode; those have to be zero.  For -m64 this seemed to never matter,
datums are always aligned; but for -m32 -mpowerpc64 you can get symbols
that are not sufficiently aligned.  So check for that.

[ Hrm, I think this triggers for lwz as well?  I'll investigate. ]


2015-01-16  Segher Boessenkool  <segher@kernel.crashing.org>

gcc/
	* config/rs6000/rs6000.c (lo_sum_symbol_misaligned_p): New function.
	(legitimate_lo_sum_address_p): Use it for TARGET_POWERPC64.

---
 gcc/config/rs6000/rs6000.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

Comments

David Edelsohn Jan. 17, 2015, 2:30 p.m. UTC | #1
On Sat, Jan 17, 2015 at 3:48 AM, Segher Boessenkool
<segher@kernel.crashing.org> wrote:
> This fixes 29 FAILs.
>
> The ld, lwa etc. insns do not encode the low two bits of the offset in
> the opcode; those have to be zero.  For -m64 this seemed to never matter,
> datums are always aligned; but for -m32 -mpowerpc64 you can get symbols
> that are not sufficiently aligned.  So check for that.
>
> [ Hrm, I think this triggers for lwz as well?  I'll investigate. ]
>
>
> 2015-01-16  Segher Boessenkool  <segher@kernel.crashing.org>
>
> gcc/
>         * config/rs6000/rs6000.c (lo_sum_symbol_misaligned_p): New function.
>         (legitimate_lo_sum_address_p): Use it for TARGET_POWERPC64.

Okay.

Thanks, David
Segher Boessenkool Jan. 17, 2015, 7:51 p.m. UTC | #2
On Sat, Jan 17, 2015 at 09:30:07AM -0500, David Edelsohn wrote:
> On Sat, Jan 17, 2015 at 3:48 AM, Segher Boessenkool
> <segher@kernel.crashing.org> wrote:
> > This fixes 29 FAILs.
> >
> > The ld, lwa etc. insns do not encode the low two bits of the offset in
> > the opcode; those have to be zero.  For -m64 this seemed to never matter,
> > datums are always aligned; but for -m32 -mpowerpc64 you can get symbols
> > that are not sufficiently aligned.  So check for that.
> >
> > [ Hrm, I think this triggers for lwz as well?  I'll investigate. ]
> >
> >
> > 2015-01-16  Segher Boessenkool  <segher@kernel.crashing.org>
> >
> > gcc/
> >         * config/rs6000/rs6000.c (lo_sum_symbol_misaligned_p): New function.
> >         (legitimate_lo_sum_address_p): Use it for TARGET_POWERPC64.
> 
> Okay.

I'll hold off on this one until it's clear what it does for lwz, and -m64
performance too.

It should do absolutely nothing for aligned accesses, so it cannot be all
that bad, but I don't want to regress even a tiny little bit so late in
the game.  -m32 -mpowerpc64 hasn't worked properly for years, this series
does not fix everything yet (it doesn't do anything specific to Darwin,
too), and this patch fixes a relatively minor issue (not affecting too
many programs).


Segher
diff mbox

Patch

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 551181b..53bee13 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -6735,6 +6735,39 @@  macho_lo_sum_memory_operand (rtx x, machine_mode mode)
   return CONSTANT_P (x);
 }
 
+/* Return true if X (which is the second operand of a LO_SUM) is a symbol
+   that is not sufficiently aligned for a DS-form instruction.  */
+static bool
+lo_sum_symbol_misaligned_p (rtx x)
+{
+  if (GET_CODE (x) == CONST)
+    x = XEXP (x, 0);
+
+  if (GET_CODE (x) == PLUS)
+    x = XEXP (x, 0);
+
+  if (GET_CODE (x) != SYMBOL_REF)
+    return false;
+
+  tree decl = SYMBOL_REF_DECL (x);
+  if (decl)
+    return DECL_ALIGN_UNIT (decl) < 4;
+
+  if (SYMBOL_REF_HAS_BLOCK_INFO_P (x)
+      && SYMBOL_REF_ANCHOR_P (x))
+    {
+      struct object_block *block = SYMBOL_REF_BLOCK (x);
+      if (block)
+	return block->alignment < 32;
+    }
+
+  if (CONSTANT_POOL_ADDRESS_P (x))
+    return GET_MODE_ALIGNMENT (get_pool_mode (x)) < 32;
+
+  /* Assume it's okay otherwise.  */
+  return false;
+}
+
 static bool
 legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
 {
@@ -6774,6 +6807,10 @@  legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
 	       TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT
 	       && (mode == DFmode || mode == DDmode)))
 	return false;
+      if (TARGET_POWERPC64
+	  && GET_MODE_SIZE (mode) >= 4
+	  && lo_sum_symbol_misaligned_p (x))
+	return false;
 
       return CONSTANT_P (x) || large_toc_ok;
     }