diff options
Diffstat (limited to 'gcc/combine.cc')
-rw-r--r-- | gcc/combine.cc | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/gcc/combine.cc b/gcc/combine.cc index 873c2bd..4dbc1f6 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -458,6 +458,7 @@ static rtx simplify_shift_const (rtx, enum rtx_code, machine_mode, rtx, int); static int recog_for_combine (rtx *, rtx_insn *, rtx *, unsigned = 0, unsigned = 0); static rtx gen_lowpart_for_combine (machine_mode, rtx); +static rtx gen_lowpart_for_combine_no_emit (machine_mode, rtx); static enum rtx_code simplify_compare_const (enum rtx_code, machine_mode, rtx *, rtx *); static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *); @@ -491,7 +492,7 @@ static rtx gen_lowpart_or_truncate (machine_mode, rtx); /* Our implementation of gen_lowpart never emits a new pseudo. */ #undef RTL_HOOKS_GEN_LOWPART_NO_EMIT -#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_for_combine +#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_for_combine_no_emit #undef RTL_HOOKS_REG_NONZERO_REG_BITS #define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_for_combine @@ -4020,34 +4021,34 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, in i3, so we need to make sure that we won't wrongly hoist a SET to i2 that would conflict with a death note present in there, or would have its dest modified or used between i2 and i3. */ - if (!modified_between_p (SET_SRC (set1), i2, i3) - && !(REG_P (SET_DEST (set1)) - && find_reg_note (i2, REG_DEAD, SET_DEST (set1))) - && !(GET_CODE (SET_DEST (set1)) == SUBREG - && find_reg_note (i2, REG_DEAD, - SUBREG_REG (SET_DEST (set1)))) - && SET_DEST (set1) != pc_rtx - && !reg_used_between_p (SET_DEST (set1), i2, i3) + if ((set_noop_p (set1) + || (!modified_between_p (SET_SRC (set1), i2, i3) + && !(REG_P (SET_DEST (set1)) + && find_reg_note (i2, REG_DEAD, SET_DEST (set1))) + && !(GET_CODE (SET_DEST (set1)) == SUBREG + && find_reg_note (i2, REG_DEAD, + SUBREG_REG (SET_DEST (set1)))) + && SET_DEST (set1) != pc_rtx + && !reg_used_between_p (SET_DEST (set1), i2, i3))) /* If I3 is a jump, ensure that set0 is a jump so that we do not create invalid RTL. */ - && (!JUMP_P (i3) || SET_DEST (set0) == pc_rtx) - ) + && (!JUMP_P (i3) || SET_DEST (set0) == pc_rtx)) { newi2pat = set1; newpat = set0; } - else if (!modified_between_p (SET_SRC (set0), i2, i3) - && !(REG_P (SET_DEST (set0)) - && find_reg_note (i2, REG_DEAD, SET_DEST (set0))) - && !(GET_CODE (SET_DEST (set0)) == SUBREG - && find_reg_note (i2, REG_DEAD, - SUBREG_REG (SET_DEST (set0)))) - && SET_DEST (set0) != pc_rtx - && !reg_used_between_p (SET_DEST (set0), i2, i3) + else if ((set_noop_p (set0) + || (!modified_between_p (SET_SRC (set0), i2, i3) + && !(REG_P (SET_DEST (set0)) + && find_reg_note (i2, REG_DEAD, SET_DEST (set0))) + && !(GET_CODE (SET_DEST (set0)) == SUBREG + && find_reg_note (i2, REG_DEAD, + SUBREG_REG (SET_DEST (set0)))) + && SET_DEST (set0) != pc_rtx + && !reg_used_between_p (SET_DEST (set0), i2, i3))) /* If I3 is a jump, ensure that set1 is a jump so that we do not create invalid RTL. */ - && (!JUMP_P (i3) || SET_DEST (set1) == pc_rtx) - ) + && (!JUMP_P (i3) || SET_DEST (set1) == pc_rtx)) { newi2pat = set0; newpat = set1; @@ -11890,6 +11891,22 @@ gen_lowpart_for_combine (machine_mode omode, rtx x) fail: return gen_rtx_CLOBBER (omode, const0_rtx); } + +/* Like gen_lowpart_for_combine but returns NULL_RTX + for an error instead of CLOBBER. + Note no_emit is not called directly from combine but rather from + simplify_rtx and is expecting a NULL on failure rather than + a CLOBBER. */ + +static rtx +gen_lowpart_for_combine_no_emit (machine_mode omode, rtx x) +{ + rtx tem = gen_lowpart_for_combine (omode, x); + if (!tem || GET_CODE (tem) == CLOBBER) + return NULL_RTX; + return tem; +} + /* Try to simplify a comparison between OP0 and a constant OP1, where CODE is the comparison code that will be tested, into a |