OSDN Git Service

* reload1.c (move2add_last_cc0): New.
[pf3gnuchains/gcc-fork.git] / gcc / combine.c
index ad56e85..f7c9852 100644 (file)
@@ -139,6 +139,12 @@ static int max_uid_cuid;
 #define UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD(val) \
   (((unsigned HOST_WIDE_INT) (val) << (BITS_PER_WORD - 1)) << 1)
 
+#define nonzero_bits(X, M) \
+  cached_nonzero_bits (X, M, NULL_RTX, VOIDmode, 0)
+
+#define num_sign_bit_copies(X, M) \
+  cached_num_sign_bit_copies (X, M, NULL_RTX, VOIDmode, 0)
+
 /* Maximum register number, which is the size of the tables below.  */
 
 static unsigned int combine_max_regno;
@@ -198,7 +204,7 @@ static basic_block this_basic_block;
 static sbitmap refresh_blocks;
 \f
 /* The next group of arrays allows the recording of the last value assigned
-   to (hard or pseudo) register n.  We use this information to see if a
+   to (hard or pseudo) register n.  We use this information to see if an
    operation being processed is redundant given a prior operation performed
    on the register.  For example, an `and' with a constant is redundant if
    all the zero bits are already known to be turned off.
@@ -371,8 +377,20 @@ static rtx make_field_assignment  PARAMS ((rtx));
 static rtx apply_distributive_law  PARAMS ((rtx));
 static rtx simplify_and_const_int  PARAMS ((rtx, enum machine_mode, rtx,
                                            unsigned HOST_WIDE_INT));
-static unsigned HOST_WIDE_INT nonzero_bits  PARAMS ((rtx, enum machine_mode));
-static unsigned int num_sign_bit_copies  PARAMS ((rtx, enum machine_mode));
+static unsigned HOST_WIDE_INT cached_nonzero_bits
+                               PARAMS ((rtx, enum machine_mode, rtx,
+                                        enum machine_mode,
+                                        unsigned HOST_WIDE_INT));
+static unsigned HOST_WIDE_INT nonzero_bits1
+                               PARAMS ((rtx, enum machine_mode, rtx,
+                                        enum machine_mode,
+                                        unsigned HOST_WIDE_INT));
+static unsigned int cached_num_sign_bit_copies
+                               PARAMS ((rtx, enum machine_mode, rtx,
+                                        enum machine_mode, unsigned int));
+static unsigned int num_sign_bit_copies1
+                               PARAMS ((rtx, enum machine_mode, rtx,
+                                        enum machine_mode, unsigned int));
 static int merge_outer_ops     PARAMS ((enum rtx_code *, HOST_WIDE_INT *,
                                         enum rtx_code, HOST_WIDE_INT,
                                         enum machine_mode, int *));
@@ -1047,8 +1065,6 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
 
   /* Don't eliminate a store in the stack pointer.  */
   if (dest == stack_pointer_rtx
-      /* If we couldn't eliminate a field assignment, we can't combine.  */
-      || GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == STRICT_LOW_PART
       /* Don't combine with an insn that sets a register to itself if it has
         a REG_EQUAL note.  This may be part of a REG_NO_CONFLICT sequence.  */
       || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX))
@@ -1301,46 +1317,16 @@ combinable_i3pat (i3, loc, i2dest, i1dest, i1_not_in_src, pi3dest_killed)
 
   if (GET_CODE (x) == SET)
     {
-      rtx set = expand_field_assignment (x);
+      rtx set = ;
       rtx dest = SET_DEST (set);
       rtx src = SET_SRC (set);
       rtx inner_dest = dest;
 
-#if 0
-      rtx inner_src = src;
-#endif
-
-      SUBST (*loc, set);
-
       while (GET_CODE (inner_dest) == STRICT_LOW_PART
             || GET_CODE (inner_dest) == SUBREG
             || GET_CODE (inner_dest) == ZERO_EXTRACT)
        inner_dest = XEXP (inner_dest, 0);
 
-  /* We probably don't need this any more now that LIMIT_RELOAD_CLASS
-     was added.  */
-#if 0
-      while (GET_CODE (inner_src) == STRICT_LOW_PART
-            || GET_CODE (inner_src) == SUBREG
-            || GET_CODE (inner_src) == ZERO_EXTRACT)
-       inner_src = XEXP (inner_src, 0);
-
-      /* If it is better that two different modes keep two different pseudos,
-        avoid combining them.  This avoids producing the following pattern
-        on a 386:
-         (set (subreg:SI (reg/v:QI 21) 0)
-              (lshiftrt:SI (reg/v:SI 20)
-                  (const_int 24)))
-        If that were made, reload could not handle the pair of
-        reg 20/21, since it would try to get any GENERAL_REGS
-        but some of them don't handle QImode.  */
-
-      if (rtx_equal_p (inner_src, i2dest)
-         && GET_CODE (inner_dest) == REG
-         && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (inner_dest)))
-       return 0;
-#endif
-
       /* Check for the case where I3 modifies its output, as
         discussed above.  */
       if ((inner_dest != dest
@@ -1449,10 +1435,10 @@ cant_combine_insn_p (insn)
   if (! INSN_P (insn))
     return 1;
 
-  /* Never combine loads and stores involving hard regs.  The register
-     allocator can usually handle such reg-reg moves by tying.  If we allow
-     the combiner to make substitutions of hard regs, we risk aborting in
-     reload on machines that have SMALL_REGISTER_CLASSES.
+  /* Never combine loads and stores involving hard regs that are likely
+     to be spilled.  The register allocator can usually handle such
+     reg-reg moves by tying.  If we allow the combiner to make 
+     substitutions of likely-spilled regs, we may abort in reload.
      As an exception, we allow combinations involving fixed regs; these are
      not available to the register allocator so there's no risk involved.  */
 
@@ -1467,9 +1453,11 @@ cant_combine_insn_p (insn)
     dest = SUBREG_REG (dest);
   if (REG_P (src) && REG_P (dest)
       && ((REGNO (src) < FIRST_PSEUDO_REGISTER
-          && ! fixed_regs[REGNO (src)])
+          && ! fixed_regs[REGNO (src)]
+          && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (src))))
          || (REGNO (dest) < FIRST_PSEUDO_REGISTER
-             && ! fixed_regs[REGNO (dest)])))
+             && ! fixed_regs[REGNO (dest)]
+             && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (dest))))))
     return 1;
 
   return 0;
@@ -1671,7 +1659,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
            abort ();
 
          lo &= ~(UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1);
-         lo |= (INTVAL (SET_SRC (PATTERN (i3))) 
+         lo |= (INTVAL (SET_SRC (PATTERN (i3)))
                 & (UWIDE_SHIFT_LEFT_BY_BITS_PER_WORD (1) - 1));
        }
       else if (HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
@@ -2838,7 +2826,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
            || GET_CODE (temp) != BARRIER)
          emit_barrier_after (undobuf.other_insn);
       }
-       
+
     /* An NOOP jump does not need barrier, but it does need cleaning up
        of CFG.  */
     if (GET_CODE (newpat) == SET
@@ -4026,7 +4014,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
          return gen_binary (MINUS, mode, temp, XEXP (XEXP (x, 0), 1));
        }
 
-      /* (neg (mult A B)) becomes (mult (neg A) B).  
+      /* (neg (mult A B)) becomes (mult (neg A) B).
          This works even for floating-point values.  */
       if (GET_CODE (XEXP (x, 0)) == MULT)
        {
@@ -4167,6 +4155,36 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
          && GET_MODE (XEXP (XEXP (x, 0), 0)) == mode)
        return XEXP (XEXP (x, 0), 0);
 
+      /* (float_truncate:SF (float_truncate:DF foo:XF))
+         = (float_truncate:SF foo:XF).
+        This may elliminate double rounding, so it is unsafe.
+
+         (float_truncate:SF (float_extend:XF foo:DF))
+         = (float_truncate:SF foo:DF).
+
+         (float_truncate:DF (float_extend:XF foo:SF))
+         = (float_extend:SF foo:DF).  */
+      if ((GET_CODE (XEXP (x, 0)) == FLOAT_TRUNCATE
+          && flag_unsafe_math_optimizations)
+         || GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND)
+       return simplify_gen_unary (GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0),
+                                                           0)))
+                                  > GET_MODE_SIZE (mode)
+                                  ? FLOAT_TRUNCATE : FLOAT_EXTEND,
+                                  mode,
+                                  XEXP (XEXP (x, 0), 0), mode);
+
+      /*  (float_truncate (float x)) is (float x)  */
+      if (GET_CODE (XEXP (x, 0)) == FLOAT
+         && (flag_unsafe_math_optimizations
+             || ((unsigned)significand_size (GET_MODE (XEXP (x, 0)))
+                 >= (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
+                     - num_sign_bit_copies (XEXP (XEXP (x, 0), 0),
+                                            GET_MODE (XEXP (XEXP (x, 0), 0)))))))
+       return simplify_gen_unary (FLOAT, mode,
+                                  XEXP (XEXP (x, 0), 0),
+                                  GET_MODE (XEXP (XEXP (x, 0), 0)));
+
       /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
         (OP:SF foo:SF) if OP is NEG or ABS.  */
       if ((GET_CODE (XEXP (x, 0)) == ABS
@@ -4183,7 +4201,23 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
          && GET_CODE (SUBREG_REG (XEXP (x, 0))) == FLOAT_TRUNCATE)
        return SUBREG_REG (XEXP (x, 0));
       break;
+    case FLOAT_EXTEND:
+      /*  (float_extend (float_extend x)) is (float_extend x)
 
+         (float_extend (float x)) is (float x) assuming that double
+         rounding can't happen.
+          */
+      if (GET_CODE (XEXP (x, 0)) == FLOAT_EXTEND
+         || (GET_CODE (XEXP (x, 0)) == FLOAT
+             && ((unsigned)significand_size (GET_MODE (XEXP (x, 0)))
+                 >= (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
+                     - num_sign_bit_copies (XEXP (XEXP (x, 0), 0),
+                                            GET_MODE (XEXP (XEXP (x, 0), 0)))))))
+       return simplify_gen_unary (GET_CODE (XEXP (x, 0)), mode,
+                                  XEXP (XEXP (x, 0), 0),
+                                  GET_MODE (XEXP (XEXP (x, 0), 0)));
+
+      break;
 #ifdef HAVE_cc0
     case COMPARE:
       /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
@@ -4224,11 +4258,11 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
     case PLUS:
       /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)).
        */
-      if (GET_CODE (XEXP (x, 0)) == MULT 
+      if (GET_CODE (XEXP (x, 0)) == MULT
          && GET_CODE (XEXP (XEXP (x, 0), 0)) == NEG)
        {
          rtx in1, in2;
-        
+
          in1 = XEXP (XEXP (XEXP (x, 0), 0), 0);
          in2 = XEXP (XEXP (x, 0), 1);
          return gen_binary (MINUS, mode, XEXP (x, 1),
@@ -4343,24 +4377,24 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
 
       /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A).
        */
-      if (GET_CODE (XEXP (x, 1)) == MULT 
+      if (GET_CODE (XEXP (x, 1)) == MULT
          && GET_CODE (XEXP (XEXP (x, 1), 0)) == NEG)
        {
          rtx in1, in2;
-        
+
          in1 = XEXP (XEXP (XEXP (x, 1), 0), 0);
          in2 = XEXP (XEXP (x, 1), 1);
          return gen_binary (PLUS, mode, gen_binary (MULT, mode, in1, in2),
                             XEXP (x, 0));
        }
 
-      /* Canonicalize (minus (neg A) (mult B C)) to 
+      /* Canonicalize (minus (neg A) (mult B C)) to
         (minus (mult (neg B) C) A).  */
-      if (GET_CODE (XEXP (x, 1)) == MULT 
+      if (GET_CODE (XEXP (x, 1)) == MULT
          && GET_CODE (XEXP (x, 0)) == NEG)
        {
          rtx in1, in2;
-        
+
          in1 = simplify_gen_unary (NEG, mode, XEXP (XEXP (x, 1), 0), mode);
          in2 = XEXP (XEXP (x, 1), 1);
          return gen_binary (MINUS, mode, gen_binary (MULT, mode, in1, in2),
@@ -4430,10 +4464,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
         with it.  */
       if (GET_CODE (XEXP (x, 0)) == COMPARE
          || (GET_MODE_CLASS (GET_MODE (XEXP (x, 0))) != MODE_CC
-#ifdef HAVE_cc0
-             && XEXP (x, 0) != cc0_rtx
-#endif
-             ))
+             && ! CC0_P (XEXP (x, 0))))
        {
          rtx op0 = XEXP (x, 0);
          rtx op1 = XEXP (x, 1);
@@ -4908,7 +4939,9 @@ simplify_if_then_else (x)
      neither 1 or -1, but it isn't worth checking for.  */
 
   if ((STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
-      && comparison_p && mode != VOIDmode && ! side_effects_p (x))
+      && comparison_p
+      && GET_MODE_CLASS (mode) == MODE_INT
+      && ! side_effects_p (x))
     {
       rtx t = make_compound_operation (true_rtx, SET);
       rtx f = make_compound_operation (false_rtx, SET);
@@ -5250,7 +5283,7 @@ simplify_set (x)
 #ifdef CANNOT_CHANGE_MODE_CLASS
       && ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
            && REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
-                                        GET_MODE (SUBREG_REG (src)), 
+                                        GET_MODE (SUBREG_REG (src)),
                                         GET_MODE (src)))
 #endif
       && (GET_CODE (dest) == REG
@@ -7297,7 +7330,8 @@ force_to_mode (x, mode, mask, reg, just_select)
              < GET_MODE_BITSIZE (GET_MODE (x)))
          && INTVAL (XEXP (XEXP (x, 0), 1)) < HOST_BITS_PER_WIDE_INT)
        {
-         temp = GEN_INT (mask << INTVAL (XEXP (XEXP (x, 0), 1)));
+         temp = gen_int_mode (mask << INTVAL (XEXP (XEXP (x, 0), 1)),
+                              GET_MODE (x));
          temp = gen_binary (XOR, GET_MODE (x), XEXP (XEXP (x, 0), 0), temp);
          x = gen_binary (LSHIFTRT, GET_MODE (x), temp, XEXP (XEXP (x, 0), 1));
 
@@ -7861,6 +7895,17 @@ make_field_assignment (x)
                       : ((unsigned HOST_WIDE_INT) 1 << len) - 1,
                       dest, 0);
 
+  /* If SRC is masked by an AND that does not make a difference in
+     the value being stored, strip it.  */
+  if (GET_CODE (assign) == ZERO_EXTRACT
+      && GET_CODE (XEXP (assign, 1)) == CONST_INT
+      && INTVAL (XEXP (assign, 1)) < HOST_BITS_PER_WIDE_INT
+      && GET_CODE (src) == AND
+      && GET_CODE (XEXP (src, 1)) == CONST_INT
+      && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (src, 1))
+         == ((unsigned HOST_WIDE_INT) 1 << INTVAL (XEXP (assign, 1))) - 1))
+    src = XEXP (src, 0);
+
   return gen_rtx_SET (VOIDmode, assign, src);
 }
 \f
@@ -8115,12 +8160,62 @@ simplify_and_const_int (x, mode, varop, constop)
   return x;
 }
 \f
+#define nonzero_bits_with_known(X, MODE) \
+  cached_nonzero_bits (X, MODE, known_x, known_mode, known_ret)
+
+/* The function cached_nonzero_bits is a wrapper around nonzero_bits1.
+   It avoids exponential behavior in nonzero_bits1 when X has
+   identical subexpressions on the first or the second level.  */
+
+static unsigned HOST_WIDE_INT
+cached_nonzero_bits (x, mode, known_x, known_mode, known_ret)
+     rtx x;
+     enum machine_mode mode;
+     rtx known_x;
+     enum machine_mode known_mode;
+     unsigned HOST_WIDE_INT known_ret;
+{
+  if (x == known_x && mode == known_mode)
+    return known_ret;
+
+  /* Try to find identical subexpressions.  If found call
+     nonzero_bits1 on X with the subexpressions as KNOWN_X and the
+     precomputed value for the subexpression as KNOWN_RET.  */
+
+  if (GET_RTX_CLASS (GET_CODE (x)) == '2'
+      || GET_RTX_CLASS (GET_CODE (x)) == 'c')
+    {
+      rtx x0 = XEXP (x, 0);
+      rtx x1 = XEXP (x, 1);
+
+      /* Check the first level.  */
+      if (x0 == x1)
+       return nonzero_bits1 (x, mode, x0, mode,
+                             nonzero_bits_with_known (x0, mode));
+
+      /* Check the second level.  */
+      if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
+          || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
+         && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
+       return nonzero_bits1 (x, mode, x1, mode,
+                             nonzero_bits_with_known (x1, mode));
+
+      if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
+          || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
+         && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
+       return nonzero_bits1 (x, mode, x0, mode,
+                        nonzero_bits_with_known (x0, mode));
+    }
+
+  return nonzero_bits1 (x, mode, known_x, known_mode, known_ret);
+}
+
 /* We let num_sign_bit_copies recur into nonzero_bits as that is useful.
    We don't let nonzero_bits recur into num_sign_bit_copies, because that
    is less useful.  We can't allow both, because that results in exponential
    run time recursion.  There is a nullstone testcase that triggered
    this.  This macro avoids accidental uses of num_sign_bit_copies.  */
-#define num_sign_bit_copies()
+#define cached_num_sign_bit_copies()
 
 /* Given an expression, X, compute which bits in X can be nonzero.
    We don't care about bits outside of those defined in MODE.
@@ -8129,9 +8224,12 @@ simplify_and_const_int (x, mode, varop, constop)
    a shift, AND, or zero_extract, we can do better.  */
 
 static unsigned HOST_WIDE_INT
-nonzero_bits (x, mode)
+nonzero_bits1 (x, mode, known_x, known_mode, known_ret)
      rtx x;
      enum machine_mode mode;
+     rtx known_x;
+     enum machine_mode known_mode;
+     unsigned HOST_WIDE_INT known_ret;
 {
   unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode);
   unsigned HOST_WIDE_INT inner_nz;
@@ -8169,7 +8267,7 @@ nonzero_bits (x, mode)
       && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT
       && GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (GET_MODE (x)))
     {
-      nonzero &= nonzero_bits (x, GET_MODE (x));
+      nonzero &= nonzero_bits_with_known (x, GET_MODE (x));
       nonzero |= GET_MODE_MASK (mode) & ~GET_MODE_MASK (GET_MODE (x));
       return nonzero;
     }
@@ -8251,7 +8349,7 @@ nonzero_bits (x, mode)
                           | ((HOST_WIDE_INT) (-1)
                              << GET_MODE_BITSIZE (GET_MODE (x))));
 #endif
-         return nonzero_bits (tem, mode) & nonzero;
+         return nonzero_bits_with_known (tem, mode) & nonzero;
        }
       else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
        {
@@ -8326,11 +8424,12 @@ nonzero_bits (x, mode)
       break;
 
     case TRUNCATE:
-      nonzero &= (nonzero_bits (XEXP (x, 0), mode) & GET_MODE_MASK (mode));
+      nonzero &= (nonzero_bits_with_known (XEXP (x, 0), mode)
+                 & GET_MODE_MASK (mode));
       break;
 
     case ZERO_EXTEND:
-      nonzero &= nonzero_bits (XEXP (x, 0), mode);
+      nonzero &= nonzero_bits_with_known (XEXP (x, 0), mode);
       if (GET_MODE (XEXP (x, 0)) != VOIDmode)
        nonzero &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
       break;
@@ -8339,7 +8438,7 @@ nonzero_bits (x, mode)
       /* If the sign bit is known clear, this is the same as ZERO_EXTEND.
         Otherwise, show all the bits in the outer mode but not the inner
         may be nonzero.  */
-      inner_nz = nonzero_bits (XEXP (x, 0), mode);
+      inner_nz = nonzero_bits_with_known (XEXP (x, 0), mode);
       if (GET_MODE (XEXP (x, 0)) != VOIDmode)
        {
          inner_nz &= GET_MODE_MASK (GET_MODE (XEXP (x, 0)));
@@ -8354,19 +8453,21 @@ nonzero_bits (x, mode)
       break;
 
     case AND:
-      nonzero &= (nonzero_bits (XEXP (x, 0), mode)
-                 & nonzero_bits (XEXP (x, 1), mode));
+      nonzero &= (nonzero_bits_with_known (XEXP (x, 0), mode)
+                 & nonzero_bits_with_known (XEXP (x, 1), mode));
       break;
 
     case XOR:   case IOR:
     case UMIN:  case UMAX:  case SMIN:  case SMAX:
       {
-       unsigned HOST_WIDE_INT nonzero0 = nonzero_bits (XEXP (x, 0), mode);
+       unsigned HOST_WIDE_INT nonzero0 =
+         nonzero_bits_with_known (XEXP (x, 0), mode);
 
        /* Don't call nonzero_bits for the second time if it cannot change
           anything.  */
        if ((nonzero & nonzero0) != nonzero)
-         nonzero &= (nonzero0 | nonzero_bits (XEXP (x, 1), mode));
+         nonzero &= (nonzero0
+                     | nonzero_bits_with_known (XEXP (x, 1), mode));
       }
       break;
 
@@ -8379,8 +8480,10 @@ nonzero_bits (x, mode)
         computing the width (position of the highest-order nonzero bit)
         and the number of low-order zero bits for each value.  */
       {
-       unsigned HOST_WIDE_INT nz0 = nonzero_bits (XEXP (x, 0), mode);
-       unsigned HOST_WIDE_INT nz1 = nonzero_bits (XEXP (x, 1), mode);
+       unsigned HOST_WIDE_INT nz0 =
+         nonzero_bits_with_known (XEXP (x, 0), mode);
+       unsigned HOST_WIDE_INT nz1 =
+         nonzero_bits_with_known (XEXP (x, 1), mode);
        int sign_index = GET_MODE_BITSIZE (GET_MODE (x)) - 1;
        int width0 = floor_log2 (nz0) + 1;
        int width1 = floor_log2 (nz1) + 1;
@@ -8465,7 +8568,7 @@ nonzero_bits (x, mode)
 
       if (SUBREG_PROMOTED_VAR_P (x) && SUBREG_PROMOTED_UNSIGNED_P (x) > 0)
        nonzero = (GET_MODE_MASK (GET_MODE (x))
-                  & nonzero_bits (SUBREG_REG (x), GET_MODE (x)));
+                  & nonzero_bits_with_known (SUBREG_REG (x), GET_MODE (x)));
 
       /* If the inner mode is a single word for both the host and target
         machines, we can compute this from which bits of the inner
@@ -8474,7 +8577,7 @@ nonzero_bits (x, mode)
          && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
              <= HOST_BITS_PER_WIDE_INT))
        {
-         nonzero &= nonzero_bits (SUBREG_REG (x), mode);
+         nonzero &= nonzero_bits_with_known (SUBREG_REG (x), mode);
 
 #if defined (WORD_REGISTER_OPERATIONS) && defined (LOAD_EXTEND_OP)
          /* If this is a typical RISC machine, we only have to worry
@@ -8517,7 +8620,8 @@ nonzero_bits (x, mode)
          unsigned int width = GET_MODE_BITSIZE (inner_mode);
          int count = INTVAL (XEXP (x, 1));
          unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode);
-         unsigned HOST_WIDE_INT op_nonzero = nonzero_bits (XEXP (x, 0), mode);
+         unsigned HOST_WIDE_INT op_nonzero =
+           nonzero_bits_with_known (XEXP (x, 0), mode);
          unsigned HOST_WIDE_INT inner = op_nonzero & mode_mask;
          unsigned HOST_WIDE_INT outer = 0;
 
@@ -8575,8 +8679,8 @@ nonzero_bits (x, mode)
       break;
 
     case IF_THEN_ELSE:
-      nonzero &= (nonzero_bits (XEXP (x, 1), mode)
-                 | nonzero_bits (XEXP (x, 2), mode));
+      nonzero &= (nonzero_bits_with_known (XEXP (x, 1), mode)
+                 | nonzero_bits_with_known (XEXP (x, 2), mode));
       break;
 
     default:
@@ -8587,17 +8691,74 @@ nonzero_bits (x, mode)
 }
 
 /* See the macro definition above.  */
-#undef num_sign_bit_copies
+#undef cached_num_sign_bit_copies
 \f
+#define num_sign_bit_copies_with_known(X, M) \
+  cached_num_sign_bit_copies (X, M, known_x, known_mode, known_ret)
+
+/* The function cached_num_sign_bit_copies is a wrapper around
+   num_sign_bit_copies1.  It avoids exponential behavior in
+   num_sign_bit_copies1 when X has identical subexpressions on the
+   first or the second level.  */
+
+static unsigned int
+cached_num_sign_bit_copies (x, mode, known_x, known_mode, known_ret)
+     rtx x;
+     enum machine_mode mode;
+     rtx known_x;
+     enum machine_mode known_mode;
+     unsigned int known_ret;
+{
+  if (x == known_x && mode == known_mode)
+    return known_ret;
+
+  /* Try to find identical subexpressions.  If found call
+     num_sign_bit_copies1 on X with the subexpressions as KNOWN_X and
+     the precomputed value for the subexpression as KNOWN_RET.  */
+
+  if (GET_RTX_CLASS (GET_CODE (x)) == '2'
+      || GET_RTX_CLASS (GET_CODE (x)) == 'c')
+    {
+      rtx x0 = XEXP (x, 0);
+      rtx x1 = XEXP (x, 1);
+
+      /* Check the first level.  */
+      if (x0 == x1)
+       return
+         num_sign_bit_copies1 (x, mode, x0, mode,
+                               num_sign_bit_copies_with_known (x0, mode));
+
+      /* Check the second level.  */
+      if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
+          || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
+         && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
+       return
+         num_sign_bit_copies1 (x, mode, x1, mode,
+                               num_sign_bit_copies_with_known (x1, mode));
+
+      if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
+          || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
+         && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
+       return
+         num_sign_bit_copies1 (x, mode, x0, mode,
+                               num_sign_bit_copies_with_known (x0, mode));
+    }
+
+  return num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret);
+}
+
 /* Return the number of bits at the high-order end of X that are known to
    be equal to the sign bit.  X will be used in mode MODE; if MODE is
    VOIDmode, X will be used in its own mode.  The returned value  will always
    be between 1 and the number of bits in MODE.  */
 
 static unsigned int
-num_sign_bit_copies (x, mode)
+num_sign_bit_copies1 (x, mode, known_x, known_mode, known_ret)
      rtx x;
      enum machine_mode mode;
+     rtx known_x;
+     enum machine_mode known_mode;
+     unsigned int known_ret;
 {
   enum rtx_code code = GET_CODE (x);
   unsigned int bitwidth;
@@ -8620,7 +8781,7 @@ num_sign_bit_copies (x, mode)
   /* For a smaller object, just ignore the high bits.  */
   if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x)))
     {
-      num0 = num_sign_bit_copies (x, GET_MODE (x));
+      num0 = num_sign_bit_copies_with_known (x, GET_MODE (x));
       return MAX (1,
                  num0 - (int) (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth));
     }
@@ -8669,7 +8830,7 @@ num_sign_bit_copies (x, mode)
 
       tem = get_last_value (x);
       if (tem != 0)
-       return num_sign_bit_copies (tem, mode);
+       return num_sign_bit_copies_with_known (tem, mode);
 
       if (nonzero_sign_valid && reg_sign_bit_copies[REGNO (x)] != 0
          && GET_MODE_BITSIZE (GET_MODE (x)) == bitwidth)
@@ -8702,7 +8863,7 @@ num_sign_bit_copies (x, mode)
 
       if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x))
        {
-         num0 = num_sign_bit_copies (SUBREG_REG (x), mode);
+         num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), mode);
          return MAX ((int) bitwidth
                      - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1,
                      num0);
@@ -8711,7 +8872,7 @@ num_sign_bit_copies (x, mode)
       /* For a smaller object, just ignore the high bits.  */
       if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
        {
-         num0 = num_sign_bit_copies (SUBREG_REG (x), VOIDmode);
+         num0 = num_sign_bit_copies_with_known (SUBREG_REG (x), VOIDmode);
          return MAX (1, (num0
                          - (int) (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
                                   - bitwidth)));
@@ -8733,7 +8894,7 @@ num_sign_bit_copies (x, mode)
           > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
          && LOAD_EXTEND_OP (GET_MODE (SUBREG_REG (x))) == SIGN_EXTEND
          && GET_CODE (SUBREG_REG (x)) == MEM)
-       return num_sign_bit_copies (SUBREG_REG (x), mode);
+       return num_sign_bit_copies_with_known (SUBREG_REG (x), mode);
 #endif
 #endif
       break;
@@ -8745,16 +8906,16 @@ num_sign_bit_copies (x, mode)
 
     case SIGN_EXTEND:
       return (bitwidth - GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
-             + num_sign_bit_copies (XEXP (x, 0), VOIDmode));
+             + num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode));
 
     case TRUNCATE:
       /* For a smaller object, just ignore the high bits.  */
-      num0 = num_sign_bit_copies (XEXP (x, 0), VOIDmode);
+      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), VOIDmode);
       return MAX (1, (num0 - (int) (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
                                    - bitwidth)));
 
     case NOT:
-      return num_sign_bit_copies (XEXP (x, 0), mode);
+      return num_sign_bit_copies_with_known (XEXP (x, 0), mode);
 
     case ROTATE:       case ROTATERT:
       /* If we are rotating left by a number of bits less than the number
@@ -8764,7 +8925,7 @@ num_sign_bit_copies (x, mode)
          && INTVAL (XEXP (x, 1)) >= 0
          && INTVAL (XEXP (x, 1)) < (int) bitwidth)
        {
-         num0 = num_sign_bit_copies (XEXP (x, 0), mode);
+         num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
          return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1))
                                 : (int) bitwidth - INTVAL (XEXP (x, 1))));
        }
@@ -8775,7 +8936,7 @@ num_sign_bit_copies (x, mode)
         is known to be positive, the number of sign bit copies is the
         same as that of the input.  Finally, if the input has just one bit
         that might be nonzero, all the bits are copies of the sign bit.  */
-      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
+      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
       if (bitwidth > HOST_BITS_PER_WIDE_INT)
        return num0 > 1 ? num0 - 1 : 1;
 
@@ -8793,8 +8954,8 @@ num_sign_bit_copies (x, mode)
     case SMIN:  case SMAX:  case UMIN:  case UMAX:
       /* Logical operations will preserve the number of sign-bit copies.
         MIN and MAX operations always return one of the operands.  */
-      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
-      num1 = num_sign_bit_copies (XEXP (x, 1), mode);
+      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
+      num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
       return MIN (num0, num1);
 
     case PLUS:  case MINUS:
@@ -8812,8 +8973,8 @@ num_sign_bit_copies (x, mode)
                    : bitwidth - floor_log2 (nonzero) - 1);
        }
 
-      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
-      num1 = num_sign_bit_copies (XEXP (x, 1), mode);
+      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
+      num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
       result = MAX (1, MIN (num0, num1) - 1);
 
 #ifdef POINTERS_EXTEND_UNSIGNED
@@ -8835,8 +8996,8 @@ num_sign_bit_copies (x, mode)
         to be positive, we must allow for an additional bit since negating
         a negative number can remove one sign bit copy.  */
 
-      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
-      num1 = num_sign_bit_copies (XEXP (x, 1), mode);
+      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
+      num1 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
 
       result = bitwidth - (bitwidth - num0) - (bitwidth - num1);
       if (result > 0
@@ -8859,17 +9020,17 @@ num_sign_bit_copies (x, mode)
                & ((HOST_WIDE_INT) 1 << (bitwidth - 1))) != 0)
        return 1;
       else
-       return num_sign_bit_copies (XEXP (x, 0), mode);
+       return num_sign_bit_copies_with_known (XEXP (x, 0), mode);
 
     case UMOD:
       /* The result must be <= the second operand.  */
-      return num_sign_bit_copies (XEXP (x, 1), mode);
+      return num_sign_bit_copies_with_known (XEXP (x, 1), mode);
 
     case DIV:
       /* Similar to unsigned division, except that we have to worry about
         the case where the divisor is negative, in which case we have
         to add 1.  */
-      result = num_sign_bit_copies (XEXP (x, 0), mode);
+      result = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
       if (result > 1
          && (bitwidth > HOST_BITS_PER_WIDE_INT
              || (nonzero_bits (XEXP (x, 1), mode)
@@ -8879,7 +9040,7 @@ num_sign_bit_copies (x, mode)
       return result;
 
     case MOD:
-      result = num_sign_bit_copies (XEXP (x, 1), mode);
+      result = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
       if (result > 1
          && (bitwidth > HOST_BITS_PER_WIDE_INT
              || (nonzero_bits (XEXP (x, 1), mode)
@@ -8891,7 +9052,7 @@ num_sign_bit_copies (x, mode)
     case ASHIFTRT:
       /* Shifts by a constant add to the number of bits equal to the
         sign bit.  */
-      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
+      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
       if (GET_CODE (XEXP (x, 1)) == CONST_INT
          && INTVAL (XEXP (x, 1)) > 0)
        num0 = MIN ((int) bitwidth, num0 + INTVAL (XEXP (x, 1)));
@@ -8905,12 +9066,12 @@ num_sign_bit_copies (x, mode)
          || INTVAL (XEXP (x, 1)) >= (int) bitwidth)
        return 1;
 
-      num0 = num_sign_bit_copies (XEXP (x, 0), mode);
+      num0 = num_sign_bit_copies_with_known (XEXP (x, 0), mode);
       return MAX (1, num0 - INTVAL (XEXP (x, 1)));
 
     case IF_THEN_ELSE:
-      num0 = num_sign_bit_copies (XEXP (x, 1), mode);
-      num1 = num_sign_bit_copies (XEXP (x, 2), mode);
+      num0 = num_sign_bit_copies_with_known (XEXP (x, 1), mode);
+      num1 = num_sign_bit_copies_with_known (XEXP (x, 2), mode);
       return MIN (num0, num1);
 
     case EQ:  case NE:  case GE:  case GT:  case LE:  case LT:
@@ -9072,7 +9233,7 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
          op0 = AND, *pcomp_p = 1;
        else /* op1 == IOR */
          /* (a | b) ^ b == a & ~b */
-         op0 = AND, *pconst0 = ~const0;
+         op0 = AND, const0 = ~const0;
        break;
 
       case AND:
@@ -9251,6 +9412,16 @@ simplify_shift_const (x, code, result_mode, varop, orig_count)
              == 0))
        code = LSHIFTRT;
 
+      if (code == LSHIFTRT
+         && GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
+         && !(nonzero_bits (varop, shift_mode) >> count))
+       varop = const0_rtx;
+      if (code == ASHIFT
+         && GET_MODE_BITSIZE (shift_mode) <= HOST_BITS_PER_WIDE_INT
+         && !((nonzero_bits (varop, shift_mode) << count)
+              & GET_MODE_MASK (shift_mode)))
+       varop = const0_rtx;
+
       switch (GET_CODE (varop))
        {
        case SIGN_EXTEND:
@@ -10014,8 +10185,9 @@ gen_lowpart_for_combine (mode, x)
       && GET_CODE (result) == SUBREG
       && GET_CODE (SUBREG_REG (result)) == REG
       && REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
-    SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (result)],
-                      REGNO (SUBREG_REG (result)));
+    bitmap_set_bit (&subregs_of_mode, REGNO (SUBREG_REG (result))
+                                     * MAX_MACHINE_MODE
+                                     + GET_MODE (result));
 #endif
 
   if (result)
@@ -10820,9 +10992,7 @@ simplify_comparison (code, pop0, pop1)
          /* We can't do anything if OP0 is a condition code value, rather
             than an actual data value.  */
          if (const_op != 0
-#ifdef HAVE_cc0
-             || XEXP (op0, 0) == cc0_rtx
-#endif
+             || CC0_P (XEXP (op0, 0))
              || GET_MODE_CLASS (GET_MODE (XEXP (op0, 0))) == MODE_CC)
            break;
 
@@ -10940,46 +11110,45 @@ simplify_comparison (code, pop0, pop1)
              continue;
            }
 
-         /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1 fits
-            in both M1 and M2 and the SUBREG is either paradoxical or
-            represents the low part, permute the SUBREG and the AND and
-            try again.  */
-         if (GET_CODE (XEXP (op0, 0)) == SUBREG
-             /* It is unsafe to commute the AND into the SUBREG if the SUBREG
-                is paradoxical and WORD_REGISTER_OPERATIONS is not defined.
-                As originally written the upper bits have a defined value
-                due to the AND operation.  However, if we commute the AND
-                inside the SUBREG then they no longer have defined values
-                and the meaning of the code has been changed.  */
-             && (0
+         /* If this is (and:M1 (subreg:M2 X 0) (const_int C1)) where C1
+            fits in both M1 and M2 and the SUBREG is either paradoxical
+            or represents the low part, permute the SUBREG and the AND
+            and try again.  */
+         if (GET_CODE (XEXP (op0, 0)) == SUBREG)
+           {
+             unsigned HOST_WIDE_INT c1;
+             tmode = GET_MODE (SUBREG_REG (XEXP (op0, 0)));
+             /* Require an integral mode, to avoid creating something like
+                (AND:SF ...).  */
+             if (SCALAR_INT_MODE_P (tmode)
+                 /* It is unsafe to commute the AND into the SUBREG if the
+                    SUBREG is paradoxical and WORD_REGISTER_OPERATIONS is
+                    not defined.  As originally written the upper bits
+                    have a defined value due to the AND operation.
+                    However, if we commute the AND inside the SUBREG then
+                    they no longer have defined values and the meaning of
+                    the code has been changed.  */
+                 && (0
 #ifdef WORD_REGISTER_OPERATIONS
-                 || ((mode_width
-                      > (GET_MODE_BITSIZE
-                          (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
-                     && mode_width <= BITS_PER_WORD)
+                     || (mode_width > GET_MODE_BITSIZE (tmode)
+                         && mode_width <= BITS_PER_WORD)
 #endif
-                 || ((mode_width
-                      <= (GET_MODE_BITSIZE
-                          (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
-                     && subreg_lowpart_p (XEXP (op0, 0))))
-             && GET_CODE (XEXP (op0, 1)) == CONST_INT
-             && mode_width <= HOST_BITS_PER_WIDE_INT
-             && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
-                 <= HOST_BITS_PER_WIDE_INT)
-             && (INTVAL (XEXP (op0, 1)) & ~mask) == 0
-             && 0 == (~GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))
-                      & INTVAL (XEXP (op0, 1)))
-             && (unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1)) != mask
-             && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op0, 1))
-                 != GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0))))))
-
-           {
-             op0
-               = gen_lowpart_for_combine
-                 (mode,
-                  gen_binary (AND, GET_MODE (SUBREG_REG (XEXP (op0, 0))),
-                              SUBREG_REG (XEXP (op0, 0)), XEXP (op0, 1)));
-             continue;
+                     || (mode_width <= GET_MODE_BITSIZE (tmode)
+                         && subreg_lowpart_p (XEXP (op0, 0))))
+                 && GET_CODE (XEXP (op0, 1)) == CONST_INT
+                 && mode_width <= HOST_BITS_PER_WIDE_INT
+                 && GET_MODE_BITSIZE (tmode) <= HOST_BITS_PER_WIDE_INT
+                 && ((c1 = INTVAL (XEXP (op0, 1))) & ~mask) == 0
+                 && (c1 & ~GET_MODE_MASK (tmode)) == 0
+                 && c1 != mask
+                 && c1 != GET_MODE_MASK (tmode))
+               {
+                 op0 = gen_binary (AND, tmode,
+                                   SUBREG_REG (XEXP (op0, 0)),
+                                   gen_int_mode (c1, tmode));
+                 op0 = gen_lowpart_for_combine (mode, op0);
+                 continue;
+               }
            }
 
          /* Convert (ne (and (lshiftrt (not X)) 1) 0) to
@@ -11359,7 +11528,45 @@ update_table_tick (x)
     /* Note that we can't have an "E" in values stored; see
        get_last_value_validate.  */
     if (fmt[i] == 'e')
