Hi, My email sent to gcc-patches@gcc.gnu.org was bounced as spam. I am resending it. This patch defines both MAX_FIXED_MODE_SIZE and MEMBER_TYPE_FORCES_BLK for i386. MEMBER_TYPE_FORCES_BLK is needed so that we always put union with XFmode field in BLKmode. This patch doesn't change any ABI since both MAX_FIXED_MODE_SIZE and MEMBER_TYPE_FORCES_BLK aren't ABI macros. They only change code quality. Tested on Linux/x86-64. OK to install?
Thanks. H.J. --- gcc/ 2012-08-16 H.J. Lu <hongjiu...@intel.com> Gary Funck <g...@intrepid.com> PR target/20020 * config/i386/i386.h (MAX_FIXED_MODE_SIZE): New macro. (MEMBER_TYPE_FORCES_BLK): Likewise. gcc/testsuite/ 2012-08-16 H.J. Lu <hongjiu...@intel.com> Gary Funck <g...@intrepid.com> PR target/20020 * gcc.target/i386/pr20020-1.c: New test. * gcc.target/i386/pr20020-2.c: Likewise. * gcc.target/i386/pr20020-3.c: Likewise. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 5ff82ab..4046a9a 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1816,6 +1816,16 @@ do { \ #define BRANCH_COST(speed_p, predictable_p) \ (!(speed_p) ? 2 : (predictable_p) ? 0 : ix86_branch_cost) +/* An integer expression for the size in bits of the largest integer machine + mode that should actually be used. We allow pairs of registers. */ +#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (TARGET_64BIT ? TImode : DImode) + +/* Union with XFmode must be in BLKmode. */ +#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \ + ((MODE) == XFmode \ + && (TREE_CODE (DECL_FIELD_CONTEXT (FIELD)) == UNION_TYPE \ + || TREE_CODE (DECL_FIELD_CONTEXT (FIELD)) == QUAL_UNION_TYPE)) + /* Define this macro as a C expression which is nonzero if accessing less than a word of memory (i.e. a `char' or a `short') is no faster than accessing a word of memory, i.e., if such access diff --git a/gcc/testsuite/gcc.target/i386/pr20020-1.c b/gcc/testsuite/gcc.target/i386/pr20020-1.c new file mode 100644 index 0000000..3f10970 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr20020-1.c @@ -0,0 +1,26 @@ +/* Check that 128-bit struct's are represented as TImode values. */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fdump-rtl-expand" } */ + +struct shared_ptr_struct +{ + unsigned long long phase:48; + unsigned short thread:16; + union + { + void *addr; + unsigned long long pad; + }; +}; +typedef struct shared_ptr_struct sptr_t; + +sptr_t S; + +sptr_t +sptr_result (void) +{ + return S; +} +/* { dg-final { scan-rtl-dump "\\\(set \\\(reg:TI \[0-9\]* \\\[ <retval> \\\]\\\)" "expand" } } */ +/* { dg-final { scan-rtl-dump "\\\(set \\\(reg/i:TI 0 ax\\\)" "expand" } } */ +/* { dg-final { cleanup-rtl-dump "expand" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr20020-2.c b/gcc/testsuite/gcc.target/i386/pr20020-2.c new file mode 100644 index 0000000..e8c5b3d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr20020-2.c @@ -0,0 +1,24 @@ +/* Check that 128-bit struct's are represented as TImode values. */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fdump-rtl-expand" } */ + +struct shared_ptr_struct +{ + unsigned long long phase:48; + unsigned short thread:16; + union + { + void *addr; + unsigned long long pad; + }; +}; +typedef struct shared_ptr_struct sptr_t; + +void +copy_sptr (sptr_t *dest, sptr_t src) +{ + *dest = src; +} + +/* { dg-final { scan-rtl-dump "\\\(set \\\(reg:TI \[0-9\]*" "expand" } } */ +/* { dg-final { cleanup-rtl-dump "expand" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr20020-3.c b/gcc/testsuite/gcc.target/i386/pr20020-3.c new file mode 100644 index 0000000..b1cc926 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr20020-3.c @@ -0,0 +1,27 @@ +/* Check that 128-bit struct's are represented as TImode values. */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fdump-rtl-expand" } */ + +struct shared_ptr_struct +{ + unsigned long long phase:48; + unsigned short thread:16; + union + { + void *addr; + unsigned long long pad; + }; +}; +typedef struct shared_ptr_struct sptr_t; + +sptr_t sptr_1, sptr_2; + +void +copy_sptr (void) +{ + sptr_1 = sptr_2; +} + +/* { dg-final { scan-rtl-dump "\\\(set \\\(reg:TI \[0-9\]*" "expand" } } */ +/* { dg-final { scan-rtl-dump "\\\(set \\\(mem/c:TI" "expand" } } */ +/* { dg-final { cleanup-rtl-dump "expand" } } */