combine: Do not call simplify from inside change_zero_ext (PR78232)
When combine splits a three-insn combination into two instructions it can reuse i2dest for the temporary result of the first new instruction. However all information it has in reg_stat about that register will be stale. This results in the simplify_gen_binary calls in change_zero_ext using out-of-date information, which makes it think one of the ANDs generated there always results in 0, and it doesn't get better from there. This can also happen if a splitter in the MD uses nonzero_bits (for example). I tried to make the splitting code in combine save and restore the i2dest reg_stat info, but that causes one of the acats tests to fail. This whole reg_stat thing needs an overhaul, and/or we shouldn't reuse i2dest for unrelated purposes when splitting. This patch changes change_zero_ext to do the expected simplifications itself and not call simplify_gen_*. PR rtl-optimization/78232 * combine.c (try_combine): Add a big comment about why reusing i2dest is undesirable. (change_zero_ext): Do not call simplify_gen_binary, do the simplifications manually. From-SVN: r242059
This commit is contained in:
parent
9490321264
commit
071af74db6
2 changed files with 30 additions and 9 deletions
|
@ -1,3 +1,11 @@
|
|||
2016-11-10 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR rtl-optimization/78232
|
||||
* combine.c (try_combine): Add a big comment about why reusing i2dest
|
||||
is undesirable.
|
||||
(change_zero_ext): Do not call simplify_gen_binary, do the
|
||||
simplifications manually.
|
||||
|
||||
2016-11-10 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): If ISA 3.0,
|
||||
|
|
|
@ -3528,6 +3528,15 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
|
|||
{
|
||||
machine_mode new_mode = GET_MODE (SET_DEST (newpat));
|
||||
|
||||
/* ??? Reusing i2dest without resetting the reg_stat entry for it
|
||||
(temporarily, until we are committed to this instruction
|
||||
combination) does not work: for example, any call to nonzero_bits
|
||||
on the register (from a splitter in the MD file, for example)
|
||||
will get the old information, which is invalid.
|
||||
|
||||
Since nowadays we can create registers during combine just fine,
|
||||
we should just create a new one here, not reuse i2dest. */
|
||||
|
||||
/* First try to split using the original register as a
|
||||
scratch register. */
|
||||
parallel = gen_rtx_PARALLEL (VOIDmode,
|
||||
|
@ -11133,8 +11142,10 @@ change_zero_ext (rtx pat)
|
|||
if (BITS_BIG_ENDIAN)
|
||||
start = GET_MODE_PRECISION (mode) - size - start;
|
||||
|
||||
x = simplify_gen_binary (LSHIFTRT, mode,
|
||||
XEXP (x, 0), GEN_INT (start));
|
||||
if (start)
|
||||
x = gen_rtx_LSHIFTRT (mode, XEXP (x, 0), GEN_INT (start));
|
||||
else
|
||||
x = XEXP (x, 0);
|
||||
}
|
||||
else if (GET_CODE (x) == ZERO_EXTEND
|
||||
&& SCALAR_INT_MODE_P (mode)
|
||||
|
@ -11190,16 +11201,18 @@ change_zero_ext (rtx pat)
|
|||
if (BITS_BIG_ENDIAN)
|
||||
offset = reg_width - width - offset;
|
||||
|
||||
rtx x, y, z, w;
|
||||
wide_int mask = wi::shifted_mask (offset, width, true, reg_width);
|
||||
rtx x = gen_rtx_AND (mode, reg, immed_wide_int_const (mask, mode));
|
||||
rtx y = simplify_gen_binary (ASHIFT, mode, SET_SRC (pat),
|
||||
GEN_INT (offset));
|
||||
wide_int mask2 = wi::shifted_mask (offset, width, false, reg_width);
|
||||
y = simplify_gen_binary (AND, mode, y,
|
||||
immed_wide_int_const (mask2, mode));
|
||||
rtx z = simplify_gen_binary (IOR, mode, x, y);
|
||||
x = gen_rtx_AND (mode, reg, immed_wide_int_const (mask, mode));
|
||||
if (offset)
|
||||
y = gen_rtx_ASHIFT (mode, SET_SRC (pat), GEN_INT (offset));
|
||||
else
|
||||
y = SET_SRC (pat);
|
||||
z = gen_rtx_AND (mode, y, immed_wide_int_const (mask2, mode));
|
||||
w = gen_rtx_IOR (mode, x, z);
|
||||
SUBST (SET_DEST (pat), reg);
|
||||
SUBST (SET_SRC (pat), z);
|
||||
SUBST (SET_SRC (pat), w);
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue