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 ----

Reply via email to