new = simplify_unary_operation (code, mode,
const_arg0 ? const_arg0 : folded_arg0,
mode_arg0);
- if (new != 0 && is_const)
+ /* NEG of PLUS could be converted into MINUS, but that causes
+ expressions of the form
+ (CONST (MINUS (CONST_INT) (SYMBOL_REF)))
+ which many ports mistakenly treat as LEGITIMATE_CONSTANT_P.
+ FIXME: those ports should be fixed. */
+ if (new != 0 && is_const
+ && GET_CODE (new) == PLUS
+ && (GET_CODE (XEXP (new, 0)) == SYMBOL_REF
+ || GET_CODE (XEXP (new, 0)) == LABEL_REF)
+ && GET_CODE (XEXP (new, 1)) == CONST_INT)
new = gen_rtx_CONST (mode, new);
}
break;
|| (GET_CODE (trial) == LABEL_REF
&& ! condjump_p (insn))))
{
+ /* Don't substitute non-local labels, this confuses CFG. */
+ if (GET_CODE (trial) == LABEL_REF
+ && LABEL_REF_NONLOCAL_P (trial))
+ continue;
+
SET_SRC (sets[i].rtl) = trial;
cse_jumps_altered = 1;
break;
/* If this SET is now setting PC to a label, we know it used to
be a conditional or computed branch. */
- else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF)
+ else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF
+ && !LABEL_REF_NONLOCAL_P (src))
{
/* Now emit a BARRIER after the unconditional jump. */
if (NEXT_INSN (insn) == 0
rtx last_insns[2];
unsigned int i;
rtx newreg;
+ edge_iterator ei;
/* We expect to have two successors. Look at both before picking
the final mode for the comparison. If we have more successors
found_equiv = false;
mode = GET_MODE (cc_src);
insn_count = 0;
- for (e = bb->succ; e; e = e->succ_next)
+ FOR_EACH_EDGE (e, ei, bb->succs)
{
rtx insn;
rtx end;
if (e->flags & EDGE_COMPLEX)
continue;
- if (! e->dest->pred
- || e->dest->pred->pred_next
+ if (EDGE_COUNT (e->dest->preds) != 1
|| e->dest == EXIT_BLOCK_PTR)
continue;