diff options
author | Richard Stallman <rms@gnu.org> | 1993-11-10 21:31:41 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1993-11-10 21:31:41 +0000 |
commit | 034f9101fd13d8da0ebf5162bd19bac08791a966 (patch) | |
tree | 9d8171e17a6ac2dc2bf4eb0827c737e5f88eda8c /gcc | |
parent | 29d40fa4d84c0ad8389798f95c97e763f9f522aa (diff) | |
download | gcc-034f9101fd13d8da0ebf5162bd19bac08791a966.zip gcc-034f9101fd13d8da0ebf5162bd19bac08791a966.tar.gz gcc-034f9101fd13d8da0ebf5162bd19bac08791a966.tar.bz2 |
(expand_expr): Use a smaller alignment when reading from a field
with a variable offset.
From-SVN: r6054
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/expr.c | 12 |
1 files changed, 11 insertions, 1 deletions
@@ -4314,6 +4314,7 @@ expand_expr (exp, target, tmode, modifier) int volatilep = 0; tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1, &unsignedp, &volatilep); + int alignment; /* If we got back the original object, something is wrong. Perhaps we are evaluating an expression too early. In any event, don't @@ -4337,6 +4338,7 @@ expand_expr (exp, target, tmode, modifier) op0 = validize_mem (force_const_mem (mode, op0)); } + alignment = TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT; if (offset != 0) { rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0); @@ -4346,6 +4348,14 @@ expand_expr (exp, target, tmode, modifier) op0 = change_address (op0, VOIDmode, gen_rtx (PLUS, Pmode, XEXP (op0, 0), force_reg (Pmode, offset_rtx))); + /* If we have a variable offset, the known alignment + is only that of the innermost structure containing the field. + (Actually, we could sometimes do better by using the + size of an element of the innermost array, but no need.) */ + if (TREE_CODE (exp) == COMPONENT_REF + || TREE_CODE (exp) == BIT_FIELD_REF) + alignment = (TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (exp, 0))) + / BITS_PER_UNIT); } /* Don't forget about volatility even if this is a bitfield. */ @@ -4382,7 +4392,7 @@ expand_expr (exp, target, tmode, modifier) op0 = extract_bit_field (validize_mem (op0), bitsize, bitpos, unsignedp, target, ext_mode, ext_mode, - TYPE_ALIGN (TREE_TYPE (tem)) / BITS_PER_UNIT, + alignment, int_size_in_bytes (TREE_TYPE (tem))); if (mode == BLKmode) { |