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.