churchyard / rpms / gcc

Forked from rpms/gcc 4 years ago
Clone
Blob Blame History Raw
2009-08-05  Jakub Jelinek  <jakub@redhat.com>

	PR target/40971
	* config/rs6000/rs6000.c (rs6000_legitimize_address): For
	[DT][FDI]mode ensure the offset isn't 4/8/12 bytes below 0x8000.

	* gcc.dg/pr40971.c: New test.

--- gcc/config/rs6000/rs6000.c.jj	2009-04-27 16:47:29.000000000 +0200
+++ gcc/config/rs6000/rs6000.c	2009-08-05 16:53:42.000000000 +0200
@@ -4490,6 +4490,28 @@ rs6000_legitimize_address (rtx x, rtx ol
 {
   rtx ret = NULL_RTX;
   rtx orig_x = x;
+  unsigned int extra = 0;
+
+  switch (mode)
+    {
+    case DFmode:
+    case DDmode:
+      extra = 4;
+      break;
+    case DImode:
+      if (!TARGET_POWERPC64)
+	extra = 4;
+      break;
+    case TFmode:
+    case TDmode:
+      extra = 12;
+      break;
+    case TImode:
+      extra = TARGET_POWERPC64 ? 8 : 12;
+      break;
+    default:
+      break;
+    }
 
   if (GET_CODE (x) == SYMBOL_REF)
     {
@@ -4512,7 +4534,7 @@ rs6000_legitimize_address (rtx x, rtx ol
 	   && GET_CODE (XEXP (x, 0)) == REG
 	   && GET_CODE (XEXP (x, 1)) == CONST_INT
 	   && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000)
-	       >= 0x10000)
+	       >= 0x10000 - extra)
 	   && !((TARGET_POWERPC64
 		 && (mode == DImode || mode == TImode)
 		 && (INTVAL (XEXP (x, 1)) & 3) != 0)
@@ -4524,10 +4546,12 @@ rs6000_legitimize_address (rtx x, rtx ol
       HOST_WIDE_INT high_int, low_int;
       rtx sum;
       low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
+      if (low_int >= 0x8000 - extra)
+	low_int = 0;
       high_int = INTVAL (XEXP (x, 1)) - low_int;
       sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
 					 GEN_INT (high_int)), 0);
-      ret = gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
+      ret = plus_constant (sum, low_int);
     }
   else if (GET_CODE (x) == PLUS
 	   && GET_CODE (XEXP (x, 0)) == REG
--- gcc/testsuite/gcc.dg/pr40971.c.jj	2009-08-05 16:46:17.000000000 +0200
+++ gcc/testsuite/gcc.dg/pr40971.c	2009-08-05 16:45:44.000000000 +0200
@@ -0,0 +1,23 @@
+/* PR target/40971 */
+/* { dg-do compile } */
+/* { dg-options "-O -fstack-protector -fno-strict-aliasing" } */
+/* { dg-require-effective-target fstack_protector } */
+
+extern void bar (char *);
+
+void
+foo (int f, long a)
+{
+  {
+    char d[32768];
+    bar (d);
+  }
+  double b = f;
+  while (a)
+    {
+      char c[sizeof (double)];
+      __builtin_memcpy (c, &b, sizeof (c));
+      if (*(double *) c != 2.0)
+	break;
+    }
+}