summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
21e5ba9)
* tree-sra.c (instantiate_element): Use BYTES_BIG_ENDIAN for
bit-field layout.
(sra_build_assignment): Likewise. Set up mask depending on
precision, not type.
(sra_build_bf_assignment): Use BYTES_BIG_ENDIAN. Don't overflow
computing bit masks.
(sra_build_elt_assignment): Don't view-convert from signed to
unsigned.
(sra_explode_bitfield_assignment): Use bit-field type if
possible. Use BYTES_BIG_ENDIAN.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129150
138bc75d-0d04-0410-961f-
82ee72b054a4
+2007-10-09 Alexandre Oliva <aoliva@redhat.com>
+
+ PR middle-end/22156
+ * tree-sra.c (instantiate_element): Use BYTES_BIG_ENDIAN for
+ bit-field layout.
+ (sra_build_assignment): Likewise. Set up mask depending on
+ precision, not type.
+ (sra_build_bf_assignment): Use BYTES_BIG_ENDIAN. Don't overflow
+ computing bit masks.
+ (sra_build_elt_assignment): Don't view-convert from signed to
+ unsigned.
+ (sra_explode_bitfield_assignment): Use bit-field type if
+ possible. Use BYTES_BIG_ENDIAN.
+
2007-10-08 Alexandre Oliva <aoliva@redhat.com>
PR middle-end/22156
2007-10-08 Alexandre Oliva <aoliva@redhat.com>
PR middle-end/22156
elt->in_bitfld_block = 1;
elt->replacement = build3 (BIT_FIELD_REF, elt->type, var,
DECL_SIZE (var),
elt->in_bitfld_block = 1;
elt->replacement = build3 (BIT_FIELD_REF, elt->type, var,
DECL_SIZE (var),
? size_binop (MINUS_EXPR,
TYPE_SIZE (elt->type),
DECL_SIZE (var))
? size_binop (MINUS_EXPR,
TYPE_SIZE (elt->type),
DECL_SIZE (var))
cst2 = size_binop (PLUS_EXPR, TREE_OPERAND (src, 1),
TREE_OPERAND (src, 2));
cst2 = size_binop (PLUS_EXPR, TREE_OPERAND (src, 1),
TREE_OPERAND (src, 2));
{
maxshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst);
minshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst2);
{
maxshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst);
minshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst2);
list = NULL;
cst2 = size_binop (MINUS_EXPR, maxshift, minshift);
list = NULL;
cst2 = size_binop (MINUS_EXPR, maxshift, minshift);
- if (tree_int_cst_equal (cst2, TYPE_SIZE (utype)))
+ if (TREE_INT_CST_LOW (cst2) == TYPE_PRECISION (utype))
{
unsignedp = true;
mask = NULL_TREE;
{
unsignedp = true;
mask = NULL_TREE;
fold_convert (bitsizetype, TREE_OPERAND (dst, 1)),
cst);
fold_convert (bitsizetype, TREE_OPERAND (dst, 1)),
cst);
{
maxshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst);
minshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst2);
{
maxshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst);
minshift = size_binop (MINUS_EXPR, TYPE_SIZE (TREE_TYPE (var)), cst2);
utype = unsigned_type_for (type);
mask = build_int_cst_wide (utype, 1, 0);
utype = unsigned_type_for (type);
mask = build_int_cst_wide (utype, 1, 0);
- cst = int_const_binop (LSHIFT_EXPR, mask, maxshift, true);
- cst2 = int_const_binop (LSHIFT_EXPR, mask, minshift, true);
+ if (TREE_INT_CST_LOW (maxshift) == TYPE_PRECISION (utype))
+ cst = build_int_cst_wide (utype, 0, 0);
+ else
+ cst = int_const_binop (LSHIFT_EXPR, mask, maxshift, true);
+ if (integer_zerop (minshift))
+ cst2 = mask;
+ else
+ cst2 = int_const_binop (LSHIFT_EXPR, mask, minshift, true);
mask = int_const_binop (MINUS_EXPR, cst, cst2, true);
mask = fold_build1 (BIT_NOT_EXPR, utype, mask);
mask = int_const_binop (MINUS_EXPR, cst, cst2, true);
mask = fold_build1 (BIT_NOT_EXPR, utype, mask);
- if (!INTEGRAL_TYPE_P (TREE_TYPE (src))
- || !TYPE_UNSIGNED (TREE_TYPE (src)))
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (src)))
src = fold_build1 (VIEW_CONVERT_EXPR,
lang_hooks.types.type_for_size
(TREE_INT_CST_LOW
(TYPE_SIZE (TREE_TYPE (src))),
1), src);
src = fold_build1 (VIEW_CONVERT_EXPR,
lang_hooks.types.type_for_size
(TREE_INT_CST_LOW
(TYPE_SIZE (TREE_TYPE (src))),
1), src);
+ gcc_assert (TYPE_UNSIGNED (TREE_TYPE (src)));
tmp = make_rename_temp (TREE_TYPE (src), "SR");
stmt = build_gimple_modify_stmt (tmp, src);
tmp = make_rename_temp (TREE_TYPE (src), "SR");
stmt = build_gimple_modify_stmt (tmp, src);
+ tree infld, invar, st, type;
infld = fld->replacement;
infld = fld->replacement;
+ type = TREE_TYPE (infld);
+ if (TYPE_PRECISION (type) != TREE_INT_CST_LOW (flen))
+ type = lang_hooks.types.type_for_size (TREE_INT_CST_LOW (flen), 1);
+
if (TREE_CODE (infld) == BIT_FIELD_REF)
{
fpos = size_binop (PLUS_EXPR, fpos, TREE_OPERAND (infld, 2));
infld = TREE_OPERAND (infld, 0);
}
if (TREE_CODE (infld) == BIT_FIELD_REF)
{
fpos = size_binop (PLUS_EXPR, fpos, TREE_OPERAND (infld, 2));
infld = TREE_OPERAND (infld, 0);
}
- else if (BITS_BIG_ENDIAN && DECL_P (fld->element)
+ else if (BYTES_BIG_ENDIAN && DECL_P (fld->element)
&& !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (infld)),
DECL_SIZE (fld->element)))
{
&& !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (infld)),
DECL_SIZE (fld->element)))
{
DECL_SIZE (fld->element));
}
DECL_SIZE (fld->element));
}
- infld = fold_build3 (BIT_FIELD_REF,
- lang_hooks.types.type_for_size
- (TREE_INT_CST_LOW (flen), 1),
- infld, flen, fpos);
+ infld = fold_build3 (BIT_FIELD_REF, type, infld, flen, fpos);
BIT_FIELD_REF_UNSIGNED (infld) = 1;
invar = size_binop (MINUS_EXPR, flp.field_pos, bpos);
BIT_FIELD_REF_UNSIGNED (infld) = 1;
invar = size_binop (MINUS_EXPR, flp.field_pos, bpos);
invar = size_binop (PLUS_EXPR, invar, flp.overlap_pos);
invar = size_binop (PLUS_EXPR, invar, vpos);
invar = size_binop (PLUS_EXPR, invar, flp.overlap_pos);
invar = size_binop (PLUS_EXPR, invar, vpos);
- invar = fold_build3 (BIT_FIELD_REF, TREE_TYPE (infld),
- var, flen, invar);
+ invar = fold_build3 (BIT_FIELD_REF, type, var, flen, invar);
BIT_FIELD_REF_UNSIGNED (invar) = 1;
if (to_var)
BIT_FIELD_REF_UNSIGNED (invar) = 1;
if (to_var)