diff options
Diffstat (limited to 'gcc-4.8/gcc/combine.c')
-rw-r--r-- | gcc-4.8/gcc/combine.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/gcc-4.8/gcc/combine.c b/gcc-4.8/gcc/combine.c index a589cfadb..8e3dff3f5 100644 --- a/gcc-4.8/gcc/combine.c +++ b/gcc-4.8/gcc/combine.c @@ -3884,15 +3884,19 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p, PATTERN (undobuf.other_insn) = other_pat; - /* If any of the notes in OTHER_INSN were REG_UNUSED, ensure that they - are still valid. Then add any non-duplicate notes added by - recog_for_combine. */ + /* If any of the notes in OTHER_INSN were REG_DEAD or REG_UNUSED, + ensure that they are still valid. Then add any non-duplicate + notes added by recog_for_combine. */ for (note = REG_NOTES (undobuf.other_insn); note; note = next) { next = XEXP (note, 1); - if (REG_NOTE_KIND (note) == REG_UNUSED - && ! reg_set_p (XEXP (note, 0), PATTERN (undobuf.other_insn))) + if ((REG_NOTE_KIND (note) == REG_DEAD + && !reg_referenced_p (XEXP (note, 0), + PATTERN (undobuf.other_insn))) + ||(REG_NOTE_KIND (note) == REG_UNUSED + && !reg_set_p (XEXP (note, 0), + PATTERN (undobuf.other_insn)))) remove_note (undobuf.other_insn, note); } @@ -5798,8 +5802,15 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest, return x; } - /* If the code changed, return a whole new comparison. */ - if (new_code != code) + /* If the code changed, return a whole new comparison. + We also need to avoid using SUBST in cases where + simplify_comparison has widened a comparison with a CONST_INT, + since in that case the wider CONST_INT may fail the sanity + checks in do_SUBST. */ + if (new_code != code + || (CONST_INT_P (op1) + && GET_MODE (op0) != GET_MODE (XEXP (x, 0)) + && GET_MODE (op0) != GET_MODE (XEXP (x, 1)))) return gen_rtx_fmt_ee (new_code, mode, op0, op1); /* Otherwise, keep this operation, but maybe change its operands. @@ -7991,7 +8002,7 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, if (code == CALL || code == ASM_OPERANDS || code == CLOBBER) return x; - /* We want to perform the operation is its present mode unless we know + /* We want to perform the operation in its present mode unless we know that the operation is valid in MODE, in which case we do the operation in MODE. */ op_mode = ((GET_MODE_CLASS (mode) == GET_MODE_CLASS (GET_MODE (x)) @@ -8427,9 +8438,10 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, GET_MODE (x), GEN_INT (mask), XEXP (x, 1)); if (temp && CONST_INT_P (temp)) - SUBST (XEXP (x, 0), + x = simplify_gen_binary (code, GET_MODE (x), force_to_mode (XEXP (x, 0), GET_MODE (x), - INTVAL (temp), next_select)); + INTVAL (temp), next_select), + XEXP (x, 1)); } break; @@ -8497,14 +8509,16 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask, /* We have no way of knowing if the IF_THEN_ELSE can itself be written in a narrower mode. We play it safe and do not do so. */ - SUBST (XEXP (x, 1), - gen_lowpart_or_truncate (GET_MODE (x), + op0 = gen_lowpart_or_truncate (GET_MODE (x), force_to_mode (XEXP (x, 1), mode, - mask, next_select))); - SUBST (XEXP (x, 2), - gen_lowpart_or_truncate (GET_MODE (x), + mask, next_select)); + op1 = gen_lowpart_or_truncate (GET_MODE (x), force_to_mode (XEXP (x, 2), mode, - mask, next_select))); + mask, next_select)); + if (op0 != XEXP (x, 1) || op1 != XEXP (x, 2)) + x = simplify_gen_ternary (IF_THEN_ELSE, GET_MODE (x), + GET_MODE (XEXP (x, 0)), XEXP (x, 0), + op0, op1); break; default: |