re PR middle-end/18008 (Duplicate mask on bitfield insertion)
PR middle-end/18008 * combine.c (make_field_assignment): Simplify store to zero_extract from a source with an overlapping mask. From-SVN: r94282
This commit is contained in:
parent
d951ae1e66
commit
55e79aef81
2 changed files with 48 additions and 11 deletions
|
@ -1,3 +1,9 @@
|
|||
2005-01-26 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR middle-end/18008
|
||||
* combine.c (make_field_assignment): Simplify store to zero_extract
|
||||
from a source with an overlapping mask.
|
||||
|
||||
2005-01-26 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
2004-11-11 Eric Christopher <echristo@redhat.com>
|
||||
|
|
|
@ -7815,14 +7815,14 @@ make_field_assignment (rtx x)
|
|||
return x;
|
||||
}
|
||||
|
||||
else if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG
|
||||
&& subreg_lowpart_p (XEXP (src, 0))
|
||||
&& (GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
|
||||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0)))))
|
||||
&& GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
|
||||
&& GET_CODE (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == CONST_INT
|
||||
&& INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
|
||||
&& rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
|
||||
if (GET_CODE (src) == AND && GET_CODE (XEXP (src, 0)) == SUBREG
|
||||
&& subreg_lowpart_p (XEXP (src, 0))
|
||||
&& (GET_MODE_SIZE (GET_MODE (XEXP (src, 0)))
|
||||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (XEXP (src, 0)))))
|
||||
&& GET_CODE (SUBREG_REG (XEXP (src, 0))) == ROTATE
|
||||
&& GET_CODE (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == CONST_INT
|
||||
&& INTVAL (XEXP (SUBREG_REG (XEXP (src, 0)), 0)) == -2
|
||||
&& rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
|
||||
{
|
||||
assign = make_extraction (VOIDmode, dest, 0,
|
||||
XEXP (SUBREG_REG (XEXP (src, 0)), 1),
|
||||
|
@ -7834,9 +7834,9 @@ make_field_assignment (rtx x)
|
|||
|
||||
/* If SRC is (ior (ashift (const_int 1) POS) DEST), this is a set of a
|
||||
one-bit field. */
|
||||
else if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT
|
||||
&& XEXP (XEXP (src, 0), 0) == const1_rtx
|
||||
&& rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
|
||||
if (GET_CODE (src) == IOR && GET_CODE (XEXP (src, 0)) == ASHIFT
|
||||
&& XEXP (XEXP (src, 0), 0) == const1_rtx
|
||||
&& rtx_equal_for_field_assignment_p (dest, XEXP (src, 1)))
|
||||
{
|
||||
assign = make_extraction (VOIDmode, dest, 0, XEXP (XEXP (src, 0), 1),
|
||||
1, 1, 1, 0);
|
||||
|
@ -7845,6 +7845,37 @@ make_field_assignment (rtx x)
|
|||
return x;
|
||||
}
|
||||
|
||||
/* If DEST is already a field assignment, i.e. ZERO_EXTRACT, and the
|
||||
SRC is an AND with all bits of that field set, then we can discard
|
||||
the AND. */
|
||||
if (GET_CODE (dest) == ZERO_EXTRACT
|
||||
&& GET_CODE (XEXP (dest, 1)) == CONST_INT
|
||||
&& GET_CODE (src) == AND
|
||||
&& GET_CODE (XEXP (src, 1)) == CONST_INT)
|
||||
{
|
||||
HOST_WIDE_INT width = INTVAL (XEXP (dest, 1));
|
||||
unsigned HOST_WIDE_INT and_mask = INTVAL (XEXP (src, 1));
|
||||
unsigned HOST_WIDE_INT ze_mask;
|
||||
|
||||
if (width >= HOST_BITS_PER_WIDE_INT)
|
||||
ze_mask = -1;
|
||||
else
|
||||
ze_mask = ((unsigned HOST_WIDE_INT)1 << width) - 1;
|
||||
|
||||
/* Complete overlap. We can remove the source AND. */
|
||||
if ((and_mask & ze_mask) == ze_mask)
|
||||
return gen_rtx_SET (VOIDmode, dest, XEXP (src, 0));
|
||||
|
||||
/* Partial overlap. We can reduce the source AND. */
|
||||
if ((and_mask & ze_mask) != and_mask)
|
||||
{
|
||||
mode = GET_MODE (src);
|
||||
src = gen_rtx_AND (mode, XEXP (src, 0),
|
||||
gen_int_mode (mode, and_mask & ze_mask));
|
||||
return gen_rtx_SET (VOIDmode, dest, src);
|
||||
}
|
||||
}
|
||||
|
||||
/* The other case we handle is assignments into a constant-position
|
||||
field. They look like (ior/xor (and DEST C1) OTHER). If C1 represents
|
||||
a mask that has all one bits except for a group of zero bits and
|
||||
|
|
Loading…
Add table
Reference in a new issue