diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-07-02 07:41:07 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-07-02 07:41:07 +0000 |
commit | 74878f86c8e599ce62202c57d0ea3ad48bbf8abd (patch) | |
tree | 2f0ff7e67c577a96205f1a538d682dfa6c362eb3 /gcc | |
parent | bed136558e0956b7e52bb3e1e7cb1cd74f7b5bc5 (diff) | |
download | ppe42-gcc-74878f86c8e599ce62202c57d0ea3ad48bbf8abd.tar.gz ppe42-gcc-74878f86c8e599ce62202c57d0ea3ad48bbf8abd.zip |
PR optimization/11210
* expr.c (handled_component_p) [NOP_EXPR]: Add ??? note
about the behaviour with regard to bitfields.
* fold-const (decode_field_reference): Record outermost type in
case the expression is a NOP. Strip all NOPs. Set the signedness
to that of the outermost type (if any) when the bitsize is equal
to the size of the type.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@68823 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/expr.c | 3 | ||||
-rw-r--r-- | gcc/fold-const.c | 14 |
3 files changed, 27 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1162a586601..edc420bec75 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2003-07-02 Eric Botcazou <ebotcazou@libertysurf.fr> + + PR optimization/11210 + * expr.c (handled_component_p) [NOP_EXPR]: Add ??? note + about the behaviour with regard to bitfields. + * fold-const (decode_field_reference): Record outermost type in + case the expression is a NOP. Strip all NOPs. Set the signedness + to that of the outermost type (if any) when the bitsize is equal + to the size of the type. + 2003-07-02 Richard Sandiford <rsandifo@redhat.com> * config/mips/mips.md (addsi3): Remove workaround for adds of -32768. diff --git a/gcc/expr.c b/gcc/expr.c index a581b178802..8049020d3d3 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5903,6 +5903,9 @@ handled_component_p (tree t) case VIEW_CONVERT_EXPR: return 1; + /* ??? Sure they are handled, but get_inner_reference may return + a different PBITSIZE, depending upon whether the expression is + wrapped up in a NOP_EXPR or not, e.g. for bitfields. */ case NOP_EXPR: case CONVERT_EXPR: return (TYPE_MODE (TREE_TYPE (t)) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 25069c58f12..3cc01ea0765 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -2625,6 +2625,7 @@ decode_field_reference (tree exp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpo enum machine_mode *pmode, int *punsignedp, int *pvolatilep, tree *pmask, tree *pand_mask) { + tree outer_type = 0; tree and_mask = 0; tree mask, inner, offset; tree unsigned_type; @@ -2636,6 +2637,13 @@ decode_field_reference (tree exp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpo if (! INTEGRAL_TYPE_P (TREE_TYPE (exp))) return 0; + /* We are interested in the bare arrangement of bits, so strip everything + that doesn't affect the machine mode. However, record the type of the + outermost expression if it may matter below. */ + if (TREE_CODE (exp) == NOP_EXPR + || TREE_CODE (exp) == CONVERT_EXPR + || TREE_CODE (exp) == NON_LVALUE_EXPR) + outer_type = TREE_TYPE (exp); STRIP_NOPS (exp); if (TREE_CODE (exp) == BIT_AND_EXPR) @@ -2654,6 +2662,12 @@ decode_field_reference (tree exp, HOST_WIDE_INT *pbitsize, HOST_WIDE_INT *pbitpo || TREE_CODE (inner) == PLACEHOLDER_EXPR) return 0; + /* If the number of bits in the reference is the same as the bitsize of + the outer type, then the outer type gives the signedness. Otherwise + (in case of a small bitfield) the signedness is unchanged. */ + if (outer_type && *pbitsize == tree_low_cst (TYPE_SIZE (outer_type), 1)) + *punsignedp = TREE_UNSIGNED (outer_type); + /* Compute the mask to access the bitfield. */ unsigned_type = (*lang_hooks.types.type_for_size) (*pbitsize, 1); precision = TYPE_PRECISION (unsigned_type); |