Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 186357)
+++ doc/tm.texi	(working copy)
@@ -2875,6 +2875,10 @@ as below:
 A target hook which returns the register bank number to which the  register @var{hard_regno} belongs to.  The smaller the number, the  more preferable the hard register usage (when all other conditions are  the same).  This hook can be used to prefer some hard register over  others in LRA.  For example, some x86-64 register usage needs  additional prefix which makes instructions longer.  The hook can  return bigger bank number for such registers make them less favorable  and as result making the generated code smaller.    The default version of this target hook returns always zero.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_DIFFERENT_ADDR_DISPLACEMENT_P (void)
+A target hook which returns true if an address with the same structure  can have different maximal legitimate displacement.  For example, the  displacement can depend on memory mode or on operand combinations in  the insn.    The default version of this target hook returns always false.
+@end deftypefn
+
 @node Old Constraints
 @section Obsolete Macros for Defining Constraints
 @cindex defining constraints, obsolete method
Index: target.def
===================================================================
--- target.def	(revision 186357)
+++ target.def	(working copy)
@@ -2300,6 +2300,18 @@ DEFHOOK
  int, (int),
  default_register_bank)
 
+/* Return true if maximal address displacement can be different.  */
+DEFHOOK
+(different_addr_displacement_p,
+ "A target hook which returns true if an address with the same structure\
+  can have different maximal legitimate displacement.  For example, the\
+  displacement can depend on memory mode or on operand combinations in\
+  the insn.\
+  \
+  The default version of this target hook returns always false.",
+ bool, (void),
+ default_different_addr_displacement_p)
+
 /* Return the class for a secondary reload, and fill in extra information.  */
 DEFHOOK
 (secondary_reload,
Index: lra-spills.c
===================================================================
--- lra-spills.c	(revision 186357)
+++ lra-spills.c	(working copy)
@@ -445,8 +445,8 @@ spill_pseudos (void)
 		       "Changing spilled pseudos to memory in insn #%u\n",
 		       INSN_UID (insn));
 	    lra_push_insn (insn);
-	    if (lra_reg_spill_p)
-	      lra_set_used_insn_alternative_by_uid (INSN_UID (insn), -1);
+	    if (lra_reg_spill_p || targetm.different_addr_displacement_p ())
+	      lra_set_used_insn_alternative (insn, -1);
 	  }
       bitmap_and_compl_into (DF_LR_IN (bb), &spilled_pseudos);
       bitmap_and_compl_into (DF_LR_OUT (bb), &spilled_pseudos);
Index: targhooks.c
===================================================================
--- targhooks.c	(revision 186357)
+++ targhooks.c	(working copy)
@@ -840,6 +840,12 @@ default_register_bank (int hard_regno AT
   return 0;
 }
 
+extern bool
+default_different_addr_displacement_p (void)
+{
+  return false;
+}
+
 reg_class_t
 default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED,
 			  reg_class_t reload_class_i ATTRIBUTE_UNUSED,
Index: targhooks.h
===================================================================
--- targhooks.h	(revision 186357)
+++ targhooks.h	(working copy)
@@ -125,6 +125,7 @@ extern void default_trampoline_init (rtx
 extern int default_return_pops_args (tree, tree, int);
 extern reg_class_t default_branch_target_register_class (void);
 extern int default_register_bank (int);
+extern bool default_different_addr_displacement_p (void);
 extern reg_class_t default_secondary_reload (bool, rtx, reg_class_t,
 					     enum machine_mode,
 					     secondary_reload_info *);
Index: rtlanal.c
===================================================================
--- rtlanal.c	(revision 186357)
+++ rtlanal.c	(working copy)
@@ -3497,7 +3497,8 @@ simplify_subreg_regno (unsigned int xreg
     return -1;
 
   if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-      && xregno == ARG_POINTER_REGNUM)
+      && xregno == ARG_POINTER_REGNUM
+      && ! lra_in_progress)
     return -1;
 
   if (xregno == STACK_POINTER_REGNUM
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c	(revision 186357)
+++ config/pa/pa.c	(working copy)
@@ -188,6 +188,7 @@ static enum machine_mode pa_c_mode_for_s
 static section *pa_function_section (tree, enum node_frequency, bool, bool);
 static bool pa_cannot_force_const_mem (enum machine_mode, rtx);
 static bool pa_legitimate_constant_p (enum machine_mode, rtx);
+static bool pa_different_addr_displacement_p (void);
 
 /* The following extra sections are only used for SOM.  */
 static GTY(()) section *som_readonly_data_section;
@@ -384,6 +385,9 @@ static size_t n_deferred_plabels = 0;
 #undef TARGET_LEGITIMATE_CONSTANT_P
 #define TARGET_LEGITIMATE_CONSTANT_P pa_legitimate_constant_p
 
+#undef TARGET_DIFFERENT_ADDR_DISPLACEMENT_P
+#define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P pa_different_addr_displacement_p
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Parse the -mfixed-range= option string.  */
@@ -5848,6 +5852,9 @@ pa_secondary_reload (bool in_p, rtx x, r
   int regno;
   enum reg_class rclass = (enum reg_class) rclass_i;
 
+  if (lra_in_progress)
+    return NO_REGS;
+
   /* Handle the easy stuff first.  */
   if (rclass == R1_REGS)
     return NO_REGS;
@@ -10338,4 +10345,12 @@ pa_legitimate_constant_p (enum machine_m
   return true;
 }
 
+/* Implement TARGET_DIFFERENT_ADDR_DISPLACEMENT_P.  */
+
+static bool
+pa_different_addr_displacement_p (void)
+{
+  return true;
+}
+
 #include "gt-pa.h"
