Fix checking failure in IPA-SRA
[gcc.git] / gcc / lra-constraints.c
index 4f434e5332ff55cbc3ea54cda2b34c71b42e45f9..80ca1e06e3108f8a90ecbbac95456a3435a31b37 100644 (file)
@@ -1,5 +1,5 @@
 /* Code for RTL transformations to satisfy insn constraints.
-   Copyright (C) 2010-2019 Free Software Foundation, Inc.
+   Copyright (C) 2010-2020 Free Software Foundation, Inc.
    Contributed by Vladimir Makarov <vmakarov@redhat.com>.
 
    This file is part of GCC.
 #include "expr.h"
 #include "cfgrtl.h"
 #include "rtl-error.h"
-#include "params.h"
 #include "lra.h"
 #include "lra-int.h"
 #include "print-rtl.h"
+#include "function-abi.h"
+#include "rtl-iter.h"
 
 /* Value of LRA_CURR_RELOAD_NUM at the beginning of BB of the current
    insn.  Remember that LRA_CURR_RELOAD_NUM is the number of emitted
@@ -235,12 +236,17 @@ get_reg_class (int regno)
    CL.  Use elimination first if REG is a hard register.  If REG is a
    reload pseudo created by this constraints pass, assume that it will
    be allocated a hard register from its allocno class, but allow that
-   class to be narrowed to CL if it is currently a superset of CL.
+   class to be narrowed to CL if it is currently a superset of CL and
+   if either:
+
+   - ALLOW_ALL_RELOAD_CLASS_CHANGES_P is true or
+   - the instruction we're processing is not a reload move.
 
    If NEW_CLASS is nonnull, set *NEW_CLASS to the new allocno class of
    REGNO (reg), or NO_REGS if no change in its class was needed.  */
 static bool
