Index: lra-assigns.c
===================================================================
--- lra-assigns.c	(revision 191029)
+++ lra-assigns.c	(working copy)
@@ -624,7 +624,9 @@ lra_setup_reg_renumber (int regno, int h
 	     regno < lra_constraint_new_regno_start
 	     ? ""
 	     : bitmap_bit_p (&lra_inheritance_pseudos, regno) ? "inheritance "
-	     : bitmap_bit_p (&lra_split_pseudos, regno) ? "split " : "reload ",
+	     : bitmap_bit_p (&lra_split_pseudos, regno) ? "split "
+	     : bitmap_bit_p (&lra_optional_reload_pseudos, regno)
+	     ? "optional reload ": "reload ",
 	     regno, lra_reg_info[regno].freq);
   if (hard_regno >= 0)
     {
@@ -768,7 +770,8 @@ spill_for (int regno, bitmap spilled_pse
 	if ((int) spill_regno >= lra_constraint_new_regno_start
 	    /* ??? */
 	    && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
-	    && ! bitmap_bit_p (&lra_split_pseudos, spill_regno))
+	    && ! bitmap_bit_p (&lra_split_pseudos, spill_regno)
+	    && ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno))
 	  goto fail;
       insn_pseudos_num = 0;
       if (lra_dump_file != NULL)
@@ -889,7 +892,9 @@ spill_for (int regno, bitmap spilled_pse
 		  : bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
 		  ? "inheritance "
 		  : bitmap_bit_p (&lra_split_pseudos, spill_regno)
-		  ? "split " : "reload "),
+		  ? "split "
+		  : bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno)
+		  ? "optional reload " : "reload "),
 		 spill_regno, reg_renumber[spill_regno],
 		 lra_reg_info[spill_regno].freq, regno);
       update_lives (spill_regno, true);
@@ -1081,6 +1086,7 @@ assign_by_spills (void)
   rtx insn;
   basic_block bb;
   bitmap_head changed_insns, do_not_assign_nonreload_pseudos;
+  bitmap_head non_reload_pseudos;
   unsigned int u;
   bitmap_iterator bi;
 
@@ -1101,6 +1107,9 @@ assign_by_spills (void)
     bitmap_initialize (&try_hard_reg_pseudos[i], &reg_obstack);
   curr_pseudo_check = 0;
   bitmap_initialize (&changed_insns, &reg_obstack);
+  bitmap_initialize (&non_reload_pseudos, &reg_obstack);
+  bitmap_ior (&non_reload_pseudos, &lra_inheritance_pseudos, &lra_split_pseudos);
+  bitmap_ior_into (&non_reload_pseudos, &lra_optional_reload_pseudos);
   for (iter = 0; iter <= 1; iter++)
     {
       qsort (sorted_pseudos, n, sizeof (int), reload_pseudo_compare_func);
@@ -1117,13 +1126,11 @@ assign_by_spills (void)
 		     regno_assign_info[regno_assign_info[regno].first].freq);
 	  hard_regno = find_hard_regno_for (regno, &cost, -1);
 	  if (hard_regno < 0
-	      && ! bitmap_bit_p (&lra_inheritance_pseudos, regno)
-	      && ! bitmap_bit_p (&lra_split_pseudos, regno))
+	      && ! bitmap_bit_p (&non_reload_pseudos, regno))
 	    hard_regno = spill_for (regno, &all_spilled_pseudos);
 	  if (hard_regno < 0)
 	    {
-	      if (! bitmap_bit_p (&lra_inheritance_pseudos, regno)
-		  && ! bitmap_bit_p (&lra_split_pseudos, regno))
+	      if (! bitmap_bit_p (&non_reload_pseudos, regno))
 		sorted_pseudos[nfails++] = regno;
 	    }
 	  else
