re PR middle-end/59990 (incorrect memcpy optimization)
2014-01-31 Richard Biener <rguenther@suse.de> 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. From-SVN: r207338
This commit is contained in:
parent
798888a050
commit
fdfd537bcb
|
@ -1,3 +1,10 @@
|
|||
2014-01-31 Richard Biener <rguenther@suse.de>
|
||||
|
||||
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 <dj@redhat.com>
|
||||
|
||||
* config/msp430/msp430.h (LIB_SPEC): Add -lcrt
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2014-01-31 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR middle-end/59990
|
||||
* gcc.dg/torture/pr59990.c: New testcase.
|
||||
|
||||
2014-01-31 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* lib/tsan-dg.exp (tsan_init): Try to run a trivial program,
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue