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:
Jozef Lawrynowicz 2018-11-07 22:06:26 +00:00
parent e217792bed
commit c2ca29d5a3
4 changed files with 78 additions and 11 deletions

View File

@ -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>

View File

@ -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))

View File

@ -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>

View 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;
}