-in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
+in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class,
+           bool allow_all_reload_class_changes_p = false)
 {
   enum reg_class rclass, common_class;
   machine_mode reg_mode;
@@ -265,7 +271,8 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
         typically moves that have many alternatives, and restricting
         reload pseudos for one alternative may lead to situations
         where other reload pseudos are no longer allocatable.  */
-      || (INSN_UID (curr_insn) >= new_insn_uid_start
+      || (!allow_all_reload_class_changes_p
+         && INSN_UID (curr_insn) >= new_insn_uid_start
          && curr_insn_set != NULL
          && ((OBJECT_P (SET_SRC (curr_insn_set))
               && ! CONSTANT_P (SET_SRC (curr_insn_set)))
@@ -388,22 +395,57 @@ address_eliminator::~address_eliminator ()
     *m_index_loc = m_index_reg;
 }
 
-/* Return true if the eliminated form of AD is a legitimate target address.  */
+/* Return true if the eliminated form of AD is a legitimate target address.
+   If OP is a MEM, AD is the address within OP, otherwise OP should be
+   ignored.  CONSTRAINT is one constraint that the operand may need
+   to meet.  */
 static bool
-valid_address_p (struct address_info *ad)
+valid_address_p (rtx op, struct address_info *ad,
+                enum constraint_num constraint)
 {
   address_eliminator eliminator (ad);
+
+  /* Allow a memory OP if it matches CONSTRAINT, even if CONSTRAINT is more
+     forgiving than "m".
+     Need to extract memory from op for special memory constraint,
+     i.e. bcst_mem_operand in i386 backend.  */
+  if (MEM_P (extract_mem_from_operand (op))
+      && (insn_extra_memory_constraint (constraint)
+         || insn_extra_special_memory_constraint (constraint))
+      && constraint_satisfied_p (op, constraint))
+    return true;
+
   return valid_address_p (ad->mode, *ad->outer, ad->as);
 }
 
+/* For special_memory_operand, it could be false for MEM_P (op),
+   i.e. bcst_mem_operand in i386 backend.
+   Extract and return real memory operand or op.  */
+rtx
+extract_mem_from_operand (rtx op)
+{
+  for (rtx x = op;; x = XEXP (x, 0))
+    {
+      if (MEM_P (x))
+       return x;
+      if (GET_RTX_LENGTH (GET_CODE (x)) != 1
+         || GET_RTX_FORMAT (GET_CODE (x))[0] != 'e')
+       break;
+    }
+  return op;
+}
+
 /* Return true if the eliminated form of memory reference OP satisfies
    extra (special) memory constraint CONSTRAINT.  */
 static bool
 satisfies_memory_constraint_p (rtx op, enum constraint_num constraint)
 {
   struct address_info ad;
+  rtx mem = extract_mem_from_operand (op);
+  if (!MEM_P (mem))
+    return false;
 
-  decompose_mem_address (&ad, op);
+  decompose_mem_address (&ad, mem);
   address_eliminator eliminator (&ad);
   return constraint_satisfied_p (op, constraint);
 }
@@ -557,13 +599,39 @@ init_curr_insn_input_reloads (void)
   curr_insn_input_reloads_num = 0;
 }
 
-/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
-   created input reload pseudo (only if TYPE is not OP_OUT).  Don't
-   reuse pseudo if IN_SUBREG_P is true and the reused pseudo should be
-   wrapped up in SUBREG.  The result pseudo is returned through
-   RESULT_REG.  Return TRUE if we created a new pseudo, FALSE if we
-   reused the already created input reload pseudo.  Use TITLE to
-   describe new registers for debug purposes.  */
+/* The canonical form of an rtx inside a MEM is not necessarily the same as the
+   canonical form of the rtx outside the MEM.  Fix this up in the case that
+   we're reloading an address (and therefore pulling it outside a MEM).  */
+static rtx
+canonicalize_reload_addr (rtx addr)
+{
+  subrtx_var_iterator::array_type array;
+  FOR_EACH_SUBRTX_VAR (iter, array, addr, NONCONST)
+    {
+      rtx x = *iter;
+      if (GET_CODE (x) == MULT && CONST_INT_P (XEXP (x, 1)))
+       {
+         const HOST_WIDE_INT ci = INTVAL (XEXP (x, 1));
+         const int pwr2 = exact_log2 (ci);
+         if (pwr2 > 0)
+           {
+             /* Rewrite this to use a shift instead, which is canonical when
+                outside of a MEM.  */
+             PUT_CODE (x, ASHIFT);
+             XEXP (x, 1) = GEN_INT (pwr2);
+           }
+       }
+    }
+
+  return addr;
+}
+
+/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse an existing
+   reload pseudo.  Don't reuse an existing reload pseudo if IN_SUBREG_P
+   is true and the reused pseudo should be wrapped up in a SUBREG.
+   The result pseudo is returned through RESULT_REG.  Return TRUE if we
+   created a new pseudo, FALSE if we reused an existing reload pseudo.
+   Use TITLE to describe new registers for debug purposes.  */
 static bool
 get_reload_reg (enum op_type type, machine_mode mode, rtx original,
                enum reg_class rclass, bool in_subreg_p,
@@ -575,6 +643,35 @@ get_reload_reg (enum op_type type, machine_mode mode, rtx original,
 
   if (type == OP_OUT)
     {
+      /* Output reload registers tend to start out with a conservative
+        choice of register class.  Usually this is ALL_REGS, although
+        a target might narrow it (for performance reasons) through
+        targetm.preferred_reload_class.  It's therefore quite common
+        for a reload instruction to require a more restrictive class
+        than the class that was originally assigned to the reload register.
+
+        In these situations, it's more efficient to refine the choice
+        of register class rather than create a second reload register.
+        This also helps to avoid cycling for registers that are only
+        used by reload instructions.  */
+      if (REG_P (original)
+         && (int) REGNO (original) >= new_regno_start
+         && INSN_UID (curr_insn) >= new_insn_uid_start
+         && in_class_p (original, rclass, &new_class, true))
+       {
+         unsigned int regno = REGNO (original);
+         if (lra_dump_file != NULL)
+           {
+             fprintf (lra_dump_file, "  Reuse r%d for output ", regno);
+             dump_value_slim (lra_dump_file, original, 1);
+           }
+         if (new_class != lra_get_allocno_class (regno))
+           lra_change_class (regno, new_class, ", change to", false);
+         if (lra_dump_file != NULL)
+           fprintf (lra_dump_file, "\n");
+         *result_reg = original;
+         return false;
+       }
       *result_reg
        = lra_create_new_reg_with_unique_value (mode, original, rclass, title);
       return true;
@@ -1041,12 +1138,15 @@ match_reload (signed char out, signed char *ins, signed char *outs,
   curr_insn_input_reloads[curr_insn_input_reloads_num].match_p = true;
   curr_insn_input_reloads[curr_insn_input_reloads_num++].reg = new_in_reg;
   for (i = 0; (in = ins[i]) >= 0; i++)
-    {
-      lra_assert
-       (GET_MODE (*curr_id->operand_loc[in]) == VOIDmode
-        || GET_MODE (new_in_reg) == GET_MODE (*curr_id->operand_loc[in]));
+    if (GET_MODE (*curr_id->operand_loc[in]) == VOIDmode
+       || GET_MODE (new_in_reg) == GET_MODE (*curr_id->operand_loc[in]))
       *curr_id->operand_loc[in] = new_in_reg;
-    }
+    else
+      {
+       lra_assert
+         (GET_MODE (new_out_reg) == GET_MODE (*curr_id->operand_loc[in]));
+       *curr_id->operand_loc[in] = new_out_reg;
+      }
   lra_update_dups (curr_id, ins);
   if (out < 0)
     return;
@@ -1054,7 +1154,14 @@ match_reload (signed char out, signed char *ins, signed char *outs,
   narrow_reload_pseudo_class (out_rtx, goal_class);
   if (find_reg_note (curr_insn, REG_UNUSED, out_rtx) == NULL_RTX)
     {
+      reg = SUBREG_P (out_rtx) ? SUBREG_REG (out_rtx) : out_rtx;
       start_sequence ();
+      /* If we had strict_low_part, use it also in reload to keep other
+        parts unchanged but do it only for regs as strict_low_part
+        has no sense for memory and probably there is no insn pattern
+        to match the reload insn in memory case.  */
+      if (out >= 0 && curr_static_id->operand[out].strict_low && REG_P (reg))
+       out_rtx = gen_rtx_STRICT_LOW_PART (VOIDmode, out_rtx);
       lra_emit_move (out_rtx, copy_rtx (new_out_reg));
       emit_insn (*after);
       *after = get_insns ();
@@ -1473,7 +1580,7 @@ static bool process_address (int, bool, rtx_insn **, rtx_insn **);
 static bool
 simplify_operand_subreg (int nop, machine_mode reg_mode)
 {
-  int hard_regno;
+  int hard_regno, inner_hard_regno;
   rtx_insn *before, *after;
   machine_mode mode, innermode;
   rtx reg, new_reg;
@@ -1497,10 +1604,11 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
       alter_subreg (curr_id->operand_loc[nop], false);
       rtx subst = *curr_id->operand_loc[nop];
       lra_assert (MEM_P (subst));
-
+      const bool addr_is_valid = valid_address_p (GET_MODE (subst),
+                                                 XEXP (subst, 0),
+                                                 MEM_ADDR_SPACE (subst));
       if (!addr_was_valid
-         || valid_address_p (GET_MODE (subst), XEXP (subst, 0),
-                             MEM_ADDR_SPACE (subst))
+         || addr_is_valid
          || ((get_constraint_type (lookup_constraint
                                    (curr_static_id->operand[nop].constraint))
               != CT_SPECIAL_MEMORY)
@@ -1529,12 +1637,20 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
             data into a register when the inner is narrower than outer or
             missing important data from memory when the inner is wider than
             outer.  This rule only applies to modes that are no wider than
-            a word.  */
-         if (!(maybe_ne (GET_MODE_PRECISION (mode),
-                         GET_MODE_PRECISION (innermode))
-               && known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD)
-               && known_le (GET_MODE_SIZE (innermode), UNITS_PER_WORD)
-               && WORD_REGISTER_OPERATIONS)
+            a word.
+
+            If valid memory becomes invalid after subreg elimination
+            and address might be different we still have to reload
+            memory.
+         */
+         if ((! addr_was_valid
+              || addr_is_valid
+              || known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (innermode)))
+             && !(maybe_ne (GET_MODE_PRECISION (mode),
+                            GET_MODE_PRECISION (innermode))
+                  && known_le (GET_MODE_SIZE (mode), UNITS_PER_WORD)
+                  && known_le (GET_MODE_SIZE (innermode), UNITS_PER_WORD)
+                  && WORD_REGISTER_OPERATIONS)
              && (!(MEM_ALIGN (subst) < GET_MODE_ALIGNMENT (mode)
                    && targetm.slow_unaligned_access (mode, MEM_ALIGN (subst)))
                  || (MEM_ALIGN (reg) < GET_MODE_ALIGNMENT (innermode)
@@ -1553,7 +1669,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
          enum reg_class rclass
            = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
          if (get_reload_reg (curr_static_id->operand[nop].type, innermode,
-                             reg, rclass, TRUE, "slow mem", &new_reg))
+                             reg, rclass, TRUE, "slow/invalid mem", &new_reg))
            {
              bool insert_before, insert_after;
              bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg));
@@ -1572,7 +1688,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
          rclass
            = (enum reg_class) targetm.preferred_reload_class (reg, ALL_REGS);
          if (get_reload_reg (curr_static_id->operand[nop].type, mode, reg,
-                             rclass, TRUE, "slow mem", &new_reg))
+                             rclass, TRUE, "slow/invalid mem", &new_reg))
            {
              bool insert_before, insert_after;
              bitmap_set_bit (&lra_subreg_reload_pseudos, REGNO (new_reg));
@@ -1585,7 +1701,7 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
            }
          *curr_id->operand_loc[nop] = new_reg;
          lra_process_new_insns (curr_insn, before, after,
-                                "Inserting slow mem reload");
+                                "Inserting slow/invalid mem reload");
          return true;
        }
 
@@ -1710,15 +1826,19 @@ simplify_operand_subreg (int nop, machine_mode reg_mode)
      for the new uses.  */
   else if (REG_P (reg)
           && REGNO (reg) >= FIRST_PSEUDO_REGISTER
-          && (hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
-          && (hard_regno_nregs (hard_regno, innermode)
-              < hard_regno_nregs (hard_regno, mode))
-          && (regclass = lra_get_allocno_class (REGNO (reg)))
-          && (type != OP_IN
-              || !in_hard_reg_set_p (reg_class_contents[regclass],
-                                     mode, hard_regno)
-              || overlaps_hard_reg_set_p (lra_no_alloc_regs,
-                                          mode, hard_regno)))
+          && paradoxical_subreg_p (operand)
+          && (inner_hard_regno = lra_get_regno_hard_regno (REGNO (reg))) >= 0
+          && ((hard_regno
+               = simplify_subreg_regno (inner_hard_regno, innermode,
+                                        SUBREG_BYTE (operand), mode)) < 0
+              || ((hard_regno_nregs (inner_hard_regno, innermode)
+                   < hard_regno_nregs (hard_regno, mode))
+                  && (regclass = lra_get_allocno_class (REGNO (reg)))
+                  && (type != OP_IN
+                      || !in_hard_reg_set_p (reg_class_contents[regclass],
+                                             mode, hard_regno)
+                      || overlaps_hard_reg_set_p (lra_no_alloc_regs,
+                                                  mode, hard_regno)))))
     {
       /* The class will be defined later in curr_insn_transform.  */
       enum reg_class rclass
@@ -1761,14 +1881,24 @@ uses_hard_regs_p (rtx x, HARD_REG_SET set)
     return false;
   code = GET_CODE (x);
   mode = GET_MODE (x);
+
   if (code == SUBREG)
     {
+      /* For all SUBREGs we want to check whether the full multi-register
+        overlaps the set.  For normal SUBREGs this means 'get_hard_regno' of
+        the inner register, for paradoxical SUBREGs this means the
+        'get_hard_regno' of the full SUBREG and for complete SUBREGs either is
+        fine.  Use the wider mode for all cases.  */
+      rtx subreg = SUBREG_REG (x);
       mode = wider_subreg_mode (x);
-      x = SUBREG_REG (x);
-      code = GET_CODE (x);
+      if (mode == GET_MODE (subreg))
+       {
+         x = subreg;
+         code = GET_CODE (x);
+       }
     }
 
-  if (REG_P (x))
+  if (REG_P (x) || SUBREG_P (x))
     {
       x_hard_regno = get_hard_regno (x, true);
       return (x_hard_regno >= 0
@@ -1835,8 +1965,7 @@ prohibited_class_reg_set_mode_p (enum reg_class rclass,
   HARD_REG_SET temp;
   
   lra_assert (hard_reg_set_subset_p (reg_class_contents[rclass], set));
-  COPY_HARD_REG_SET (temp, set);
-  AND_COMPL_HARD_REG_SET (temp, lra_no_alloc_regs);
+  temp = set & ~lra_no_alloc_regs;
   return (hard_reg_set_subset_p
          (temp, ira_prohibited_class_mode_regs[rclass][mode]));
 }
@@ -1847,11 +1976,12 @@ prohibited_class_reg_set_mode_p (enum reg_class rclass,
    alternative.  */
 static unsigned int curr_small_class_check = 0;
 
-/* Update number of used inputs of class OP_CLASS for operand NOP.
-   Return true if we have more such class operands than the number of
-   available regs.  */
+/* Update number of used inputs of class OP_CLASS for operand NOP
+   of alternative NALT.  Return true if we have more such class operands
+   than the number of available regs.  */
 static bool
-update_and_check_small_class_inputs (int nop, enum reg_class op_class)
+update_and_check_small_class_inputs (int nop, int nalt,
+                                    enum reg_class op_class)
 {
   static unsigned int small_class_check[LIM_REG_CLASSES];
   static int small_class_input_nums[LIM_REG_CLASSES];
@@ -1862,7 +1992,7 @@ update_and_check_small_class_inputs (int nop, enum reg_class op_class)
       && hard_reg_set_intersect_p (reg_class_contents[op_class],
                                   ira_no_alloc_regs)
       && (curr_static_id->operand[nop].type != OP_OUT
-         || curr_static_id->operand[nop].early_clobber))
+         || TEST_BIT (curr_static_id->operand[nop].early_clobber_alts, nalt)))
     {
       if (small_class_check[op_class] == curr_small_class_check)
        small_class_input_nums[op_class]++;
@@ -2131,7 +2261,8 @@ process_alt_operands (int only_alternative)
                        /* We should reject matching of an early
                           clobber operand if the matching operand is
                           not dying in the insn.  */
-                       if (! curr_static_id->operand[m].early_clobber
+                       if (!TEST_BIT (curr_static_id->operand[m]
+                                      .early_clobber_alts, nalt)
                            || operand_reg[nop] == NULL_RTX
                            || (find_regno_note (curr_insn, REG_DEAD,
                                                 REGNO (op))
@@ -2152,9 +2283,18 @@ process_alt_operands (int only_alternative)
                      }
                    else
                      {
+                       /* If the operands do not match and one
+                          operand is INOUT, we can not match them.
+                          Try other possibilities, e.g. other
+                          alternatives or commutative operand
+                          exchange.  */
+                       if (curr_static_id->operand[nop].type == OP_INOUT
+                           || curr_static_id->operand[m].type == OP_INOUT)
+                         break;
                        /* Operands don't match.  If the operands are
-                          different user defined explicit hard registers,
-                          then we cannot make them match.  */
+                          different user defined explicit hard
+                          registers, then we cannot make them match
+                          when one is early clobber operand.  */
                        if ((REG_P (*curr_id->operand_loc[nop])
                             || SUBREG_P (*curr_id->operand_loc[nop]))
                            && (REG_P (*curr_id->operand_loc[m])
@@ -2173,9 +2313,17 @@ process_alt_operands (int only_alternative)
                                && REG_P (m_reg)
                                && HARD_REGISTER_P (m_reg)
                                && REG_USERVAR_P (m_reg))
-                             break;
+                             {
+                               int i;
+                               
+                               for (i = 0; i < early_clobbered_regs_num; i++)
+                                 if (m == early_clobbered_nops[i])
+                                   break;
+                               if (i < early_clobbered_regs_num
+                                   || early_clobber_p)
+                                 break;
+                             }
                          }
-
                        /* Both operands must allow a reload register,
                           otherwise we cannot make them match.  */
                        if (curr_alt[m] == NO_REGS)
@@ -2198,7 +2346,8 @@ process_alt_operands (int only_alternative)
                           it results in less hard regs required for
                           the insn than a non-matching earlyclobber
                           alternative.  */
-                       if (curr_static_id->operand[m].early_clobber)
+                       if (TEST_BIT (curr_static_id->operand[m]
+                                     .early_clobber_alts, nalt))
                          {
                            if (lra_dump_file != NULL)
                              fprintf
@@ -2249,7 +2398,7 @@ process_alt_operands (int only_alternative)
                       reloads. */
                    badop = false;
                    this_alternative = curr_alt[m];
-                   COPY_HARD_REG_SET (this_alternative_set, curr_alt_set[m]);
+                   this_alternative_set = curr_alt_set[m];
                    winreg = this_alternative != NO_REGS;
                    break;
                  }
@@ -2321,8 +2470,7 @@ process_alt_operands (int only_alternative)
                      break;
 
                    case CT_SPECIAL_MEMORY:
-                     if (MEM_P (op)
-                         && satisfies_memory_constraint_p (op, cn))
+                     if (satisfies_memory_constraint_p (op, cn))
                        win = true;
                      else if (spilled_pseudo_p (op))
                        win = true;
@@ -2331,18 +2479,16 @@ process_alt_operands (int only_alternative)
                  break;
 
                reg:
+                 if (mode == BLKmode)
+                   break;
                  this_alternative = reg_class_subunion[this_alternative][cl];
-                 IOR_HARD_REG_SET (this_alternative_set,
-                                   reg_class_contents[cl]);
+                 this_alternative_set |= reg_class_contents[cl];
                  if (costly_p)
                    {
                      this_costly_alternative
                        = reg_class_subunion[this_costly_alternative][cl];
-                     IOR_HARD_REG_SET (this_costly_alternative_set,
-                                       reg_class_contents[cl]);
+                     this_costly_alternative_set |= reg_class_contents[cl];
                    }
-                 if (mode == BLKmode)
-                   break;
                  winreg = true;
                  if (REG_P (op))
                    {
@@ -2362,7 +2508,7 @@ process_alt_operands (int only_alternative)
          while ((p += len), c);
 
          scratch_p = (operand_reg[nop] != NULL_RTX
-                      && lra_former_scratch_p (REGNO (operand_reg[nop])));
+                      && ira_former_scratch_p (REGNO (operand_reg[nop])));
          /* Record which operands fit this alternative.  */
          if (win)
            {
@@ -2476,14 +2622,11 @@ process_alt_operands (int only_alternative)
 
              if (this_alternative != NO_REGS)
                {
-                 HARD_REG_SET available_regs;
-                 
-                 COPY_HARD_REG_SET (available_regs,
-                                    reg_class_contents[this_alternative]);
-                 AND_COMPL_HARD_REG_SET
-                   (available_regs,
-                    ira_prohibited_class_mode_regs[this_alternative][mode]);
-                 AND_COMPL_HARD_REG_SET (available_regs, lra_no_alloc_regs);
+                 HARD_REG_SET available_regs
+                   = (reg_class_contents[this_alternative]
+                      & ~((ira_prohibited_class_mode_regs
+                           [this_alternative][mode])
+                          | lra_no_alloc_regs));
                  if (hard_reg_set_empty_p (available_regs))
                    {
                      /* There are no hard regs holding a value of given
@@ -2662,7 +2805,7 @@ process_alt_operands (int only_alternative)
                  if (lra_dump_file != NULL)
                    fprintf (lra_dump_file,
                             "            alt=%d: reload pseudo for op %d "
-                            " cannot hold the mode value -- refuse\n",
+                            "cannot hold the mode value -- refuse\n",
                             nalt, nop);
                  goto fail;
                }
@@ -2676,11 +2819,24 @@ process_alt_operands (int only_alternative)
                          && (targetm.preferred_output_reload_class
                              (op, this_alternative) == NO_REGS))))
                {
-                 if (lra_dump_file != NULL)
-                   fprintf (lra_dump_file,
-                            "            %d Non-prefered reload: reject+=%d\n",
-                            nop, LRA_MAX_REJECT);
-                 reject += LRA_MAX_REJECT;
+                 if (offmemok && REG_P (op))
+                   {
+                     if (lra_dump_file != NULL)
+                       fprintf
+                         (lra_dump_file,
+                          "            %d Spill pseudo into memory: reject+=3\n",
+                          nop);
+                     reject += 3;
+                   }
+                 else
+                   {
+                     if (lra_dump_file != NULL)
+                       fprintf
+                         (lra_dump_file,
+                          "            %d Non-prefered reload: reject+=%d\n",
+                          nop, LRA_MAX_REJECT);
+                     reject += LRA_MAX_REJECT;
+                   }
                }
 
              if (! (MEM_P (op) && offmemok)
@@ -2787,29 +2943,32 @@ process_alt_operands (int only_alternative)
                              (GET_MODE (op), this_alternative, cl)))))
                losers++;
 
-             /* Input reloads can be inherited more often than output
-                reloads can be removed, so penalize output
-                reloads.  */
-             if (!REG_P (op) || curr_static_id->operand[nop].type != OP_IN)
-               {
-                 if (lra_dump_file != NULL)
-                   fprintf
-                     (lra_dump_file,
-                      "            %d Non input pseudo reload: reject++\n",
-                      nop);
-                 reject++;
-               }
-
              if (MEM_P (op) && offmemok)
                addr_losers++;
-             else if (curr_static_id->operand[nop].type == OP_INOUT)
+             else
                {
-                 if (lra_dump_file != NULL)
-                   fprintf
-                     (lra_dump_file,
-                      "            %d Input/Output reload: reject+=%d\n",
-                      nop, LRA_LOSER_COST_FACTOR);
-                 reject += LRA_LOSER_COST_FACTOR;
+                 /* Input reloads can be inherited more often than
+                    output reloads can be removed, so penalize output
+                    reloads.  */
+                 if (!REG_P (op) || curr_static_id->operand[nop].type != OP_IN)
+                   {
+                     if (lra_dump_file != NULL)
+                       fprintf
+                         (lra_dump_file,
+                          "            %d Non input pseudo reload: reject++\n",
+                          nop);
+                     reject++;
+                   }
+
+                 if (curr_static_id->operand[nop].type == OP_INOUT)
+                   {
+                     if (lra_dump_file != NULL)
+                       fprintf
+                         (lra_dump_file,
+                          "            %d Input/Output reload: reject+=%d\n",
+                          nop, LRA_LOSER_COST_FACTOR);
+                     reject += LRA_LOSER_COST_FACTOR;
+                   }
                }
            }
 
@@ -2836,7 +2995,8 @@ process_alt_operands (int only_alternative)
               goto fail;
             }
 
-         if (update_and_check_small_class_inputs (nop, this_alternative))
+         if (update_and_check_small_class_inputs (nop, nalt,
+                                                  this_alternative))
            {
              if (lra_dump_file != NULL)
                fprintf (lra_dump_file,
@@ -2845,7 +3005,7 @@ process_alt_operands (int only_alternative)
              goto fail;
            }
          curr_alt[nop] = this_alternative;
-         COPY_HARD_REG_SET (curr_alt_set[nop], this_alternative_set);
+         curr_alt_set[nop] = this_alternative_set;
          curr_alt_win[nop] = this_alternative_win;
          curr_alt_match_win[nop] = this_alternative_match_win;
          curr_alt_offmemok[nop] = this_alternative_offmemok;
@@ -3270,13 +3430,14 @@ process_address_1 (int nop, bool check_only_p,
   rtx new_reg;
   HOST_WIDE_INT scale;
   rtx op = *curr_id->operand_loc[nop];
+  rtx mem = extract_mem_from_operand (op);
   const char *constraint = curr_static_id->operand[nop].constraint;
   enum constraint_num cn = lookup_constraint (constraint);
   bool change_p = false;
 
-  if (MEM_P (op)
-      && GET_MODE (op) == BLKmode
-      && GET_CODE (XEXP (op, 0)) == SCRATCH)
+  if (MEM_P (mem)
+      && GET_MODE (mem) == BLKmode
+      && GET_CODE (XEXP (mem, 0)) == SCRATCH)
     return false;
 
   if (insn_extra_address_constraint (cn)
@@ -3289,12 +3450,14 @@ process_address_1 (int nop, bool check_only_p,
       && curr_static_id->operand[nop].is_address)
     decompose_lea_address (&ad, curr_id->operand_loc[nop]);
   /* Do not attempt to decompose arbitrary addresses generated by combine
-     for asm operands with loose constraints, e.g 'X'.  */
-  else if (MEM_P (op)
+     for asm operands with loose constraints, e.g 'X'.
+     Need to extract memory from op for special memory constraint,
+     i.e. bcst_mem_operand in i386 backend.  */
+  else if (MEM_P (mem)
           && !(INSN_CODE (curr_insn) < 0
                && get_constraint_type (cn) == CT_FIXED_FORM
                && constraint_satisfied_p (op, cn)))
-    decompose_mem_address (&ad, op);
+    decompose_mem_address (&ad, mem);
   else if (GET_CODE (op) == SUBREG
           && MEM_P (SUBREG_REG (op)))
     decompose_mem_address (&ad, SUBREG_REG (op));
@@ -3360,7 +3523,7 @@ process_address_1 (int nop, bool check_only_p,
 
      All these cases involve a non-autoinc address, so there is no
      point revalidating other types.  */
-  if (ad.autoinc_p || valid_address_p (&ad))
+  if (ad.autoinc_p || valid_address_p (op, &ad, cn))
     return change_p;
 
   /* Any index existed before LRA started, so we can assume that the
@@ -3389,7 +3552,7 @@ process_address_1 (int nop, bool check_only_p,
              if (code >= 0)
                {
                  *ad.inner = gen_rtx_LO_SUM (Pmode, new_reg, addr);
-                 if (! valid_address_p (ad.mode, *ad.outer, ad.as))
+                 if (!valid_address_p (op, &ad, cn))
                    {
                      /* Try to put lo_sum into register.  */
                      insn = emit_insn (gen_rtx_SET
@@ -3399,7 +3562,7 @@ process_address_1 (int nop, bool check_only_p,
                      if (code >= 0)
                        {
                          *ad.inner = new_reg;
-                         if (! valid_address_p (ad.mode, *ad.outer, ad.as))
+                         if (!valid_address_p (op, &ad, cn))
                            {
                              *ad.inner = addr;
                              code = -1;
@@ -3494,7 +3657,7 @@ process_address_1 (int nop, bool check_only_p,
          && CONSTANT_P (XEXP (SET_SRC (set), 1)))
        {
          *ad.inner = SET_SRC (set);
-         if (valid_address_p (ad.mode, *ad.outer, ad.as))
+         if (valid_address_p (op, &ad, cn))
            {
              *ad.base_term = XEXP (SET_SRC (set), 0);
              *ad.disp_term = XEXP (SET_SRC (set), 1);
@@ -3791,10 +3954,10 @@ curr_insn_transform (bool check_only_p)
   no_input_reloads_p = no_output_reloads_p = false;
   goal_alt_number = -1;
   change_p = sec_mem_p = false;
-  /* JUMP_INSNs and CALL_INSNs are not allowed to have any output
-     reloads; neither are insns that SET cc0.  Insns that use CC0 are
-     not allowed to have any input reloads.  */
-  if (JUMP_P (curr_insn) || CALL_P (curr_insn))
+  /* CALL_INSNs are not allowed to have any output reloads; neither
+     are insns that SET cc0.  Insns that use CC0 are not allowed to
+     have any input reloads.  */
+  if (CALL_P (curr_insn))
     no_output_reloads_p = true;
 
   if (HAVE_cc0 && reg_referenced_p (cc0_rtx, PATTERN (curr_insn)))
@@ -3941,9 +4104,18 @@ curr_insn_transform (bool check_only_p)
       error_for_asm (curr_insn,
                     "inconsistent operand constraints in an %<asm%>");
       lra_asm_error_p = true;
-      /* Avoid further trouble with this insn.  Don't generate use
-        pattern here as we could use the insn SP offset.  */
-      lra_set_insn_deleted (curr_insn);
+      if (! JUMP_P (curr_insn))
+       {
+         /* Avoid further trouble with this insn.  Don't generate use
+            pattern here as we could use the insn SP offset.  */
+         lra_set_insn_deleted (curr_insn);
+       }
+      else
+       {
+         lra_invalidate_insn_data (curr_insn);
+         ira_nullify_asm_goto (curr_insn);
+         lra_update_insn_regno_info (curr_insn);
+       }
       return true;
     }
 
@@ -4197,8 +4369,8 @@ curr_insn_transform (bool check_only_p)
                 assigment pass and the scratch pseudo will be
                 spilled.  Spilled scratch pseudos are transformed
                 back to scratches at the LRA end.  */
-             && lra_former_scratch_operand_p (curr_insn, i)
-             && lra_former_scratch_p (REGNO (op)))
+             && ira_former_scratch_operand_p (curr_insn, i)
+             && ira_former_scratch_p (REGNO (op)))
            {
              int regno = REGNO (op);
              lra_change_class (regno, NO_REGS, "      Change to", true);
@@ -4219,7 +4391,7 @@ curr_insn_transform (bool check_only_p)
              && goal_alt[i] != NO_REGS && REG_P (op)
              && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
              && regno < new_regno_start
-             && ! lra_former_scratch_p (regno)
+             && ! ira_former_scratch_p (regno)
              && reg_renumber[regno] < 0
              /* Check that the optional reload pseudo will be able to
                 hold given mode value.  */
@@ -4234,6 +4406,32 @@ curr_insn_transform (bool check_only_p)
                           || MEM_P (SET_DEST (curr_insn_set))
                           || GET_CODE (SET_DEST (curr_insn_set)) == SUBREG))))
            optional_p = true;
+         else if (goal_alt_matched[i][0] != -1
+                  && curr_static_id->operand[i].type == OP_OUT
+                  && (curr_static_id->operand_alternative
+                      [goal_alt_number * n_operands + i].earlyclobber)
+                  && REG_P (op))
+           {
+             for (j = 0; goal_alt_matched[i][j] != -1; j++)
+               {
+                 rtx op2 = *curr_id->operand_loc[goal_alt_matched[i][j]];
+                 
+                 if (REG_P (op2) && REGNO (op) != REGNO (op2))
+                   break;
+               }
+             if (goal_alt_matched[i][j] != -1)
+               {
+                 /* Generate reloads for different output and matched
+                    input registers.  This is the easiest way to avoid
+                    creation of non-existing register conflicts in
+                    lra-lives.c.  */
+                 match_reload (i, goal_alt_matched[i], outputs, goal_alt[i], &before,
+                               &after, TRUE);
+                 outputs[n_outputs++] = i;
+                 outputs[n_outputs] = -1;
+               }
+             continue;
+           }
          else
            continue;
        }
@@ -4264,12 +4462,19 @@ curr_insn_transform (bool check_only_p)
            {
              rtx addr = *loc;
              enum rtx_code code = GET_CODE (addr);
-             
+             bool align_p = false;
+
              if (code == AND && CONST_INT_P (XEXP (addr, 1)))
-               /* (and ... (const_int -X)) is used to align to X bytes.  */
-               addr = XEXP (*loc, 0);
+               {
+                 /* (and ... (const_int -X)) is used to align to X bytes.  */
+                 align_p = true;
+                 addr = XEXP (*loc, 0);
+               }
+             else
+               addr = canonicalize_reload_addr (addr);
+
              lra_emit_move (new_reg, addr);
-             if (addr != *loc)
+             if (align_p)
                emit_move_insn (new_reg, gen_rtx_AND (GET_MODE (new_reg), new_reg, XEXP (*loc, 1)));
            }
          before = get_insns ();
@@ -4491,7 +4696,7 @@ contains_reg_p (rtx x, bool hard_reg_p, bool spilled_p)
            regno = lra_get_regno_hard_regno (regno);
          if (regno < 0)
            return false;
-         COMPL_HARD_REG_SET (alloc_regs, lra_no_alloc_regs);
+         alloc_regs = ~lra_no_alloc_regs;
          return overlaps_hard_reg_set_p (alloc_regs, GET_MODE (x), regno);
        }
       else
@@ -4589,11 +4794,14 @@ loc_equivalence_callback (rtx loc, const_rtx, void *data)
 /* The current iteration number of this LRA pass.  */
 int lra_constraint_iter;
 
-/* True if we substituted equiv which needs checking register
-   allocation correctness because the equivalent value contains
-   allocatable hard registers or when we restore multi-register
-   pseudo.  */
-bool lra_risky_transformations_p;
+/* True if we should during assignment sub-pass check assignment
+   correctness for all pseudos and spill some of them to correct
+   conflicts.  It can be necessary when we substitute equiv which
+   needs checking register allocation correctness because the
+   equivalent value contains allocatable hard registers, or when we
+   restore multi-register pseudo, or when we change the insn code and
+   its operand became INOUT operand when it was IN one before.  */
+bool check_and_force_assignment_correctness_p;
 
 /* Return true if REGNO is referenced in more than one block.  */
 static bool
@@ -4606,12 +4814,12 @@ multi_block_pseudo_p (int regno)
   if (regno < FIRST_PSEUDO_REGISTER)
     return false;
 
-    EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi)
-      if (bb == NULL)
-       bb = BLOCK_FOR_INSN (lra_insn_recog_data[uid]->insn);
-      else if (BLOCK_FOR_INSN (lra_insn_recog_data[uid]->insn) != bb)
-       return true;
-    return false;
+  EXECUTE_IF_SET_IN_BITMAP (&lra_reg_info[regno].insn_bitmap, 0, uid, bi)
+    if (bb == NULL)
+      bb = BLOCK_FOR_INSN (lra_insn_recog_data[uid]->insn);
+    else if (BLOCK_FOR_INSN (lra_insn_recog_data[uid]->insn) != bb)
+      return true;
+  return false;
 }
 
 /* Return true if LIST contains a deleted insn.  */
@@ -4735,12 +4943,14 @@ lra_constraints (bool first_p)
   changed_p = false;
   if (pic_offset_table_rtx
       && REGNO (pic_offset_table_rtx) >= FIRST_PSEUDO_REGISTER)
-    lra_risky_transformations_p = true;
-  else
+    check_and_force_assignment_correctness_p = true;
+  else if (first_p)
     /* On the first iteration we should check IRA assignment
        correctness.  In rare cases, the assignments can be wrong as
-       early clobbers operands are ignored in IRA.  */
-    lra_risky_transformations_p = first_p;
+       early clobbers operands are ignored in IRA or usages of
+       paradoxical sub-registers are not taken into account by
+       IRA.  */
+    check_and_force_assignment_correctness_p = true;
   new_insn_uid_start = get_max_uid ();
   new_regno_start = first_p ? lra_constraint_new_regno_start : max_reg_num ();
   /* Mark used hard regs for target stack size calulations.  */
@@ -4848,7 +5058,7 @@ lra_constraints (bool first_p)
        }
       if (new_insns_num > MAX_RELOAD_INSNS_NUMBER)
        internal_error
-         ("Max. number of generated reload insns per insn is achieved (%d)\n",
+         ("maximum number of generated reload insns per insn achieved (%d)",
           MAX_RELOAD_INSNS_NUMBER);
       new_insns_num++;
       if (DEBUG_INSN_P (curr_insn))
@@ -4916,7 +5126,7 @@ lra_constraints (bool first_p)
                      dump_insn_slim (lra_dump_file, curr_insn);
                    }
                  if (contains_reg_p (x, true, false))
-                   lra_risky_transformations_p = true;
+                   check_and_force_assignment_correctness_p = true;
                  lra_set_insn_deleted (curr_insn);
                  continue;
                }
@@ -5081,6 +5291,14 @@ static int reloads_num;
 /* Number of calls passed so far in current EBB.  */
 static int calls_num;
 
+/* Index ID is the CALLS_NUM associated the last call we saw with
+   ABI identifier ID.  */
+static int last_call_for_abi[NUM_ABI_IDS];
+
+/* Which registers have been fully or partially clobbered by a call
+   since they were last used.  */
+static HARD_REG_SET full_and_partial_call_clobbers;
+
 /* Current reload pseudo check for validity of elements in
    USAGE_INSNS.         */
 static int curr_usage_insns_check;
@@ -5124,6 +5342,10 @@ setup_next_usage_insn (int regno, rtx insn, int reloads_num, bool after_p)
   usage_insns[regno].reloads_num = reloads_num;
   usage_insns[regno].calls_num = calls_num;
   usage_insns[regno].after_p = after_p;
+  if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0)
+    remove_from_hard_reg_set (&full_and_partial_call_clobbers,
+                             PSEUDO_REGNO_MODE (regno),
+                             reg_renumber[regno]);
 }
 
 /* The function is used to form list REGNO usages which consists of
@@ -5369,15 +5591,19 @@ static inline bool
 need_for_call_save_p (int regno)
 {
   lra_assert (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0);
-  return (usage_insns[regno].calls_num < calls_num
-         && (overlaps_hard_reg_set_p
-             ((flag_ipa_ra &&
-               ! hard_reg_set_empty_p (lra_reg_info[regno].actual_call_used_reg_set))
-              ? lra_reg_info[regno].actual_call_used_reg_set
-              : call_used_reg_set,
-              PSEUDO_REGNO_MODE (regno), reg_renumber[regno])
-             || (targetm.hard_regno_call_part_clobbered
-                 (reg_renumber[regno], PSEUDO_REGNO_MODE (regno)))));
+  if (usage_insns[regno].calls_num < calls_num)
+    {
+      unsigned int abis = 0;
+      for (unsigned int i = 0; i < NUM_ABI_IDS; ++i)
+       if (last_call_for_abi[i] > usage_insns[regno].calls_num)
+         abis |= 1 << i;
+      gcc_assert (abis);
+      if (call_clobbered_in_region_p (abis, full_and_partial_call_clobbers,
+                                     PSEUDO_REGNO_MODE (regno),
+                                     reg_renumber[regno]))
+       return true;
+    }
+  return false;
 }
 
 /* Global registers occurring in the current EBB.  */
@@ -5413,12 +5639,11 @@ need_for_split_p (HARD_REG_SET potential_reload_hard_regs, int regno)
           /* Don't split call clobbered hard regs living through
              calls, otherwise we might have a check problem in the
              assign sub-pass as in the most cases (exception is a
-             situation when lra_risky_transformations_p value is
+             situation when check_and_force_assignment_correctness_p value is
              true) the assign pass assumes that all pseudos living
              through calls are assigned to call saved hard regs.  */
           && (regno >= FIRST_PSEUDO_REGISTER
-              || ! TEST_HARD_REG_BIT (call_used_reg_set, regno)
-              || usage_insns[regno].calls_num == calls_num)
+              || !TEST_HARD_REG_BIT (full_and_partial_call_clobbers, regno))
           /* We need at least 2 reloads to make pseudo splitting
              profitable.  We should provide hard regno splitting in
              any case to solve 1st insn scheduling problem when
@@ -5706,7 +5931,7 @@ split_reg (bool before_p, int original_regno, rtx_insn *insn,
        sub-register levels, LRA do this on pseudos level right now and
        this discrepancy may create allocation conflicts after
        splitting.  */
-    lra_risky_transformations_p = true;
+    check_and_force_assignment_correctness_p = true;
   if (lra_dump_file != NULL)
     fprintf (lra_dump_file,
             "    ))))))))))))))))))))))))))))))))))))))))))))))))\n");
@@ -5814,6 +6039,9 @@ invariant_p (const_rtx x)
   enum rtx_code code;
   int i, j;
 
+  if (side_effects_p (x))
+    return false;
+
   code = GET_CODE (x);
   mode = GET_MODE (x);
   if (code == SUBREG)
@@ -6167,12 +6395,14 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
   curr_usage_insns_check++;
   clear_invariants ();
   reloads_num = calls_num = 0;
+  for (unsigned int i = 0; i < NUM_ABI_IDS; ++i)
+    last_call_for_abi[i] = 0;
+  CLEAR_HARD_REG_SET (full_and_partial_call_clobbers);
   bitmap_clear (&check_only_regs);
   bitmap_clear (&invalid_invariant_regs);
   last_processed_bb = NULL;
   CLEAR_HARD_REG_SET (potential_reload_hard_regs);
-  COPY_HARD_REG_SET (live_hard_regs, eliminable_regset);
-  IOR_HARD_REG_SET (live_hard_regs, lra_no_alloc_regs);
+  live_hard_regs = eliminable_regset | lra_no_alloc_regs;
   /* We don't process new insns generated in the loop. */
   for (curr_insn = tail; curr_insn != PREV_INSN (head); curr_insn = prev_insn)
     {
@@ -6242,8 +6472,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
          else
            setup_next_usage_insn (src_regno, curr_insn, reloads_num, false);
          if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs))
-           IOR_HARD_REG_SET (potential_reload_hard_regs,
-                             reg_class_contents[cl]);
+           potential_reload_hard_regs |= reg_class_contents[cl];
        }
       else if (src_regno < 0
               && dst_regno >= lra_constraint_new_regno_start
@@ -6260,8 +6489,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
          if (process_invariant_for_inheritance (SET_DEST (curr_set), SET_SRC (curr_set)))
            change_p = true;
          if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs))
-           IOR_HARD_REG_SET (potential_reload_hard_regs,
-                             reg_class_contents[cl]);
+           potential_reload_hard_regs |= reg_class_contents[cl];
        }
       else if (src_regno >= lra_constraint_new_regno_start
               && dst_regno < lra_constraint_new_regno_start
@@ -6283,8 +6511,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
          /* Invalidate.  */
          usage_insns[dst_regno].check = 0;
          if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs))
-           IOR_HARD_REG_SET (potential_reload_hard_regs,
-                             reg_class_contents[cl]);
+           potential_reload_hard_regs |= reg_class_contents[cl];
        }
       else if (INSN_P (curr_insn))
        {
@@ -6339,7 +6566,8 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
                      else
                        add_to_hard_reg_set (&s, PSEUDO_REGNO_MODE (dst_regno),
                                             reg_renumber[dst_regno]);
-                     AND_COMPL_HARD_REG_SET (live_hard_regs, s);
+                     live_hard_regs &= ~s;
+                     potential_reload_hard_regs &= ~s;
                    }
                  /* We should invalidate potential inheritance or
                     splitting for the current insn usages to the next
@@ -6383,6 +6611,10 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
              int regno, hard_regno;
 
              calls_num++;
+             function_abi callee_abi = insn_callee_abi (curr_insn);
+             last_call_for_abi[callee_abi.id ()] = calls_num;
+             full_and_partial_call_clobbers
+               |= callee_abi.full_and_partial_reg_clobbers ();
              if ((cheap = find_reg_note (curr_insn,
                                          REG_RETURNED, NULL_RTX)) != NULL_RTX
                  && ((cheap = XEXP (cheap, 0)), true)
@@ -6392,7 +6624,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
                  /* If there are pending saves/restores, the
                     optimization is not worth.  */
                  && usage_insns[regno].calls_num == calls_num - 1
-                 && TEST_HARD_REG_BIT (call_used_reg_set, hard_regno))
+                 && callee_abi.clobbers_reg_p (GET_MODE (cheap), hard_regno))
                {
                  /* Restore the pseudo from the call result as
                     REG_RETURNED note says that the pseudo value is
@@ -6415,6 +6647,9 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
                      /* We don't need to save/restore of the pseudo from
                         this call.      */
                      usage_insns[regno].calls_num = calls_num;
+                     remove_from_hard_reg_set
+                       (&full_and_partial_call_clobbers,
+                        GET_MODE (cheap), hard_regno);
                      bitmap_set_bit (&check_only_regs, regno);
                    }
                }
@@ -6458,7 +6693,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
                                                 before_p, curr_insn, max_uid))
                        {
                          if (reg->subreg_p)
-                           lra_risky_transformations_p = true;
+                           check_and_force_assignment_correctness_p = true;
                          change_p = true;
                          /* Invalidate. */
                          usage_insns[src_regno].check = 0;
@@ -6518,8 +6753,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
              if (ira_class_hard_regs_num[cl] <= max_small_class_regs_num)
                reloads_num++;
              if (hard_reg_set_subset_p (reg_class_contents[cl], live_hard_regs))
-               IOR_HARD_REG_SET (potential_reload_hard_regs,
-                                 reg_class_contents[cl]);
+               potential_reload_hard_regs |= reg_class_contents[cl];
            }
        }
       if (NONDEBUG_INSN_P (curr_insn))
@@ -6592,7 +6826,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail)
    a BB is not greater than the following value, we don't add the BB
    to EBB.  */
 #define EBB_PROBABILITY_CUTOFF \
-  ((REG_BR_PROB_BASE * LRA_INHERITANCE_EBB_PROBABILITY_CUTOFF) / 100)
+  ((REG_BR_PROB_BASE * param_lra_inheritance_ebb_probability_cutoff) / 100)
 
 /* Current number of inheritance/split iteration.  */
 int lra_inheritance_iter;