On Wed, 10 Aug 2011, Richard Guenther wrote: > > Nothing in the middle-end happens conditional on > can_trust_pointer_alignment anymore - we can always "trust" pointer > alignment, that function and its comment is somewhat gross. > In fact we can now track alignment properly via CCP and thus > the hack in cfgexpand.c:expand_call_stmt should not be neccessary > anymore. > > Now, looking at the use of can_trust_pointer_alignment in build_over_call > and especially its comment: > > if (!can_trust_pointer_alignment ()) > { > /* If we can't be sure about pointer alignment, a call > to __builtin_memcpy is expanded as a call to memcpy, which > is invalid with identical args. Otherwise it is > expanded as a block move, which should be safe. */ > arg0 = save_expr (arg0); > arg1 = save_expr (arg1); > test = build2 (EQ_EXPR, boolean_type_node, arg0, arg1); > } > > "Otherwise it is expanded as a block move" is certainly not true. > Whether it is expanded as block move depends on optimization setting, > target costs and, well, a way to do block moves (we fall back to > memcpy after all). > > So the patch changes the above to if (!optimize), but I'd argue > we can as well either remove the conditional or emit it unconditional. > Dependent on whether we believe a memcpy implementation exists in > the wild that asserts that src != dst.
The following patch changes us to unconditionally call memcpy, like the backend may decide to do for the tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)) MODIFY_EXPR case. Bootstrapped and tested on x86_64-unknown-linux-gnu. Ok? Thanks, Richard. 2011-08-10 Richard Guenther <rguent...@suse.de> * tree.h (can_trust_pointer_alignment): Remove. * builtins.c (can_trust_pointer_alignment): Remove. cp/ * call.c (build_over_call): Call memcpy unconditionally. Index: trunk/gcc/builtins.c =================================================================== *** trunk.orig/gcc/builtins.c 2011-08-10 14:25:04.000000000 +0200 --- trunk/gcc/builtins.c 2011-08-10 14:25:53.000000000 +0200 *************** get_object_alignment (tree exp) *** 453,468 **** return align; } - /* Returns true iff we can trust that alignment information has been - calculated properly. */ - - bool - can_trust_pointer_alignment (void) - { - /* We rely on TER to compute accurate alignment information. */ - return (optimize && flag_tree_ter); - } - /* Return the alignment in bits of EXP, a pointer valued expression. The alignment returned is, by default, the alignment of the thing that EXP points to. If it is not a POINTER_TYPE, 0 is returned. --- 453,458 ---- Index: trunk/gcc/cp/call.c =================================================================== *** trunk.orig/gcc/cp/call.c 2011-08-10 14:19:23.000000000 +0200 --- trunk/gcc/cp/call.c 2011-08-10 14:26:58.000000000 +0200 *************** build_over_call (struct z_candidate *can *** 6767,6799 **** else { /* We must only copy the non-tail padding parts. ! Use __builtin_memcpy for the bitwise copy. ! FIXME fix 22488 so we can go back to using MODIFY_EXPR ! instead of an explicit call to memcpy. */ ! tree arg0, arg1, arg2, t; - tree test = NULL_TREE; arg2 = TYPE_SIZE_UNIT (as_base); arg1 = arg; arg0 = cp_build_addr_expr (to, complain); - if (!can_trust_pointer_alignment ()) - { - /* If we can't be sure about pointer alignment, a call - to __builtin_memcpy is expanded as a call to memcpy, which - is invalid with identical args. Otherwise it is - expanded as a block move, which should be safe. */ - arg0 = save_expr (arg0); - arg1 = save_expr (arg1); - test = build2 (EQ_EXPR, boolean_type_node, arg0, arg1); - } t = implicit_built_in_decls[BUILT_IN_MEMCPY]; t = build_call_n (t, 3, arg0, arg1, arg2); t = convert (TREE_TYPE (arg0), t); - if (test) - t = build3 (COND_EXPR, TREE_TYPE (t), test, arg0, t); val = cp_build_indirect_ref (t, RO_NULL, complain); TREE_NO_WARNING (val) = 1; } --- 6767,6783 ---- else { /* We must only copy the non-tail padding parts. ! Use __builtin_memcpy for the bitwise copy. */ tree arg0, arg1, arg2, t; arg2 = TYPE_SIZE_UNIT (as_base); arg1 = arg; arg0 = cp_build_addr_expr (to, complain); t = implicit_built_in_decls[BUILT_IN_MEMCPY]; t = build_call_n (t, 3, arg0, arg1, arg2); t = convert (TREE_TYPE (arg0), t); val = cp_build_indirect_ref (t, RO_NULL, complain); TREE_NO_WARNING (val) = 1; } Index: trunk/gcc/tree.h =================================================================== *** trunk.orig/gcc/tree.h 2011-08-10 14:25:04.000000000 +0200 --- trunk/gcc/tree.h 2011-08-10 14:25:37.000000000 +0200 *************** extern tree build_va_arg_indirect_ref (t *** 5358,5364 **** extern tree build_string_literal (int, const char *); extern bool validate_arglist (const_tree, ...); extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode); - extern bool can_trust_pointer_alignment (void); extern bool is_builtin_name (const char *); extern bool is_builtin_fn (tree); extern unsigned int get_object_alignment_1 (tree, unsigned HOST_WIDE_INT *); --- 5358,5363 ----