OSDN Git Service

PR rtl-opt/21528
[pf3gnuchains/gcc-fork.git] / gcc / expr.c
index c2c9ffe..8b75ed7 100644 (file)
@@ -126,7 +126,7 @@ static void move_by_pieces_1 (rtx (*) (rtx, ...), enum machine_mode,
                              struct move_by_pieces *);
 static bool block_move_libcall_safe_for_call_parm (void);
 static bool emit_block_move_via_movmem (rtx, rtx, rtx, unsigned);
-static rtx emit_block_move_via_libcall (rtx, rtx, rtx);
+static rtx emit_block_move_via_libcall (rtx, rtx, rtx, bool);
 static tree emit_block_move_libcall_fn (int);
 static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned);
 static rtx clear_by_pieces_1 (void *, HOST_WIDE_INT, enum machine_mode);
@@ -135,7 +135,7 @@ static void store_by_pieces_1 (struct store_by_pieces *, unsigned int);
 static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode,
                               struct store_by_pieces *);
 static bool clear_storage_via_clrmem (rtx, rtx, unsigned);
-static rtx clear_storage_via_libcall (rtx, rtx);
+static rtx clear_storage_via_libcall (rtx, rtx, bool);
 static tree clear_storage_libcall_fn (int);
 static rtx compress_float_constant (rtx, rtx);
 static rtx get_subtarget (rtx);
@@ -208,6 +208,30 @@ enum insn_code clrmem_optab[NUM_MACHINE_MODES];
 enum insn_code cmpstr_optab[NUM_MACHINE_MODES];
 enum insn_code cmpmem_optab[NUM_MACHINE_MODES];
 
+/* Synchronization primitives.  */
+enum insn_code sync_add_optab[NUM_MACHINE_MODES];
+enum insn_code sync_sub_optab[NUM_MACHINE_MODES];
+enum insn_code sync_ior_optab[NUM_MACHINE_MODES];
+enum insn_code sync_and_optab[NUM_MACHINE_MODES];
+enum insn_code sync_xor_optab[NUM_MACHINE_MODES];
+enum insn_code sync_nand_optab[NUM_MACHINE_MODES];
+enum insn_code sync_old_add_optab[NUM_MACHINE_MODES];
+enum insn_code sync_old_sub_optab[NUM_MACHINE_MODES];
+enum insn_code sync_old_ior_optab[NUM_MACHINE_MODES];
+enum insn_code sync_old_and_optab[NUM_MACHINE_MODES];
+enum insn_code sync_old_xor_optab[NUM_MACHINE_MODES];
+enum insn_code sync_old_nand_optab[NUM_MACHINE_MODES];
+enum insn_code sync_new_add_optab[NUM_MACHINE_MODES];
+enum insn_code sync_new_sub_optab[NUM_MACHINE_MODES];
+enum insn_code sync_new_ior_optab[NUM_MACHINE_MODES];
+enum insn_code sync_new_and_optab[NUM_MACHINE_MODES];
+enum insn_code sync_new_xor_optab[NUM_MACHINE_MODES];
+enum insn_code sync_new_nand_optab[NUM_MACHINE_MODES];
+enum insn_code sync_compare_and_swap[NUM_MACHINE_MODES];
+enum insn_code sync_compare_and_swap_cc[NUM_MACHINE_MODES];
+enum insn_code sync_lock_test_and_set[NUM_MACHINE_MODES];
+enum insn_code sync_lock_release[NUM_MACHINE_MODES];
+
 /* SLOW_UNALIGNED_ACCESS is nonzero if unaligned accesses are very slow.  */
 
 #ifndef SLOW_UNALIGNED_ACCESS
@@ -442,19 +466,27 @@ convert_move (rtx to, rtx from, int unsignedp)
     }
   if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
     {
+      rtx new_from;
       enum machine_mode full_mode
        = smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT);
 
       gcc_assert (sext_optab->handlers[full_mode][from_mode].insn_code
                  != CODE_FOR_nothing);
 
-      emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
-                     to, from, UNKNOWN);
       if (to_mode == full_mode)
-       return;
+       {
+         emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
+                         to, from, UNKNOWN);
+         return;
+       }
+
+      new_from = gen_reg_rtx (full_mode);
+      emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
+                     new_from, from, UNKNOWN);
 
       /* else proceed to integer conversions below.  */
       from_mode = full_mode;
+      from = new_from;
     }
 
   /* Now both modes are integers.  */
@@ -1124,6 +1156,7 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
   switch (method)
     {
     case BLOCK_OP_NORMAL:
+    case BLOCK_OP_TAILCALL:
       may_use_call = true;
       break;
 
@@ -1172,7 +1205,8 @@ emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
   else if (emit_block_move_via_movmem (x, y, size, align))
     ;
   else if (may_use_call)
-    retval = emit_block_move_via_libcall (x, y, size);
+    retval = emit_block_move_via_libcall (x, y, size,
+                                         method == BLOCK_OP_TAILCALL);
   else
     emit_block_move_via_loop (x, y, size, align);
 
@@ -1301,7 +1335,7 @@ emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align)
    Return the return value from memcpy, 0 otherwise.  */
 
 static rtx
-emit_block_move_via_libcall (rtx dst, rtx src, rtx size)
+emit_block_move_via_libcall (rtx dst, rtx src, rtx size, bool tailcall)
 {
   rtx dst_addr, src_addr;
   tree call_expr, arg_list, fn, src_tree, dst_tree, size_tree;
@@ -1343,6 +1377,7 @@ emit_block_move_via_libcall (rtx dst, rtx src, rtx size)
   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
                      call_expr, arg_list, NULL_TREE);
+  CALL_EXPR_TAILCALL (call_expr) = tailcall;
 
   retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
 
@@ -2403,11 +2438,13 @@ store_by_pieces_2 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
    its length in bytes.  */
 
 rtx
