Index: lra-assigns.c
===================================================================
--- lra-assigns.c	(revision 184177)
+++ lra-assigns.c	(working copy)
@@ -935,10 +935,10 @@ setup_live_pseudos_and_spill_after_risky
    pseudos to the connected pseudos.  We need this because inheritance
    pseudos are allocated after reload pseudos in the thread and when
    we assign a hard register to a reload pseudo we don't know yet that
-   the connected inheritance pseudos can get the same hard
-   register.  */
+   the connected inheritance pseudos can get the same hard register.
+   Add pseudos with changed allocation to bitmap CHANGED_PSEUDOS.  */
 static void
-improve_inheritance (void)
+improve_inheritance (bitmap changed_pseudos)
 {
   unsigned int k;
   int regno, another_regno, hard_regno, another_hard_regno, cost, i, n;
@@ -983,6 +983,7 @@ improve_inheritance (void)
 		assign_hard_regno (hard_regno, another_regno);
 	      else
 		assign_hard_regno (another_hard_regno, another_regno);
+	      bitmap_set_bit (changed_pseudos, another_regno);
 	    }
 	}
     }
@@ -1104,7 +1105,7 @@ assign_by_spills (void)
 	  }
       n = nfails;
     }
-  improve_inheritance ();
+  improve_inheritance (&changed_pseudo_bitmap);
   bitmap_clear (&changed_insns);
   /* We can not assign to inherited pseudos if any its inheritance
      pseudo did not get hard register because undo inheritance pass
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 184524)
+++ lra-constraints.c	(working copy)
@@ -295,7 +295,9 @@ get_reload_reg (enum op_type type, enum 
 
 /* The page contains code to extract memory address parts.  */
 
