OSDN Git Service

2011-10-18 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Oct 2011 08:46:00 +0000 (08:46 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Oct 2011 08:46:00 +0000 (08:46 +0000)
PR middle-end/50716
* expr.c (get_object_or_type_alignment): New function.
(expand_assignment): Use it.
(expand_expr_real_1): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180125 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c

index dfe8d99..19f851d 100644 (file)
@@ -1,3 +1,10 @@
+2011-10-18  Richard Guenther  <rguenther@suse.de>
+
+       PR middle-end/50716
+       * expr.c (get_object_or_type_alignment): New function.
+       (expand_assignment): Use it.
+       (expand_expr_real_1): Likewise.
+
 2011-10-18  Dodji Seketeli  <dodji@redhat.com>
 
        PR bootstrap/50760
index b020978..c1117a8 100644 (file)
@@ -4544,6 +4544,27 @@ get_bit_range (unsigned HOST_WIDE_INT *bitstart,
     }
 }
 
+/* Return the alignment of the object EXP, also considering its type
+   when we do not know of explicit misalignment.
+   ???  Note that, in the general case, the type of an expression is not kept
+   consistent with misalignment information by the front-end, for
+   example when taking the address of a member of a packed structure.
+   However, in most of the cases, expressions have the alignment of
+   their type, so we optimistically fall back to the alignment of the
+   type when we cannot compute a misalignment.  */
+
+static unsigned int
+get_object_or_type_alignment (tree exp)
+{
+  unsigned HOST_WIDE_INT misalign;
+  unsigned int align = get_object_alignment_1 (exp, &misalign);
+  if (misalign != 0)
+    align = (misalign & -misalign);
+  else
+    align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align);
+  return align;
+}
+
 /* Expand an assignment that stores the value of FROM into TO.  If NONTEMPORAL
    is true, try generating a nontemporal store.  */
 
@@ -4553,7 +4574,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
   rtx to_rtx = 0;
   rtx result;
   enum machine_mode mode;
-  int align;
+  unsigned int align;
   enum insn_code icode;
 
   /* Don't crash if the lhs of the assignment was erroneous.  */
@@ -4571,8 +4592,8 @@ expand_assignment (tree to, tree from, bool nontemporal)
   if ((TREE_CODE (to) == MEM_REF
        || TREE_CODE (to) == TARGET_MEM_REF)
       && mode != BLKmode
-      && ((align = MAX (TYPE_ALIGN (TREE_TYPE (to)), get_object_alignment (to)))
-         < (signed) GET_MODE_ALIGNMENT (mode))
+      && ((align = get_object_or_type_alignment (to))
+         < GET_MODE_ALIGNMENT (mode))
       && ((icode = optab_handler (movmisalign_optab, mode))
          != CODE_FOR_nothing))
     {
@@ -9241,7 +9262,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
        struct mem_address addr;
        enum insn_code icode;
-       int align;
+       unsigned int align;
 
        get_address_description (exp, &addr);
        op0 = addr_for_mem_ref (&addr, as, true);
@@ -9249,9 +9270,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        temp = gen_rtx_MEM (mode, op0);
        set_mem_attributes (temp, exp, 0);
        set_mem_addr_space (temp, as);
-       align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), get_object_alignment (exp));
+       align = get_object_or_type_alignment (exp);
        if (mode != BLKmode
-           && (unsigned) align < GET_MODE_ALIGNMENT (mode)
+           && align < GET_MODE_ALIGNMENT (mode)
            /* If the target does not have special handling for unaligned
               loads of mode then it can use regular moves for them.  */
            && ((icode = optab_handler (movmisalign_optab, mode))
@@ -9278,7 +9299,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        tree base = TREE_OPERAND (exp, 0);
        gimple def_stmt;
        enum insn_code icode;
-       int align;
+       unsigned align;
        /* Handle expansion of non-aliased memory with non-BLKmode.  That
           might end up in a register.  */
        if (TREE_CODE (base) == ADDR_EXPR)
@@ -9329,7 +9350,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
                           gimple_assign_rhs1 (def_stmt), mask);
            TREE_OPERAND (exp, 0) = base;
          }
-       align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), get_object_alignment (exp));
+       align = get_object_or_type_alignment (exp);
        op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM);
        op0 = memory_address_addr_space (address_mode, op0, as);
        if (!integer_zerop (TREE_OPERAND (exp, 1)))
@@ -9345,7 +9366,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
        if (TREE_THIS_VOLATILE (exp))
          MEM_VOLATILE_P (temp) = 1;
        if (mode != BLKmode
-           && (unsigned) align < GET_MODE_ALIGNMENT (mode)
+           && align < GET_MODE_ALIGNMENT (mode)
            /* If the target does not have special handling for unaligned
               loads of mode then it can use regular moves for them.  */
            && ((icode = optab_handler (movmisalign_optab, mode))