[RS6000] pr65810, powerpc64 alignment of r2
Alan Modra
amodra@gmail.com
Mon Apr 20 13:53:00 GMT 2015
This fixes a thinko in offsettable_ok_by_alignment. It's not the
absolute placement that matters, but the toc-pointer relative offset.
So alignment of r2 also needs to be taken into account.
Bootstrapped and regression tested powerpc64-linux. OK for mainline
and gcc-5 branch? Without the dead code removal for the branch..
I also have a linker fix to align the toc pointer and gcc configury
changes to supply POWERPC64_TOC_POINTER_ALIGNMENT in the works.
PR target/65810
* config/rs6000/rs6000.c (POWERPC64_TOC_POINTER_ALIGNMENT): Define.
(offsettable_ok_by_alignment): Return false if size exceeds
POWERPC64_TOC_POINTER_ALIGNMENT. Replace dead code with assertion.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 222227)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -6497,13 +6497,21 @@ virtual_stack_registers_memory_p (rtx op)
}
/* Return true if a MODE sized memory accesses to OP plus OFFSET
- is known to not straddle a 32k boundary. */
+ is known to not straddle a 32k boundary. This function is used
+ to determine whether -mcmodel=medium code can use TOC pointer
+ relative addressing for OP. This means the alignment of the TOC
+ pointer must also be taken into account, and unfortunately that is
+ only 8 bytes. */
+#ifndef POWERPC64_TOC_POINTER_ALIGNMENT
+#define POWERPC64_TOC_POINTER_ALIGNMENT 8
+#endif
+
static bool
offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
machine_mode mode)
{
- tree decl, type;
+ tree decl;
unsigned HOST_WIDE_INT dsize, dalign, lsb, mask;
if (GET_CODE (op) != SYMBOL_REF)
@@ -6510,6 +6518,8 @@ offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT
return false;
dsize = GET_MODE_SIZE (mode);
+ if (dsize > POWERPC64_TOC_POINTER_ALIGNMENT)
+ return false;
decl = SYMBOL_REF_DECL (op);
if (!decl)
{
@@ -6553,6 +6563,8 @@ offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT
return false;
dsize = tree_to_uhwi (DECL_SIZE_UNIT (decl));
+ if (dsize > POWERPC64_TOC_POINTER_ALIGNMENT)
+ return false;
if (dsize > 32768)
return false;
@@ -6560,32 +6572,8 @@ offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT
}
}
else
- {
- type = TREE_TYPE (decl);
+ gcc_unreachable ();
- dalign = TYPE_ALIGN (type);
- if (CONSTANT_CLASS_P (decl))
- dalign = CONSTANT_ALIGNMENT (decl, dalign);
- else
- dalign = DATA_ALIGNMENT (decl, dalign);
-
- if (dsize == 0)
- {
- /* BLKmode, check the entire object. */
- if (TREE_CODE (decl) == STRING_CST)
- dsize = TREE_STRING_LENGTH (decl);
- else if (TYPE_SIZE_UNIT (type)
- && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
- dsize = tree_to_uhwi (TYPE_SIZE_UNIT (type));
- else
- return false;
- if (dsize > 32768)
- return false;
-
- return dalign / BITS_PER_UNIT >= dsize;
- }
- }
-
/* Find how many bits of the alignment we know for this access. */
mask = dalign / BITS_PER_UNIT - 1;
lsb = offset & -offset;
--
Alan Modra
Australia Development Lab, IBM
More information about the Gcc-patches
mailing list