[Also posted to the GCC mailing list, http://gcc.gnu.org/ml/gcc/2005- 02/msg00692.html]
Given, struct shared_ptr_struct { unsigned int phase : 24; unsigned short thread : 16; void *addr; }; On the x86_64 (ie, Opteron[tm]) platform, GCC appears to designate the underlying mode of this type as a BLKmode, instead of a TImode. This has implications in terms of the quality of the code that is generated to copy and manipulate 128 bit structures (as defined in the example above). The decision to commit this type to a BLKmode value, originates in this logic in mode_for_size(): if (limit && size > MAX_FIXED_MODE_SIZE) return BLKmode; On the x86 platform, there appears to be no target definition for MAX_FIELD_SIZE. Thus, the default in stor-layout.c applies: #ifndef MAX_FIXED_MODE_SIZE #define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode) #endif Other 64 bit targets define MAX_FIXED_MODE_SIZE along these lines (some line wrapping may occur below): config/i960/i960.h:#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TImode) config/ia64/ia64.h:#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TImode) config/mips/mips.h:#define MAX_FIXED_MODE_SIZE LONG_DOUBLE_TYPE_SIZE config/sh/sh.h:#define MAX_FIXED_MODE_SIZE (TARGET_SH5 ? 128 : 64) on MIPS, LONG_DOUBLE_TYPE_SIZE is defined as follows: /* A C expression for the size in bits of the type `long double' on the target machine. If you don't define this, the default is two words. */ #define LONG_DOUBLE_TYPE_SIZE \ (mips_abi == ABI_N32 || mips_abi == ABI_64 ? 128 : 64) In the 'dev' tree, the s390 defines MAX_FIXED_MODE_SIZE as follows: config/s390/s390.h:#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode) (Arguably, the s390 variant might be a better default value to be defined in stor-layout.c) -- Summary: x86_64 - 128 bit structs not targeted to TImode Product: gcc Version: 4.0.0 Status: UNCONFIRMED Severity: normal Priority: P2 Component: target AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: gary at intrepid dot com CC: gcc-bugs at gcc dot gnu dot org GCC host triplet: x86_64-unknown-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20020