@@ -1166,6 +1173,8 @@ assign_by_spills (void)
 	    for (r = data->regs; r != NULL; r = r->next)
 	      {
 		regno = r->regno;
+		/* We can use inheritance pseudos in original insns
+		   (not reload ones).  */
 		if (regno < lra_constraint_new_regno_start
 		    || bitmap_bit_p (&lra_inheritance_pseudos, regno)
 		    || reg_renumber[regno] < 0)
@@ -1183,6 +1192,7 @@ assign_by_spills (void)
       n = nfails;
     }
   improve_inheritance (&changed_pseudo_bitmap);
+  bitmap_clear (&non_reload_pseudos);
   bitmap_clear (&changed_insns);
   /* We should not assign to original pseudos of inheritance pseudos
      or split pseudos if any its inheritance pseudo did not get hard
@@ -1192,10 +1202,11 @@ assign_by_spills (void)
   bitmap_initialize (&do_not_assign_nonreload_pseudos, &reg_obstack);
   EXECUTE_IF_SET_IN_BITMAP (&lra_inheritance_pseudos, 0, u, bi)
     if ((restore_regno = lra_reg_info[u].restore_regno) >= 0
-	&& ((reg_renumber[u] < 0
-	     && bitmap_bit_p (&lra_inheritance_pseudos, u))
-	    || (reg_renumber[u] >= 0
-		&& bitmap_bit_p (&lra_split_pseudos, u))))
+	&& reg_renumber[u] < 0 && bitmap_bit_p (&lra_inheritance_pseudos, u))
+      bitmap_set_bit (&do_not_assign_nonreload_pseudos, restore_regno);
+  EXECUTE_IF_SET_IN_BITMAP (&lra_split_pseudos, 0, u, bi)
+    if ((restore_regno = lra_reg_info[u].restore_regno) >= 0
+	&& reg_renumber[u] >= 0 && bitmap_bit_p (&lra_split_pseudos, u))
       bitmap_set_bit (&do_not_assign_nonreload_pseudos, restore_regno);
   for (n = 0, i = FIRST_PSEUDO_REGISTER; i < max_reg_num (); i++)
     if (((i < lra_constraint_new_regno_start
@@ -1203,7 +1214,8 @@ assign_by_spills (void)
 	 || (bitmap_bit_p (&lra_inheritance_pseudos, i)
 	     && lra_reg_info[i].restore_regno >= 0)
 	 || (bitmap_bit_p (&lra_split_pseudos, i)
-	     && lra_reg_info[i].restore_regno >= 0))
+	     && lra_reg_info[i].restore_regno >= 0)
+	 || bitmap_bit_p (&lra_optional_reload_pseudos, i))
 	&& reg_renumber[i] < 0 && lra_reg_info[i].nrefs != 0
 	&& regno_allocno_class_array[i] != NO_REGS)
       sorted_pseudos[n++] = i;
Index: lra.c
===================================================================
--- lra.c	(revision 191029)
+++ lra.c	(working copy)
@@ -2153,6 +2153,10 @@ bitmap_head lra_inheritance_pseudos;
 /* Split pseudo regnos before the new spill pass.  */ 
 bitmap_head lra_split_pseudos;
 
+/* Reload pseudo regnos before the new assign pass which still can be
+   spilled after the assinment pass.  */ 
+bitmap_head lra_optional_reload_pseudos;
+
 /* First UID of insns generated before a new spill pass.  */
 int lra_constraint_new_insn_uid_start;
 
@@ -2243,11 +2247,13 @@ lra (FILE *f)
   lra_constraint_new_insn_uid_start = get_max_uid ();
   bitmap_initialize (&lra_inheritance_pseudos, &reg_obstack);
   bitmap_initialize (&lra_split_pseudos, &reg_obstack);
+  bitmap_initialize (&lra_optional_reload_pseudos, &reg_obstack);
   live_p = false;
   for (;;)
     {
       for (;;)
 	{
+	  bitmap_clear (&lra_optional_reload_pseudos);
 	  /* We should try to assign hard registers to scratches even
 	     if there were no RTL transformations in
 	     lra_constraints.  */
Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 191029)
+++ lra-constraints.c	(working copy)
@@ -216,14 +216,16 @@ get_reg_class (int regno)
   return NO_REGS;
 }
 
