summaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-17 06:42:12 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2016-04-17 06:42:12 +0000
commitbd356bb6d247b18723734d4d1d0b32191cfb1a9a (patch)
tree1882cabb94561f964beaa242d722700c4239ab25 /gcc/combine.c
parentc8aed844acdc89884d630c7e3266ecd8d4101847 (diff)
downloadgcc-bd356bb6d247b18723734d4d1d0b32191cfb1a9a.tar.gz
2016-04-17 Basile Starynkevitch <basile@starynkevitch.net>
{{merging with even more of GCC 6, using subversion 1.9 svn merge -r232606:233050 ^/trunk }} [gcc/] 2016-04-17 Basile Starynkevitch <basile@starynkevitch.net> * melt/libmelt-ana-gimple.melt: (gimple_transaction): Use gimple_transaction_label_norm. Not sure that (gccif "6." ...) does what it should... git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@235078 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index 2f913dd8ea9..c307793a495 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1454,15 +1454,21 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
&& ! unmentioned_reg_p (note, SET_SRC (set))
&& (GET_MODE (note) == VOIDmode
? SCALAR_INT_MODE_P (GET_MODE (SET_DEST (set)))
- : GET_MODE (SET_DEST (set)) == GET_MODE (note)))
+ : (GET_MODE (SET_DEST (set)) == GET_MODE (note)
+ && (GET_CODE (SET_DEST (set)) != ZERO_EXTRACT
+ || (GET_MODE (XEXP (SET_DEST (set), 0))
+ == GET_MODE (note))))))
{
/* Temporarily replace the set's source with the
contents of the REG_EQUAL note. The insn will
be deleted or recognized by try_combine. */
- rtx orig = SET_SRC (set);
+ rtx orig_src = SET_SRC (set);
+ rtx orig_dest = SET_DEST (set);
+ if (GET_CODE (SET_DEST (set)) == ZERO_EXTRACT)
+ SET_DEST (set) = XEXP (SET_DEST (set), 0);
SET_SRC (set) = note;
i2mod = temp;
- i2mod_old_rhs = copy_rtx (orig);
+ i2mod_old_rhs = copy_rtx (orig_src);
i2mod_new_rhs = copy_rtx (note);
next = try_combine (insn, i2mod, NULL, NULL,
&new_direct_jump_p,
@@ -1473,7 +1479,8 @@ combine_instructions (rtx_insn *f, unsigned int nregs)
statistics_counter_event (cfun, "insn-with-note combine", 1);
goto retry;
}
- SET_SRC (set) = orig;
+ SET_SRC (set) = orig_src;
+ SET_DEST (set) = orig_dest;
}
}
@@ -7880,11 +7887,25 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
&& (i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
{
- new_rtx = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
- next_code);
- new_rtx = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new_rtx, 0,
- XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
- 0, in_code == COMPARE);
+ rtx inner_x0 = SUBREG_REG (XEXP (x, 0));
+ machine_mode inner_mode = GET_MODE (inner_x0);
+ new_rtx = make_compound_operation (XEXP (inner_x0, 0), next_code);
+ new_rtx = make_extraction (inner_mode, new_rtx, 0,
+ XEXP (inner_x0, 1),
+ i, 1, 0, in_code == COMPARE);
+
+ if (new_rtx)
+ {
+ /* If we narrowed the mode when dropping the subreg, then
+ we must zero-extend to keep the semantics of the AND. */
+ if (GET_MODE_SIZE (inner_mode) >= GET_MODE_SIZE (mode))
+ ;
+ else if (SCALAR_INT_MODE_P (inner_mode))
+ new_rtx = simplify_gen_unary (ZERO_EXTEND, mode,
+ new_rtx, inner_mode);
+ else
+ new_rtx = NULL;
+ }
/* If that didn't give anything, see if the AND simplifies on
its own. */