mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-17 10:20:33 +08:00
re PR c/87691 (transparent_union attribute does not work with MODE_PARTIAL_INT)
2018-11-07 Jozef Lawrynowicz <jozef.l@mittosystems.com> PR c/87691 gcc/ChangeLog: * stor-layout.c (compute_record_mode): Set TYPE_MODE of UNION_TYPE to the mode of the widest field iff the widest field has mode class MODE_INT, or MODE_PARTIAL_INT and the union would be passed by reference. gcc/testsuite/ChangeLog: * gcc.target/msp430/pr87691.c: New test. From-SVN: r265894
This commit is contained in:
parent
e217792bed
commit
c2ca29d5a3
@ -1,9 +1,17 @@
|
||||
2018-11-17 Nikolai Merinov <n.merinov@inango-systems.com>
|
||||
2018-11-07 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
|
||||
* common.opt: Add -Wattribute-warning.
|
||||
* doc/invoke.texi: Add documentation for -Wno-attribute-warning.
|
||||
* expr.c (expand_expr_real_1): Add new attribute to warning_at
|
||||
call to allow user configure behavior of "warning" attribute.
|
||||
PR c/87691
|
||||
* stor-layout.c (compute_record_mode): Set TYPE_MODE of UNION_TYPE
|
||||
to the mode of the widest field iff the widest field has mode class
|
||||
MODE_INT, or MODE_PARTIAL_INT and the union would be passed by
|
||||
reference.
|
||||
|
||||
2018-11-07 Nikolai Merinov <n.merinov@inango-systems.com>
|
||||
|
||||
* common.opt: Add -Wattribute-warning.
|
||||
* doc/invoke.texi: Add documentation for -Wno-attribute-warning.
|
||||
* expr.c (expand_expr_real_1): Add new attribute to warning_at
|
||||
call to allow user configure behavior of "warning" attribute.
|
||||
|
||||
2018-11-07 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
|
@ -1834,7 +1834,13 @@ compute_record_mode (tree type)
|
||||
/* If this field is the whole struct, remember its mode so
|
||||
that, say, we can put a double in a class into a DF
|
||||
register instead of forcing it to live in the stack. */
|
||||
if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
|
||||
if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field))
|
||||
/* Partial int types (e.g. __int20) may have TYPE_SIZE equal to
|
||||
wider types (e.g. int32), despite precision being less. Ensure
|
||||
that the TYPE_MODE of the struct does not get set to the partial
|
||||
int mode if there is a wider type also in the struct. */
|
||||
&& known_gt (GET_MODE_PRECISION (DECL_MODE (field)),
|
||||
GET_MODE_PRECISION (mode)))
|
||||
mode = DECL_MODE (field);
|
||||
|
||||
/* With some targets, it is sub-optimal to access an aligned
|
||||
@ -1844,10 +1850,17 @@ compute_record_mode (tree type)
|
||||
}
|
||||
|
||||
/* If we only have one real field; use its mode if that mode's size
|
||||
matches the type's size. This only applies to RECORD_TYPE. This
|
||||
does not apply to unions. */
|
||||
matches the type's size. This generally only applies to RECORD_TYPE.
|
||||
For UNION_TYPE, if the widest field is MODE_INT then use that mode.
|
||||
If the widest field is MODE_PARTIAL_INT, and the union will be passed
|
||||
by reference, then use that mode. */
|
||||
poly_uint64 type_size;
|
||||
if (TREE_CODE (type) == RECORD_TYPE
|
||||
if ((TREE_CODE (type) == RECORD_TYPE
|
||||
|| (TREE_CODE (type) == UNION_TYPE
|
||||
&& (GET_MODE_CLASS (mode) == MODE_INT
|
||||
|| (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT
|
||||
&& targetm.calls.pass_by_reference (pack_cumulative_args (0),
|
||||
mode, type, 0)))))
|
||||
&& mode != VOIDmode
|
||||
&& poly_int_tree_p (TYPE_SIZE (type), &type_size)
|
||||
&& known_eq (GET_MODE_BITSIZE (mode), type_size))
|
||||
|
@ -1,6 +1,11 @@
|
||||
2018-11-17 Nikolai Merinov <n.merinov@inango-systems.com>
|
||||
2018-11-07 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
|
||||
* gcc.dg/Wno-attribute-warning.c: New test.
|
||||
PR c/87691
|
||||
* gcc.target/msp430/pr87691.c: New test.
|
||||
|
||||
2018-11-07 Nikolai Merinov <n.merinov@inango-systems.com>
|
||||
|
||||
* gcc.dg/Wno-attribute-warning.c: New test.
|
||||
|
||||
2018-11-07 Nathan Sidwell <nathan@acm.org>
|
||||
|
||||
|
41
gcc/testsuite/gcc.target/msp430/pr87691.c
Normal file
41
gcc/testsuite/gcc.target/msp430/pr87691.c
Normal file
@ -0,0 +1,41 @@
|
||||
/* PR 87691 - Test that a union containing __int20 and a float is not treated as
|
||||
20-bits in size. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-skip-if "no __int20 for mcpu=msp430" { *-*-* } { "-mcpu=msp430" } { "" } } */
|
||||
/* { dg-final { scan-assembler-not "MOVX.A" } } */
|
||||
|
||||
/* To move a 20-bit value from memory (using indexed or indirect register
|
||||
mode), onto the stack (also addressed using indexed or indirect register
|
||||
mode), MOVX.A must be used. MOVA does not support these addressing modes.
|
||||
Therefore, to check that the union is not manipulated as a 20-bit type,
|
||||
test that no MOVX.A instructions are present in the assembly.
|
||||
|
||||
MOVA is used to fill/spill u.i, but if the union is treated as 20 bits in
|
||||
size, MOVX.A would be used. No other __int20 operations are present
|
||||
in the source, so there will be no valid uses of MOVX.A in the resulting
|
||||
assembly. */
|
||||
|
||||
union U1
|
||||
{
|
||||
float f;
|
||||
__int20 i;
|
||||
};
|
||||
|
||||
union U2
|
||||
{
|
||||
__int20 i;
|
||||
float f;
|
||||
};
|
||||
|
||||
float foo1 (union U1 u)
|
||||
{
|
||||
u.i += 42;
|
||||
return u.f;
|
||||
}
|
||||
|
||||
float foo2 (union U2 u)
|
||||
{
|
||||
u.i += 42;
|
||||
return u.f;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user