-clear_storage (rtx object, rtx size)
+clear_storage (rtx object, rtx size, enum block_op_methods method)
 {
   enum machine_mode mode = GET_MODE (object);
   unsigned int align;
 
+  gcc_assert (method == BLOCK_OP_NORMAL || method == BLOCK_OP_TAILCALL);
+
   /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
      just move a zero.  Otherwise, do this a piece at a time.  */
   if (mode != BLKmode
@@ -2444,7 +2481,8 @@ clear_storage (rtx object, rtx size)
   else if (clear_storage_via_clrmem (object, size, align))
     ;
   else
-    return clear_storage_via_libcall (object, size);
+    return clear_storage_via_libcall (object, size,
+                                     method == BLOCK_OP_TAILCALL);
 
   return NULL;
 }
@@ -2509,7 +2547,7 @@ clear_storage_via_clrmem (rtx object, rtx size, unsigned int align)
    Return the return value of memset, 0 otherwise.  */
 
 static rtx
-clear_storage_via_libcall (rtx object, rtx size)
+clear_storage_via_libcall (rtx object, rtx size, bool tailcall)
 {
   tree call_expr, arg_list, fn, object_tree, size_tree;
   enum machine_mode size_mode;
@@ -2542,6 +2580,7 @@ clear_storage_via_libcall (rtx object, rtx size)
   call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
   call_expr = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
                      call_expr, arg_list, NULL_TREE);
+  CALL_EXPR_TAILCALL (call_expr) = tailcall;
 
   retval = expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
 
@@ -2626,7 +2665,7 @@ write_complex_part (rtx cplx, rtx val, bool imag_p)
         the original object if it spans an even number of hard regs.
         This special case is important for SCmode on 64-bit platforms
         where the natural size of floating-point regs is 32-bit.  */
-      || (GET_CODE (cplx) == REG
+      || (REG_P (cplx)
          && REGNO (cplx) < FIRST_PSEUDO_REGISTER
          && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)
       /* For MEMs we always try to make a "subreg", that is to adjust
@@ -2686,7 +2725,7 @@ read_complex_part (rtx cplx, bool imag_p)
         the original object if it spans an even number of hard regs.
         This special case is important for SCmode on 64-bit platforms
         where the natural size of floating-point regs is 32-bit.  */
-      || (GET_CODE (cplx) == REG
+      || (REG_P (cplx)
          && REGNO (cplx) < FIRST_PSEUDO_REGISTER
          && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)
       /* For MEMs we always try to make a "subreg", that is to adjust
@@ -2877,19 +2916,14 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
   if (push_operand (x, mode))
     return emit_move_complex_push (mode, x, y);
 
-  /* For memory to memory moves, optimal behavior can be had with the
-     existing block move logic.  */
-  if (MEM_P (x) && MEM_P (y))
-    {
-      emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
-                      BLOCK_OP_NO_LIBCALL);
-      return get_last_insn ();
-    }
-
   /* See if we can coerce the target into moving both values at once.  */
 
+  /* Move floating point as parts.  */
+  if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
+      && mov_optab->handlers[GET_MODE_INNER (mode)].insn_code != CODE_FOR_nothing)
+    try_int = false;
   /* Not possible if the values are inherently not adjacent.  */
-  if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
+  else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
     try_int = false;
   /* Is possible if both are registers (or subregs of registers).  */
   else if (register_operand (x, mode) && register_operand (y, mode))
@@ -2907,7 +2941,18 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
 
   if (try_int)
     {
-      rtx ret = emit_move_via_integer (mode, x, y);
+      rtx ret;
+
+      /* For memory to memory moves, optimal behavior can be had with the
+        existing block move logic.  */
+      if (MEM_P (x) && MEM_P (y))
+       {
+         emit_block_move (x, y, GEN_INT (GET_MODE_SIZE (mode)),
+                          BLOCK_OP_NO_LIBCALL);
+         return get_last_insn ();
+       }
+
+      ret = emit_move_via_integer (mode, x, y);
       if (ret)
        return ret;
     }
@@ -2990,8 +3035,8 @@ emit_move_multi_word (enum machine_mode mode, rtx x, rtx y)
       rtx ypart = operand_subword (y, i, 1, mode);
 
       /* If we can't get a part of Y, put Y into memory if it is a
-        constant.  Otherwise, force it into a register.  If we still
-        can't get a part of Y, abort.  */
+        constant.  Otherwise, force it into a register.  Then we must
+        be able to get a part of Y.  */
       if (ypart == 0 && CONSTANT_P (y))
        {
          y = force_const_mem (mode, y);
@@ -3514,7 +3559,7 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
       int not_stack;
       /* # bytes of start of argument
         that we must make space for but need not store.  */
-      int offset = partial % (PARM_BOUNDARY / BITS_PER_WORD);
+      int offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
       int args_offset = INTVAL (args_so_far);
       int skip;
 
@@ -3532,8 +3577,9 @@ emit_push_insn (rtx x, enum machine_mode mode, tree type, rtx size,
        offset = 0;
 
       /* Now NOT_STACK gets the number of words that we don't need to
-        allocate on the stack.  */
+        allocate on the stack. Convert OFFSET to words too. */
       not_stack = (partial - offset) / UNITS_PER_WORD;
+      offset /= UNITS_PER_WORD;
 
       /* If the partial register-part of the arg counts in its stack size,
         skip the part of stack space corresponding to the registers.
@@ -3824,7 +3870,6 @@ expand_assignment (tree to, tree from)
     {
       enum machine_mode mode1;
       HOST_WIDE_INT bitsize, bitpos;
-      rtx orig_to_rtx;
       tree offset;
       int unsignedp;
       int volatilep = 0;
@@ -3837,7 +3882,7 @@ expand_assignment (tree to, tree from)
       /* If we are going to use store_bit_field and extract_bit_field,
         make sure to_rtx will be safe for multiple use.  */
 
-      orig_to_rtx = to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, 0);
+      to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, 0);
 
       if (offset != 0)
        {
@@ -4192,10 +4237,10 @@ store_expr (tree exp, rtx target, int call_param_p)
         but TARGET is not valid memory reference, TEMP will differ
         from TARGET although it is really the same location.  */
       && !(alt_rtl && rtx_equal_p (alt_rtl, target))
-      /* If there's nothing to copy, don't bother.  Don't call expr_size
-        unless necessary, because some front-ends (C++) expr_size-hook
-        aborts on objects that are not supposed to be bit-copied or
-        bit-initialized.  */
+      /* If there's nothing to copy, don't bother.  Don't call
+        expr_size unless necessary, because some front-ends (C++)
+        expr_size-hook must not be given objects that are not
+        supposed to be bit-copied or bit-initialized.  */
       && expr_size (exp) != const0_rtx)
     {
       if (GET_MODE (temp) != GET_MODE (target)
@@ -4275,7 +4320,7 @@ store_expr (tree exp, rtx target, int call_param_p)
                }
 
              if (size != const0_rtx)
-               clear_storage (target, size);
+               clear_storage (target, size, BLOCK_OP_NORMAL);
 
              if (label)
                emit_label (label);
@@ -4517,7 +4562,6 @@ count_type_elements (tree type)
 
     case VOID_TYPE:
     case METHOD_TYPE:
-    case FILE_TYPE:
     case FUNCTION_TYPE:
     case LANG_TYPE:
     default:
@@ -4630,7 +4674,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
                 && ! CONSTRUCTOR_ELTS (exp))
          /* If the constructor is empty, clear the union.  */
          {
-           clear_storage (target, expr_size (exp));
+           clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
            cleared = 1;
          }
 
@@ -4658,7 +4702,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
                     || ((HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target))
                         == size)))
          {
-           clear_storage (target, GEN_INT (size));
+           clear_storage (target, GEN_INT (size), BLOCK_OP_NORMAL);
            cleared = 1;
          }
 
