/* First substitute in the INSN condition as the SET_SRC of the JUMP,
then substitute that given values in this expanded JUMP. */
- if (setcc != NULL)
+ if (setcc != NULL
+ && !modified_between_p (from, setcc, jump)
+ && !modified_between_p (src, setcc, jump))
{
rtx setcc_set = single_set (setcc);
new_set = simplify_replace_rtx (SET_SRC (set),
/* If no simplification can be made, then try the next
register. */
- if (rtx_equal_p (new, new_set))
+ if (rtx_equal_p (new, new_set) || rtx_equal_p (new, SET_SRC (set)))
return 0;
/* If this is now a no-op delete it, otherwise this must be a valid insn. */
delete_insn (jump);
else
{
+ /* Ensure the value computed inside the jump insn to be equivalent
+ to one computed by setcc. */
+ if (setcc
+ && modified_in_p (new, setcc))
+ return 0;
if (! validate_change (jump, &SET_SRC (set), new, 0))
return 0;
/* LIBCALL_SP is a zero-terminated array of insns at the end of a libcall;
their REG_EQUAL notes need updating. */
+
static bool
do_local_cprop (x, insn, alter_jumps, libcall_sp)
rtx x;
{
rtx newreg = NULL, newcnst = NULL;
- /* Rule out USE instructions and ASM statements as we don't want to change the hard registers mentioned. */
+ /* Rule out USE instructions and ASM statements as we don't want to
+ change the hard registers mentioned. */
if (GET_CODE (x) == REG
&& (REGNO (x) >= FIRST_PSEUDO_REGISTER
- || (GET_CODE (PATTERN (insn)) != USE && asm_noperands (PATTERN (insn)) < 0)))
+ || (GET_CODE (PATTERN (insn)) != USE
+ && asm_noperands (PATTERN (insn)) < 0)))
{
cselib_val *val = cselib_lookup (x, GET_MODE (x), 0);
struct elt_loc_list *l;
else
eqv = SET_SRC (set);
- set_unique_reg_note (new, REG_EQUAL, copy_insn_1 (src));
+ set_unique_reg_note (new, REG_EQUAL, copy_insn_1 (eqv));
return new;
}