diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6b8dc6467ec37d63e6e276f2ed2c0beb36f4ae91..76a2bd2b8e9fa7fc8e39cd269983f09612e07448 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2011-03-04  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
+
+	* config/s390/s390.c (s390_decompose_address): Reject non-literal
+	pool references in UNSPEC_LTREL_OFFSET.
+
 2011-03-04  Jan Hubicka  <jh@suse.cz>
 
 	PR lto/47497
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index f43b3765032b1c98161a06d9326e271554e336c8..3e6edb76b475e56eeb9fb5f489c4825f3d1b5584 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2065,6 +2065,16 @@ s390_decompose_address (rtx addr, struct s390_address *out)
       else if (GET_CODE (disp) == UNSPEC
 	       && XINT (disp, 1) == UNSPEC_LTREL_OFFSET)
         {
+	  /* In case CSE pulled a non literal pool reference out of
+	     the pool we have to reject the address.  This is
+	     especially important when loading the GOT pointer on non
+	     zarch CPUs.  In this case the literal pool contains an lt
+	     relative offset to the _GLOBAL_OFFSET_TABLE_ label which
+	     will most likely exceed the displacement.  */
+	  if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF
+	      || !CONSTANT_POOL_ADDRESS_P (XVECEXP (disp, 0, 0)))
+	    return false;
+
 	  orig_disp = gen_rtx_CONST (Pmode, disp);
 	  if (offset)
 	    {