[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