-      update_table_tick (XEXP (x, i));
+      {
+       /* Check for identical subexpressions.  If x contains
+          identical subexpression we only have to traverse one of
+          them.  */
+       if (i == 0
+           && (GET_RTX_CLASS (code) == '2'
+               || GET_RTX_CLASS (code) == 'c'))
+         {
+           /* Note that at this point x1 has already been
+              processed.  */
+           rtx x0 = XEXP (x, 0);
+           rtx x1 = XEXP (x, 1);
+
+           /* If x0 and x1 are identical then there is no need to
+              process x0.  */
+           if (x0 == x1)
+             break;
+
+           /* If x0 is identical to a subexpression of x1 then while
+              processing x1, x0 has already been processed.  Thus we
+              are done with x.  */
+           if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
+                || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
+               && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
+             break;
+
+           /* If x1 is identical to a subexpression of x0 then we
+              still have to process the rest of x0.  */
+           if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
+                || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
+               && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
+             {
+               update_table_tick (XEXP (x0, x1 == XEXP (x0, 0) ? 1 : 0));
+               break;
+             }
+         }
+
+       update_table_tick (XEXP (x, i));
+      }
 }
 
 /* Record that REG is set to VALUE in insn INSN.  If VALUE is zero, we
@@ -11712,11 +11919,52 @@ get_last_value_validate (loc, insn, tick, replace)
     }
 
   for (i = 0; i < len; i++)
-    if ((fmt[i] == 'e'
-        && get_last_value_validate (&XEXP (x, i), insn, tick, replace) == 0)
-       /* Don't bother with these.  They shouldn't occur anyway.  */
-       || fmt[i] == 'E')
-      return 0;
+    {
+      if (fmt[i] == 'e')
+       {
+         /* Check for identical subexpressions.  If x contains
+            identical subexpression we only have to traverse one of
+            them.  */
+         if (i == 1
+             && (GET_RTX_CLASS (GET_CODE (x)) == '2'
+                 || GET_RTX_CLASS (GET_CODE (x)) == 'c'))
+           {
+             /* Note that at this point x0 has already been checked
+                and found valid.  */
+             rtx x0 = XEXP (x, 0);
+             rtx x1 = XEXP (x, 1);
+
+             /* If x0 and x1 are identical then x is also valid.  */
+             if (x0 == x1)
+               return 1;
+
+             /* If x1 is identical to a subexpression of x0 then
+                while checking x0, x1 has already been checked.  Thus
+                it is valid and so as x.  */
+             if ((GET_RTX_CLASS (GET_CODE (x0)) == '2'
+                  || GET_RTX_CLASS (GET_CODE (x0)) == 'c')
+                 && (x1 == XEXP (x0, 0) || x1 == XEXP (x0, 1)))
+               return 1;
+
+             /* If x0 is identical to a subexpression of x1 then x is
+                valid iff the rest of x1 is valid.  */
+             if ((GET_RTX_CLASS (GET_CODE (x1)) == '2'
+                  || GET_RTX_CLASS (GET_CODE (x1)) == 'c')
+                 && (x0 == XEXP (x1, 0) || x0 == XEXP (x1, 1)))
+               return
+                 get_last_value_validate (&XEXP (x1,
+                                                 x0 == XEXP (x1, 0) ? 1 : 0),
+                                          insn, tick, replace);
+           }
+
+         if (get_last_value_validate (&XEXP (x, i), insn, tick,
+                                      replace) == 0)
+           return 0;
+       }
+      /* Don't bother with these.  They shouldn't occur anyway.  */
+      else if (fmt[i] == 'E')
+       return 0;
+    }
 
   /* If we haven't found a reason for it to be invalid, it is valid.  */
   return 1;
@@ -12324,7 +12572,6 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
        {
        case REG_BR_PROB:
        case REG_BR_PRED:
-       case REG_EXEC_COUNT:
          /* Doesn't matter much where we put this, as long as it's somewhere.
             It is preferable to keep these notes on branches, which is most
             likely to be i3.  */