From ce319529799266f174e697b59a97310d65f75818 Mon Sep 17 00:00:00 2001 From: rguenth Date: Fri, 31 Jan 2014 11:54:26 +0000 Subject: [PATCH] 2014-01-31 Richard Biener PR middle-end/59990 * builtins.c (fold_builtin_memory_op): Make sure to not use a floating-point mode or a boolean or enumeral type for the copy operation. * gcc.dg/torture/pr59990.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207338 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++++ gcc/builtins.c | 64 ++++++++++++++++++++++------------ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/torture/pr59990.c | 18 ++++++++++ 4 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr59990.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 158f2d6a12e..bbf6b476f97 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2014-01-31 Richard Biener + + PR middle-end/59990 + * builtins.c (fold_builtin_memory_op): Make sure to not + use a floating-point mode or a boolean or enumeral type for + the copy operation. + 2014-01-30 DJ Delorie * config/msp430/msp430.h (LIB_SPEC): Add -lcrt diff --git a/gcc/builtins.c b/gcc/builtins.c index a45380ce877..f5f55bf0e2e 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8851,6 +8851,12 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, if (!POINTER_TYPE_P (TREE_TYPE (src)) || !POINTER_TYPE_P (TREE_TYPE (dest))) return NULL_TREE; + /* In the following try to find a type that is most natural to be + used for the memcpy source and destination and that allows + the most optimization when memcpy is turned into a plain assignment + using that type. In theory we could always use a char[len] type + but that only gains us that the destination and source possibly + no longer will have their address taken. */ /* As we fold (void *)(p + CST) to (void *)p + CST undo this here. */ if (TREE_CODE (src) == POINTER_PLUS_EXPR) { @@ -8886,6 +8892,41 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, || TREE_ADDRESSABLE (desttype)) return NULL_TREE; + /* Make sure we are not copying using a floating-point mode or + a type whose size possibly does not match its precision. */ + 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); + } + 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); + } + if (!srctype) + srctype = desttype; + if (!desttype) + desttype = srctype; + if (!srctype) + return NULL_TREE; + src_align = get_pointer_alignment (src); dest_align = get_pointer_alignment (dest); if (dest_align < TYPE_ALIGN (desttype) @@ -8899,29 +8940,6 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src, off0 = build_int_cst (build_pointer_type_for_mode (char_type_node, ptr_mode, true), 0); - /* For -fsanitize={bool,enum} make sure the load isn't performed in - the bool or enum type. */ - if (((flag_sanitize & SANITIZE_BOOL) - && TREE_CODE (desttype) == BOOLEAN_TYPE) - || ((flag_sanitize & SANITIZE_ENUM) - && TREE_CODE (desttype) == ENUMERAL_TYPE)) - { - tree destitype - = lang_hooks.types.type_for_mode (TYPE_MODE (desttype), - TYPE_UNSIGNED (desttype)); - desttype = build_aligned_type (destitype, TYPE_ALIGN (desttype)); - } - if (((flag_sanitize & SANITIZE_BOOL) - && TREE_CODE (srctype) == BOOLEAN_TYPE) - || ((flag_sanitize & SANITIZE_ENUM) - && TREE_CODE (srctype) == ENUMERAL_TYPE)) - { - tree srcitype - = lang_hooks.types.type_for_mode (TYPE_MODE (srctype), - TYPE_UNSIGNED (srctype)); - srctype = build_aligned_type (srcitype, TYPE_ALIGN (srctype)); - } - destvar = dest; STRIP_NOPS (destvar); if (TREE_CODE (destvar) == ADDR_EXPR diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 435b0556f41..87fff131c64 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-01-31 Richard Biener + + PR middle-end/59990 + * gcc.dg/torture/pr59990.c: New testcase. + 2014-01-31 Jakub Jelinek * lib/tsan-dg.exp (tsan_init): Try to run a trivial program, diff --git a/gcc/testsuite/gcc.dg/torture/pr59990.c b/gcc/testsuite/gcc.dg/torture/pr59990.c new file mode 100644 index 00000000000..e54f9b7efb0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr59990.c @@ -0,0 +1,18 @@ +/* { dg-do run } */ + +extern void abort (void); + +unsigned char value[4] = { 66, 9, 160, 255 }; + +int main (void) +{ + volatile float f; + unsigned char a[4]; + + __builtin_memcpy ((void *)&f, value, 4); + __builtin_memcpy (a, (void *)&f, 4); + if (a[2] != 160) + abort (); + + return 0; +} -- 2.11.4.GIT