Attached, is a patch to fix PR20020, and three test cases. This patch improves the code generated for structs that can be represented in a TImode value on an x86_64 target. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20020
The test cases scan the generated RTL and verify that TImode operations are present. Note that this patch will uncover a new test regression, described here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20020#c9
Index: gcc/config/i386/i386.h =================================================================== --- gcc/config/i386/i386.h (revision 190336) +++ gcc/config/i386/i386.h (working copy) @@ -1820,6 +1820,10 @@ 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) + /* 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 Index: gcc/testsuite/gcc.dg/pr20020-1.c =================================================================== --- gcc/testsuite/gcc.dg/pr20020-1.c (revision 0) +++ gcc/testsuite/gcc.dg/pr20020-1.c (revision 0) @@ -0,0 +1,25 @@ +/* Target is restricted to x86_64 type architectures, + to check that 128-bit struct's are represented + as TImode values. */ +/* { dg-require-effective-target int128 } */ +/* { dg-do compile { target { x86_64-*-* } } } */ +/* { dg-options "-O2 -fdump-rtl-expand" } */ + +struct shared_ptr_struct +{ + unsigned long long phase:48; + unsigned short thread:16; + void *addr; +}; +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" } } */ Index: gcc/testsuite/gcc.dg/pr20020-2.c =================================================================== --- gcc/testsuite/gcc.dg/pr20020-2.c (revision 0) +++ gcc/testsuite/gcc.dg/pr20020-2.c (revision 0) @@ -0,0 +1,23 @@ +/* Target is restricted to x86_64 type architectures, + to check that 128-bit struct's are represented + as TImode values. */ +/* { dg-require-effective-target int128 } */ +/* { dg-do compile { target { x86_64-*-* } } } */ +/* { dg-options "-O2 -fdump-rtl-expand" } */ + +struct shared_ptr_struct +{ + unsigned long long phase:48; + unsigned short thread:16; + void *addr; +}; +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" } } */ Index: gcc/testsuite/gcc.dg/pr20020-3.c =================================================================== --- gcc/testsuite/gcc.dg/pr20020-3.c (revision 0) +++ gcc/testsuite/gcc.dg/pr20020-3.c (revision 0) @@ -0,0 +1,26 @@ +/* Target is restricted to x86_64 type architectures, + to check that 128-bit struct's are represented + as TImode values. */ +/* { dg-require-effective-target int128 } */ +/* { dg-do compile { target { x86_64-*-* } } } */ +/* { dg-options "-O2 -fdump-rtl-expand" } */ + +struct shared_ptr_struct +{ + unsigned long long phase:48; + unsigned short thread:16; + void *addr; +}; +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" } } */