-/* Return true if REGNO satisfies reg class constraint CL.  For new
-   reload pseudos we should make more accurate class *NEW_CLASS
-   (we set up it if it is not NULL) to satisfy the constraints.
-   Otherwise, set up NEW_CLASS to NO_REGS.  */
+/* Return true if REGNO in REG_MODE satisfies reg class constraint CL.
+   For new reload pseudos we should make more accurate class
+   *NEW_CLASS (we set up it if it is not NULL) to satisfy the
+   constraints.  Otherwise, set up NEW_CLASS to NO_REGS.  */
 static bool
-in_class_p (int regno, enum reg_class cl, enum reg_class *new_class)
+in_class_p (int regno, enum machine_mode reg_mode,
+	    enum reg_class cl, enum reg_class *new_class)
 {
   enum reg_class rclass, common_class;
+  int class_size, hard_regno, nregs, i, j;
 
   if (new_class != NULL)
     *new_class = NO_REGS;
@@ -237,16 +239,33 @@ in_class_p (int regno, enum reg_class cl
 	 impossibility of find registers for several reloads of one
 	 insn.	*/
       || INSN_UID (curr_insn) >= new_insn_uid_start)
-    return (rclass != NO_REGS && ira_class_subset_p[rclass][cl]
-	     && ! hard_reg_set_subset_p (reg_class_contents[cl],
-					 lra_no_alloc_regs));
+    return ((regno >= new_regno_start && rclass == ALL_REGS)
+	    || (rclass != NO_REGS && ira_class_subset_p[rclass][cl]
+		&& ! hard_reg_set_subset_p (reg_class_contents[cl],
+					    lra_no_alloc_regs)));
   else
     {
       common_class = ira_reg_class_subset[rclass][cl];
       if (new_class != NULL)
 	*new_class = common_class;
-      return ! hard_reg_set_subset_p (reg_class_contents[common_class],
-				      lra_no_alloc_regs);
+      if (hard_reg_set_subset_p (reg_class_contents[common_class],
+				 lra_no_alloc_regs))
+	return false;
+      /* Check that there are enough allocatable regs.  */
+      class_size = ira_class_hard_regs_num[common_class];
+      for (i = 0; i < class_size; i++)
+	{
+	  hard_regno = ira_class_hard_regs[common_class][i];
+	  nregs = hard_regno_nregs[hard_regno][reg_mode];
+	  if (nregs == 1)
+	    return true;
+	  for (j = 0; j < nregs; j++)
+	    if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j))
+	      break;
+	  if (j >= nregs)
+	    return true;
+	}
+      return false;
     }
 }
 