-/* Info about base and index regs of an address.  */
+/* Info about base and index regs of an address.  In some rare cases,
+   base/index register can be actually memory.  In this case we will
+   reload it.  */
 struct address
 {
   rtx *base_reg_loc;  /* NULL if there is no a base register.  */
@@ -519,6 +521,13 @@ extract_loc_address_regs (bool top_p, en
 				SCRATCH, true, ad);
       break;
 
+      /* We process memory as a register.  That means we flatten
+	 addresses.  In other words, the final code will never
+	 contains memory in an address even if the target supports
+	 such addresses (it is too rare these days).  Memory also can
+	 occur in address as a result some previous transformations
+	 like equivalence substitution.  */
+    case MEM:
     case REG:
       if (context_p)
 	ad->index_reg_loc = loc;
@@ -1228,6 +1237,26 @@ process_addr_reg (rtx *loc, rtx *before,
   enum machine_mode mode;
   bool change_p = false;
 
+  mode = GET_MODE (reg);
+  if (MEM_P (reg))
+    {
+      /* Always reload memory in an address even if the target
+	 supports such addresses.  */
+      new_reg = lra_create_new_reg_with_unique_value (mode, reg, cl, "address");
+      push_to_sequence (*before);
+      lra_emit_move (new_reg, reg);
+      *before = get_insns ();
+      end_sequence ();
+      *loc = new_reg;
+      if (after != NULL)
+	{
+	  push_to_sequence (*after);
+	  lra_emit_move (reg, new_reg);
+	  *after = get_insns ();
+	  end_sequence ();
+	}
+      return true;
+    }
   gcc_assert (REG_P (reg));
   final_regno = regno = REGNO (reg);
   if (regno < FIRST_PSEUDO_REGISTER)
@@ -1257,7 +1286,6 @@ process_addr_reg (rtx *loc, rtx *before,
     }
   if (*loc != reg || ! in_class_p (final_regno, cl, &new_class))
     {
-      mode = GET_MODE (reg);
       reg = *loc;
       if (get_reload_reg (OP_IN, mode, reg, cl, "address", &new_reg))
 	{
@@ -1564,7 +1592,7 @@ process_alt_operands (int only_alternati
 	    }
       
 	  op = no_subreg_operand[nop];
-	  mode = GET_MODE (*curr_id->operand_loc[nop]);
+	  mode = get_op_mode (nop);
 
 	  win = did_match = winreg = offmemok = constmemok = false;
 	  badop = true;
@@ -2474,8 +2502,8 @@ process_address (int nop, rtx *before, r
     {
       if (process_addr_reg (ad.base_reg_loc, before,
 			    (ad.base_modify_p
-			     && find_regno_note (curr_insn, REG_DEAD,
-						 REGNO (*ad.base_reg_loc)) == NULL
+			     && find_reg_note (curr_insn, REG_DEAD,
+					       *ad.base_reg_loc) == NULL
 			     ? after : NULL),
 			    base_reg_class (mode, as, ad.base_outer_code,
 					    ad.index_code)))
bash-4.1$ svn diff --diff-cmd diff -x -up lra*.[ch] 
Index: lra-assigns.c
===================================================================
--- lra-assigns.c	(revision 184177)
+++ lra-assigns.c	(working copy)
@@ -935,10 +935,10 @@ setup_live_pseudos_and_spill_after_risky
    pseudos to the connected pseudos.  We need this because inheritance
    pseudos are allocated after reload pseudos in the thread and when
    we assign a hard register to a reload pseudo we don't know yet that
-   the connected inheritance pseudos can get the same hard
-   register.  */
+   the connected inheritance pseudos can get the same hard register.
+   Add pseudos with changed allocation to bitmap CHANGED_PSEUDOS.  */
 static void
-improve_inheritance (void)
+improve_inheritance (bitmap changed_pseudos)
 {
   unsigned int k;
   int regno, another_regno, hard_regno, another_hard_regno, cost, i, n;
@@ -969,7 +969,11 @@ improve_inheritance (void)
 	    }
 	  else
 	    gcc_unreachable ();
-	  if ((another_hard_regno = reg_renumber[another_regno]) >= 0
+	  /* Don't change reload pseudo allocation.  It might have
+	     this allocation for a purpose (e.g. bound to another
+	     pseudo) and changing it can result in LRA cycling.  */
+	  if (another_regno < lra_constraint_new_regno_start
+	      && (another_hard_regno = reg_renumber[another_regno]) >= 0
 	      && another_hard_regno != hard_regno)
 	    {
 	      if (lra_dump_file != NULL)
@@ -983,6 +987,7 @@ improve_inheritance (void)
 		assign_hard_regno (hard_regno, another_regno);
 	      else
 		assign_hard_regno (another_hard_regno, another_regno);
+	      bitmap_set_bit (changed_pseudos, another_regno);
 	    }
 	}
     }
@@ -1104,7 +1109,7 @@ assign_by_spills (void)
 	  }
       n = nfails;
     }
-  improve_inheritance ();
+  improve_inheritance (&changed_pseudo_bitmap);
   bitmap_clear (&changed_insns);
   /* We can not assign to inherited pseudos if any its inheritance
      pseudo did not get hard register because undo inheritance pass
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 184524)
+++ lra-constraints.c	(working copy)
@@ -295,7 +295,9 @@ get_reload_reg (enum op_type type, enum 
 
 /* The page contains code to extract memory address parts.  */
 
-/* Info about base and index regs of an address.  */
+/* Info about base and index regs of an address.  In some rare cases,
+   base/index register can be actually memory.  In this case we will
+   reload it.  */
 struct address
 {
   rtx *base_reg_loc;  /* NULL if there is no a base register.  */
@@ -519,6 +521,13 @@ extract_loc_address_regs (bool top_p, en
 				SCRATCH, true, ad);
       break;
 
+      /* We process memory as a register.  That means we flatten
+	 addresses.  In other words, the final code will never
+	 contains memory in an address even if the target supports
+	 such addresses (it is too rare these days).  Memory also can
+	 occur in address as a result some previous transformations
+	 like equivalence substitution.  */
+    case MEM:
     case REG:
       if (context_p)
 	ad->index_reg_loc = loc;
@@ -1228,6 +1237,26 @@ process_addr_reg (rtx *loc, rtx *before,
   enum machine_mode mode;
   bool change_p = false;
 
+  mode = GET_MODE (reg);
+  if (MEM_P (reg))
+    {
+      /* Always reload memory in an address even if the target
+	 supports such addresses.  */
+      new_reg = lra_create_new_reg_with_unique_value (mode, reg, cl, "address");
+      push_to_sequence (*before);
+      lra_emit_move (new_reg, reg);
+      *before = get_insns ();
+      end_sequence ();
+      *loc = new_reg;
+      if (after != NULL)
+	{
+	  push_to_sequence (*after);
+	  lra_emit_move (reg, new_reg);
+	  *after = get_insns ();
+	  end_sequence ();
+	}
+      return true;
+    }
   gcc_assert (REG_P (reg));
   final_regno = regno = REGNO (reg);
   if (regno < FIRST_PSEUDO_REGISTER)
@@ -1257,7 +1286,6 @@ process_addr_reg (rtx *loc, rtx *before,
     }
   if (*loc != reg || ! in_class_p (final_regno, cl, &new_class))
     {
-      mode = GET_MODE (reg);
       reg = *loc;
       if (get_reload_reg (OP_IN, mode, reg, cl, "address", &new_reg))
 	{
@@ -1564,7 +1592,7 @@ process_alt_operands (int only_alternati
 	    }
       
 	  op = no_subreg_operand[nop];
-	  mode = GET_MODE (*curr_id->operand_loc[nop]);
+	  mode = get_op_mode (nop);
 
 	  win = did_match = winreg = offmemok = constmemok = false;
 	  badop = true;
@@ -2474,8 +2502,8 @@ process_address (int nop, rtx *before, r
     {
       if (process_addr_reg (ad.base_reg_loc, before,
 			    (ad.base_modify_p
-			     && find_regno_note (curr_insn, REG_DEAD,
-						 REGNO (*ad.base_reg_loc)) == NULL
+			     && find_reg_note (curr_insn, REG_DEAD,
+					       *ad.base_reg_loc) == NULL
 			     ? after : NULL),
 			    base_reg_class (mode, as, ad.base_outer_code,
 					    ad.index_code)))