@@ -4754,9 +4798,9 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
                
                if (BYTES_BIG_ENDIAN)
                  value
-                   = fold (build2 (LSHIFT_EXPR, type, value,
-                                   build_int_cst (NULL_TREE,
-                                                  BITS_PER_WORD - bitsize)));
+                  = fold_build2 (LSHIFT_EXPR, type, value,
+                                  build_int_cst (NULL_TREE,
+                                                 BITS_PER_WORD - bitsize));
                bitsize = BITS_PER_WORD;
                mode = word_mode;
              }
@@ -4858,7 +4902,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
            if (REG_P (target))
              emit_move_insn (target,  CONST0_RTX (GET_MODE (target)));
            else
-             clear_storage (target, GEN_INT (size));
+             clear_storage (target, GEN_INT (size), BLOCK_OP_NORMAL);
            cleared = 1;
          }
 
@@ -4957,8 +5001,8 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
                    /* Assign value to element index.  */
                    position
                      = convert (ssizetype,
-                                fold (build2 (MINUS_EXPR, TREE_TYPE (index),
-                                              index, TYPE_MIN_VALUE (domain))));
+                                fold_build2 (MINUS_EXPR, TREE_TYPE (index),
+                                             index, TYPE_MIN_VALUE (domain)));
                    position = size_binop (MULT_EXPR, position,
                                           convert (ssizetype,
                                                    TYPE_SIZE_UNIT (elttype)));