@@ -344,7 +363,8 @@ get_reload_reg (enum op_type type, enum
       break;
   if (i >= curr_insn_input_reloads_num
       || ! in_class_p (REGNO (curr_insn_input_reloads[i].reg),
-			rclass, &new_class))
+		       GET_MODE (curr_insn_input_reloads[i].reg),
+		       rclass, &new_class))
     {
       res_p = true;
       *result_reg = lra_create_new_reg (mode, original, rclass, title);
@@ -1396,7 +1416,7 @@ process_addr_reg (rtx *loc, rtx *before,
       *loc = copy_rtx (*loc);
       change_p = true;
     }
-  if (*loc != reg || ! in_class_p (final_regno, cl, &new_class))
+  if (*loc != reg || ! in_class_p (final_regno, GET_MODE (reg), cl, &new_class))
     {
       reg = *loc;
       if (get_reload_reg (OP_IN, mode, reg, cl, "address", &new_reg))
@@ -1476,9 +1496,11 @@ simplify_operand_subreg (int nop, enum m
       enum reg_class rclass
 	= (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
 
-      if (get_reload_reg (type, reg_mode, reg, rclass, "subreg reg", &new_reg)
-	  && (type != OP_OUT
-	      || GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode)))
+      new_reg = lra_create_new_reg_with_unique_value (reg_mode, reg, rclass,
+						      "subreg reg");
+      bitmap_set_bit (&lra_optional_reload_pseudos, REGNO (new_reg));
+      if (type != OP_OUT
+	  || GET_MODE_SIZE (GET_MODE (reg)) > GET_MODE_SIZE (mode))
 	{
 	  push_to_sequence (before);
 	  lra_emit_move (new_reg, reg);
@@ -2104,7 +2126,7 @@ process_alt_operands (int only_alternati
 						mode, hard_regno[nop]))
 			win = true;
 		      else if (hard_regno[nop] < 0
-			       && in_class_p (REGNO (op),
+			       && in_class_p (REGNO (op), GET_MODE (op),
 					      this_alternative, NULL))
 			win = true;
 		    }
@@ -2138,6 +2160,7 @@ process_alt_operands (int only_alternati
 			 conditions.  */
 		      reject++;
 		      if (in_class_p (REGNO (operand_reg[nop]),
+				      GET_MODE (operand_reg[nop]),
 				      this_costly_alternative, NULL))
 			reject++;
 		    }
@@ -2180,7 +2203,7 @@ process_alt_operands (int only_alternati
 		       || ! in_hard_reg_set_p (this_alternative_set,
 					       mode, hard_regno[nop]))
 		      && (hard_regno[nop] >= 0
-			  || ! in_class_p (REGNO (op),
+			  || ! in_class_p (REGNO (op), GET_MODE (op),
 					   this_alternative, NULL))))
 		losers++;
 	      if (operand_reg[nop] != NULL_RTX)
@@ -2330,15 +2353,21 @@ process_alt_operands (int only_alternati
 		   conflict by forcing to use the same pseudo for the
 		   operands hoping that the pseudo gets the same hard
 		   regno as the operands and the reloads are gone.  */
-		curr_alt_win[i] = false;
-		curr_alt_match_win[j] = false;
+		if (*curr_id->operand_loc[i] != *curr_id->operand_loc[j])
+		  {
+		    curr_alt_win[i] = false;
+		    curr_alt_match_win[j] = false;
+		  }
 		continue;
 	      }
 	    else if (curr_alt_matches[i] == j && curr_alt_match_win[i])
 	      {
 		/* See the comment for the previous case.  */
-		curr_alt_win[j] = false;
-		curr_alt_match_win[i] = false;
+		if (*curr_id->operand_loc[i] != *curr_id->operand_loc[j])
+		  {
+		    curr_alt_win[j] = false;
+		    curr_alt_match_win[i] = false;
+		  }
 		continue;
 	      }
 	    else if (uses_hard_regs_p (curr_id->operand_loc[j], temp_set))
@@ -3205,7 +3234,8 @@ curr_insn_transform (void)
 	    
 	if (REG_P (reg) && (regno = REGNO (reg)) >= FIRST_PSEUDO_REGISTER)
 	  {
-	    bool ok_p = in_class_p (regno, goal_alt[i], &new_class);
+	    bool ok_p = in_class_p (regno, GET_MODE (reg),
+				    goal_alt[i], &new_class);
 
 	    if (new_class != NO_REGS && get_reg_class (regno) != new_class)
 	      {
Index: lra-int.h
===================================================================
--- lra-int.h	(revision 191029)
+++ lra-int.h	(working copy)
@@ -289,6 +289,7 @@ extern bool lra_former_scratch_operand_p
 extern int lra_constraint_new_regno_start;
 extern bitmap_head lra_inheritance_pseudos;
 extern bitmap_head lra_split_pseudos;
+extern bitmap_head lra_optional_reload_pseudos;
 extern int lra_constraint_new_insn_uid_start;
 
 /* lra-constraints.c: */
