http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20020
--- Comment #46 from H.J. Lu <hjl.tools at gmail dot com> 2012-08-15 16:01:15
UTC ---
(In reply to comment #45)
> Changing this is generally very risky for ABI incompatibilities, many targets
> base some of the decisions how to pass parameters or return values on the type
> mode.
ABI is tightly controlled by i386 backend and shouldn't be a problem.
The main issue is middle-end isn't prepared to deal with it.
compute_record_mode has
/* 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. */
if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
&& host_integerp (TYPE_SIZE (type), 1)
&& GET_MODE_BITSIZE (mode) == TREE_INT_CST_LOW (TYPE_SIZE (type)))
SET_TYPE_MODE (type, mode);
else
SET_TYPE_MODE (type, mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1));
/* If structure's known alignment is less than what the scalar
mode would need, and it matters, then stick with BLKmode. */
if (TYPE_MODE (type) != BLKmode
&& STRICT_ALIGNMENT
&& ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
|| TYPE_ALIGN (type) >= GET_MODE_ALIGNMENT (TYPE_MODE (type))))
{
/* If this is the only reason this type is BLKmode, then
don't force containing types to be BLKmode. */
TYPE_NO_FORCE_BLK (type) = 1;
SET_TYPE_MODE (type, BLKmode);
}
We need a target hook to proper handle union with a single XFmode.