@@ -5000,10 +5044,10 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
                
                if (minelt)
                  index = fold_convert (ssizetype,
-                                       fold (build2 (MINUS_EXPR,
-                                                     TREE_TYPE (index),
-                                                     index,
-                                                     TYPE_MIN_VALUE (domain))));
+                                       fold_build2 (MINUS_EXPR,
+                                                    TREE_TYPE (index),
+                                                    index,
+                                                    TYPE_MIN_VALUE (domain)));
                
                position = size_binop (MULT_EXPR, index,
                                       convert (ssizetype,
@@ -5103,7 +5147,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
            if (REG_P (target))
              emit_move_insn (target,  CONST0_RTX (GET_MODE (target)));
            else
-             clear_storage (target, GEN_INT (size));
+             clear_storage (target, GEN_INT (size), BLOCK_OP_NORMAL);
            cleared = 1;
          }
        
@@ -5456,8 +5500,8 @@ get_inner_reference (tree exp, HOST_WIDE_INT *pbitsize,
               index, then convert to sizetype and multiply by the size of
               the array element.  */
            if (! integer_zerop (low_bound))
-             index = fold (build2 (MINUS_EXPR, TREE_TYPE (index),
-                                   index, low_bound));
+             index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
+                                  index, low_bound);
 
            offset = size_binop (PLUS_EXPR, offset,
                                 size_binop (MULT_EXPR,
@@ -6072,7 +6116,7 @@ expand_var (tree var)
       ? !TREE_ASM_WRITTEN (var)
       : !DECL_RTL_SET_P (var))
     {
-      if (TREE_CODE (var) == VAR_DECL && DECL_VALUE_EXPR (var))
+      if (TREE_CODE (var) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (var))
        /* Should be ignored.  */;
       else if (lang_hooks.expand_decl (var))
        /* OK.  */;
@@ -6184,7 +6228,7 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode,
          /* If the DECL isn't in memory, then the DECL wasn't properly
             marked TREE_ADDRESSABLE, which will be either a front-end
             or a tree optimizer bug.  */
-         gcc_assert (GET_CODE (result) == MEM);
+         gcc_assert (MEM_P (result));
          result = XEXP (result, 0);
 
          /* ??? Is this needed anymore?  */
@@ -6818,7 +6862,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
     case INDIRECT_REF:
       {
        tree exp1 = TREE_OPERAND (exp, 0);
-       tree orig;
 
        if (modifier != EXPAND_WRITE)
          {
@@ -6841,10 +6884,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
 
        temp = gen_rtx_MEM (mode, op0);
 
-       orig = REF_ORIGINAL (exp);
-       if (!orig)
-         orig = exp;
-       set_mem_attributes (temp, orig, 0);
+       set_mem_attributes (temp, exp, 0);
 
        /* Resolve the misalignment now, so that we don't have to remember
           to resolve it later.  Of course, this only works for reads.  */
@@ -6876,6 +6916,18 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        return temp;
       }
 
+    case TARGET_MEM_REF:
+      {
+       struct mem_address addr;
+
+       get_address_description (exp, &addr);
+       op0 = addr_for_mem_ref (&addr, true);
+       op0 = memory_address (mode, op0);
+       temp = gen_rtx_MEM (mode, op0);
+       set_mem_attributes (temp, TMR_ORIGINAL (exp), 0);
+      }
+      return temp;
+
     case ARRAY_REF:
 
       {
@@ -7711,7 +7763,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
          optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
          this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
 
-         if (mode == GET_MODE_WIDER_MODE (innermode))
+         if (mode == GET_MODE_2XWIDER_MODE (innermode))
            {
              if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
                {
@@ -7770,18 +7822,6 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       return expand_divmod (0, code, mode, op0, op1, target, unsignedp);
 
     case RDIV_EXPR:
-      /* Emit a/b as a*(1/b).  Later we may manage CSE the reciprocal saving
-         expensive divide.  If not, combine will rebuild the original
-         computation.  */
-      if (flag_unsafe_math_optimizations && optimize && !optimize_size
-         && TREE_CODE (type) == REAL_TYPE
-         && !real_onep (TREE_OPERAND (exp, 0)))
-        return expand_expr (build2 (MULT_EXPR, type, TREE_OPERAND (exp, 0),
-                                   build2 (RDIV_EXPR, type,
-                                           build_real (type, dconst1),
-                                           TREE_OPERAND (exp, 1))),
-                           target, tmode, modifier);
-
       goto binop;
 
     case TRUNC_MOD_EXPR:
@@ -7877,9 +7917,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       /* If op1 was placed in target, swap op0 and op1.  */
       if (target != op0 && target == op1)
        {
-         rtx tem = op0;
+         temp = op0;
          op0 = op1;
-         op1 = tem;
+         op1 = temp;
        }
 
       /* We generate better code and avoid problems with op1 mentioning
@@ -7887,10 +7927,51 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       if (! CONSTANT_P (op1))
        op1 = force_reg (mode, op1);
 
+#ifdef HAVE_conditional_move
+      /* Use a conditional move if possible.  */
+      if (can_conditionally_move_p (mode))
+       {
+         enum rtx_code comparison_code;
+         rtx insn;
+
+         if (code == MAX_EXPR)
+           comparison_code = unsignedp ? GEU : GE;
+         else
+           comparison_code = unsignedp ? LEU : LE;
+
+         /* ??? Same problem as in expmed.c: emit_conditional_move
+            forces a stack adjustment via compare_from_rtx, and we
+            lose the stack adjustment if the sequence we are about
+            to create is discarded.  */
+         do_pending_stack_adjust ();
+
+         start_sequence ();
+
+         /* Try to emit the conditional move.  */
+         insn = emit_conditional_move (target, comparison_code,
+                                       op0, op1, mode,
+                                       op0, op1, mode,
+                                       unsignedp);
+
+         /* If we could do the conditional move, emit the sequence,
+            and return.  */
+         if (insn)
+           {
+             rtx seq = get_insns ();
+             end_sequence ();
+             emit_insn (seq);
+             return target;
+           }
+
+         /* Otherwise discard the sequence and fall back to code with
+            branches.  */
+         end_sequence ();
+       }
+#endif
       if (target != op0)
        emit_move_insn (target, op0);
 
-      op0 = gen_label_rtx ();
+      temp = gen_label_rtx ();
 
       /* If this mode is an integer too wide to compare properly,
         compare word by word.  Rely on cse to optimize constant cases.  */
@@ -7899,18 +7980,18 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        {
          if (code == MAX_EXPR)
            do_jump_by_parts_greater_rtx (mode, unsignedp, target, op1,
-                                         NULL_RTX, op0);
+                                         NULL_RTX, temp);
          else
            do_jump_by_parts_greater_rtx (mode, unsignedp, op1, target,
-                                         NULL_RTX, op0);
+                                         NULL_RTX, temp);
        }
       else
        {
          do_compare_rtx_and_jump (target, op1, code == MAX_EXPR ? GE : LE,
-                                  unsignedp, mode, NULL_RTX, NULL_RTX, op0);
+                                  unsignedp, mode, NULL_RTX, NULL_RTX, temp);
        }
       emit_move_insn (target, op1);
-      emit_label (op0);
+      emit_label (temp);
       return target;
 
     case BIT_NOT_EXPR:
@@ -8271,8 +8352,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
         op2 = expand_expr (oprnd2, NULL_RTX, VOIDmode, 0);
         temp = expand_ternary_op (mode, this_optab, op0, op1, op2, 
                                  target, unsignedp);
-        if (temp == 0)
-          abort ();
+        gcc_assert (temp);
         return temp;
       }
 
@@ -8657,8 +8737,7 @@ do_store_flag (tree exp, rtx target, enum machine_mode mode, int only_cheap)
       if ((code == LT && integer_zerop (arg1))
          || (! only_cheap && code == GE && integer_zerop (arg1)))
        ;
-      else if (BRANCH_COST >= 0
-              && ! only_cheap && (code == NE || code == EQ)
+      else if (! only_cheap && (code == NE || code == EQ)
               && TREE_CODE (type) != REAL_TYPE
               && ((abs_optab->handlers[(int) operand_mode].insn_code
                    != CODE_FOR_nothing)
@@ -8902,9 +8981,9 @@ try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
   if (! HAVE_tablejump)
     return 0;
 
-  index_expr = fold (build2 (MINUS_EXPR, index_type,
-                            convert (index_type, index_expr),
-                            convert (index_type, minval)));
+  index_expr = fold_build2 (MINUS_EXPR, index_type,
+                           convert (index_type, index_expr),
+                           convert (index_type, minval));
   index = expand_expr (index_expr, NULL_RTX, VOIDmode, 0);
   do_pending_stack_adjust ();