aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2003-07-02 09:41:07 +0200
committerEric Botcazou <ebotcazou@gcc.gnu.org>2003-07-02 07:41:07 +0000
commit1a8c4ca62da430aa2d8920b70f1614ab0755059b (patch)
tree2f0ff7e67c577a96205f1a538d682dfa6c362eb3 /gcc
parent23cdfcf71f295697ac4322f0a0e8128e22e834b4 (diff)
downloadgcc-1a8c4ca62da430aa2d8920b70f1614ab0755059b.zip
gcc-1a8c4ca62da430aa2d8920b70f1614ab0755059b.tar.gz
gcc-1a8c4ca62da430aa2d8920b70f1614ab0755059b.tar.bz2
re PR rtl-optimization/11210 (optimizer drops conditional with typecast from signed to unsigned char)
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. From-SVN: r68823
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/expr.c3
-rw-r--r--gcc/fold-const.c14
3 files changed, 27 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1162a58..edc420b 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 a581b17..8049020 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 25069c5..3cc01ea 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);