diff --git a/gcc44-pr40971.patch b/gcc44-pr40971.patch new file mode 100644 index 0000000..1f6a1cf --- /dev/null +++ b/gcc44-pr40971.patch @@ -0,0 +1,93 @@ +2009-08-05 Jakub Jelinek + + 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 +@@ -3808,6 +3808,8 @@ rtx + rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, + enum machine_mode mode) + { ++ unsigned int extra = 0; ++ + if (GET_CODE (x) == SYMBOL_REF) + { + enum tls_model model = SYMBOL_REF_TLS_MODEL (x); +@@ -3815,10 +3817,32 @@ rs6000_legitimize_address (rtx x, rtx ol + return rs6000_legitimize_tls_address (x, model); + } + ++ 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) == PLUS + && GET_CODE (XEXP (x, 0)) == REG + && GET_CODE (XEXP (x, 1)) == CONST_INT +- && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000 ++ && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) ++ >= 0x10000 - extra) + && !((TARGET_POWERPC64 + && (mode == DImode || mode == TImode) + && (INTVAL (XEXP (x, 1)) & 3) != 0) +@@ -3831,10 +3855,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); +- return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int)); ++ return 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; ++ } ++}