machmode.h (bitwise_mode_for_mode): Declare.
gcc/ * machmode.h (bitwise_mode_for_mode): Declare. * stor-layout.h (bitwise_type_for_mode): Likewise. * stor-layout.c (bitwise_mode_for_mode): New function. (bitwise_type_for_mode): Likewise. * builtins.c (fold_builtin_memory_op): Use it instead of int_mode_for_mode and build_nonstandard_integer_type. gcc/testsuite/ * gcc.dg/memcpy-5.c: New test. From-SVN: r209622
This commit is contained in:
parent
d9f069ab4f
commit
dbf23a7900
7 changed files with 113 additions and 20 deletions
|
@ -1,3 +1,12 @@
|
|||
2014-04-22 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* machmode.h (bitwise_mode_for_mode): Declare.
|
||||
* stor-layout.h (bitwise_type_for_mode): Likewise.
|
||||
* stor-layout.c (bitwise_mode_for_mode): New function.
|
||||
(bitwise_type_for_mode): Likewise.
|
||||
* builtins.c (fold_builtin_memory_op): Use it instead of
|
||||
int_mode_for_mode and build_nonstandard_integer_type.
|
||||
|
||||
2014-04-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* config.gcc (enable_obsolete): Remove *-*-solaris2.9*.
|
||||
|
|
|
@ -8921,29 +8921,11 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
|
|||
if (FLOAT_MODE_P (TYPE_MODE (desttype))
|
||||
|| TREE_CODE (desttype) == BOOLEAN_TYPE
|
||||
|| TREE_CODE (desttype) == ENUMERAL_TYPE)
|
||||
{
|
||||
/* A more suitable int_mode_for_mode would return a vector
|
||||
integer mode for a vector float mode or a integer complex
|
||||
mode for a float complex mode if there isn't a regular
|
||||
integer mode covering the mode of desttype. */
|
||||
enum machine_mode mode = int_mode_for_mode (TYPE_MODE (desttype));
|
||||
if (mode == BLKmode)
|
||||
desttype = NULL_TREE;
|
||||
else
|
||||
desttype = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode),
|
||||
1);
|
||||
}
|
||||
desttype = bitwise_type_for_mode (TYPE_MODE (desttype));
|
||||
if (FLOAT_MODE_P (TYPE_MODE (srctype))
|
||||
|| TREE_CODE (srctype) == BOOLEAN_TYPE
|
||||
|| TREE_CODE (srctype) == ENUMERAL_TYPE)
|
||||
{
|
||||
enum machine_mode mode = int_mode_for_mode (TYPE_MODE (srctype));
|
||||
if (mode == BLKmode)
|
||||
srctype = NULL_TREE;
|
||||
else
|
||||
srctype = build_nonstandard_integer_type (GET_MODE_BITSIZE (mode),
|
||||
1);
|
||||
}
|
||||
srctype = bitwise_type_for_mode (TYPE_MODE (srctype));
|
||||
if (!srctype)
|
||||
srctype = desttype;
|
||||
if (!desttype)
|
||||
|
|
|
@ -271,6 +271,8 @@ extern enum machine_mode smallest_mode_for_size (unsigned int,
|
|||
|
||||
extern enum machine_mode int_mode_for_mode (enum machine_mode);
|
||||
|
||||
extern enum machine_mode bitwise_mode_for_mode (enum machine_mode);
|
||||
|
||||
/* Return a mode that is suitable for representing a vector,
|
||||
or BLKmode on failure. */
|
||||
|
||||
|
|
|
@ -403,6 +403,73 @@ int_mode_for_mode (enum machine_mode mode)
|
|||
return mode;
|
||||
}
|
||||
|
||||
/* Find a mode that can be used for efficient bitwise operations on MODE.
|
||||
Return BLKmode if no such mode exists. */
|
||||
|
||||
enum machine_mode
|
||||
bitwise_mode_for_mode (enum machine_mode mode)
|
||||
{
|
||||
/* Quick exit if we already have a suitable mode. */
|
||||
unsigned int bitsize = GET_MODE_BITSIZE (mode);
|
||||
if (SCALAR_INT_MODE_P (mode) && bitsize <= MAX_FIXED_MODE_SIZE)
|
||||
return mode;
|
||||
|
||||
/* Reuse the sanity checks from int_mode_for_mode. */
|
||||
gcc_checking_assert ((int_mode_for_mode (mode), true));
|
||||
|
||||
/* Try to replace complex modes with complex modes. In general we
|
||||
expect both components to be processed independently, so we only
|
||||
care whether there is a register for the inner mode. */
|
||||
if (COMPLEX_MODE_P (mode))
|
||||
{
|
||||
enum machine_mode trial = mode;
|
||||
if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT)
|
||||
trial = mode_for_size (bitsize, MODE_COMPLEX_INT, false);
|
||||
if (trial != BLKmode
|
||||
&& have_regs_of_mode[GET_MODE_INNER (trial)])
|
||||
return trial;
|
||||
}
|
||||
|
||||
/* Try to replace vector modes with vector modes. Also try using vector
|
||||
modes if an integer mode would be too big. */
|
||||
if (VECTOR_MODE_P (mode) || bitsize > MAX_FIXED_MODE_SIZE)
|
||||
{
|
||||
enum machine_mode trial = mode;
|
||||
if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
|
||||
trial = mode_for_size (bitsize, MODE_VECTOR_INT, 0);
|
||||
if (trial != BLKmode
|
||||
&& have_regs_of_mode[trial]
|
||||
&& targetm.vector_mode_supported_p (trial))
|
||||
return trial;
|
||||
}
|
||||
|
||||
/* Otherwise fall back on integers while honoring MAX_FIXED_MODE_SIZE. */
|
||||
return mode_for_size (bitsize, MODE_INT, true);
|
||||
}
|
||||
|
||||
/* Find a type that can be used for efficient bitwise operations on MODE.
|
||||
Return null if no such mode exists. */
|
||||
|
||||
tree
|
||||
bitwise_type_for_mode (enum machine_mode mode)
|
||||
{
|
||||
mode = bitwise_mode_for_mode (mode);
|
||||
if (mode == BLKmode)
|
||||
return NULL_TREE;
|
||||
|
||||
unsigned int inner_size = GET_MODE_UNIT_BITSIZE (mode);
|
||||
tree inner_type = build_nonstandard_integer_type (inner_size, true);
|
||||
|
||||
if (VECTOR_MODE_P (mode))
|
||||
return build_vector_type_for_mode (inner_type, mode);
|
||||
|
||||
if (COMPLEX_MODE_P (mode))
|
||||
return build_complex_type (inner_type);
|
||||
|
||||
gcc_checking_assert (GET_MODE_INNER (mode) == VOIDmode);
|
||||
return inner_type;
|
||||
}
|
||||
|
||||
/* Find a mode that is suitable for representing a vector with
|
||||
NUNITS elements of mode INNERMODE. Returns BLKmode if there
|
||||
is no suitable mode. */
|
||||
|
|
|
@ -98,6 +98,8 @@ extern tree make_unsigned_type (int);
|
|||
mode_for_size, but is passed a tree. */
|
||||
extern enum machine_mode mode_for_size_tree (const_tree, enum mode_class, int);
|
||||
|
||||
extern tree bitwise_type_for_mode (enum machine_mode);
|
||||
|
||||
/* Given a VAR_DECL, PARM_DECL or RESULT_DECL, clears the results of
|
||||
a previous call to layout_decl and calls it again. */
|
||||
extern void relayout_decl (tree);
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2014-04-22 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* gcc.dg/memcpy-5.c: New test.
|
||||
|
||||
2014-04-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* gcc.c-torture/compile/pr28865.c: Remove dg-xfail-if.
|
||||
|
|
27
gcc/testsuite/gcc.dg/memcpy-5.c
Normal file
27
gcc/testsuite/gcc.dg/memcpy-5.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* { dg-options "-O -fdump-tree-optimized" } */
|
||||
|
||||
extern void *memcpy (void *, const void *, __SIZE_TYPE__);
|
||||
|
||||
#define TEST(NAME, TYPE) \
|
||||
TYPE NAME##x; \
|
||||
char NAME##y[sizeof (NAME##x)] __attribute__((aligned (__alignof__ (NAME##x)))); \
|
||||
void NAME (void) { memcpy (&NAME##x, &NAME##y, sizeof (NAME##x)); }
|
||||
|
||||
TEST (f, float);
|
||||
TEST (d, double);
|
||||
TEST (ld, long double);
|
||||
TEST (cf, _Complex float);
|
||||
TEST (cd, _Complex double);
|
||||
TEST (cld, _Complex long double);
|
||||
TEST (d8f, float __attribute__((vector_size (8))));
|
||||
TEST (d16f, float __attribute__((vector_size (16))));
|
||||
TEST (d32f, float __attribute__((vector_size (32))));
|
||||
TEST (d64f, float __attribute__((vector_size (64))));
|
||||
TEST (d128f, float __attribute__((vector_size (128))));
|
||||
TEST (d16d, double __attribute__((vector_size (16))));
|
||||
TEST (d32d, double __attribute__((vector_size (32))));
|
||||
TEST (d64d, double __attribute__((vector_size (64))));
|
||||
TEST (d128d, double __attribute__((vector_size (128))));
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "memcpy" "optimized" { target x86_64-*-* } } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
Loading…
Add table
Reference in a new issue