https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64516

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
   Target Milestone|---                         |4.9.4
            Summary|[4.x Regression] arm: wrong |[4.9/5/6/7 Regression] arm:
                   |unaligned load generated    |wrong unaligned load
                   |                            |generated

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
get16_unaligned should work.  Confirmed on trunk.

(insn 6 5 7 (set (reg:SI 114)
        (zero_extend:SI (mem:HI (reg/v/f:SI 111 [ p ]) [1 MEM[(const struct TU2
*)p_2(D)]+0 S2 A16]))) t.c:7 -1
     (nil))

This is because the MEM_REF has a wrong type/alignment on it.  Ah, and it's
one folding I know is wrong for a long time ... :/

    case VIEW_CONVERT_EXPR:
      if (TREE_CODE (op0) == MEM_REF)
        {
          tem = fold_build2_loc (loc, MEM_REF, type,
                                 TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
          REF_REVERSE_STORAGE_ORDER (tem) = REF_REVERSE_STORAGE_ORDER (op0);
          return tem;
        }

this drops alignment info.

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c    (revision 237286)
+++ gcc/fold-const.c    (working copy)
@@ -7964,6 +7974,8 @@ fold_unary_loc (location_t loc, enum tre
     case VIEW_CONVERT_EXPR:
       if (TREE_CODE (op0) == MEM_REF)
         {
+         if (TYPE_ALIGN (TREE_TYPE (op0)) != TYPE_ALIGN (type))
+           type = build_aligned_type (type, TYPE_ALIGN (TREE_TYPE (op0)));
          tem = fold_build2_loc (loc, MEM_REF, type,
                                 TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1));
          REF_REVERSE_STORAGE_ORDER (tem) = REF_REVERSE_STORAGE_ORDER (op0);

then generates

get16_unaligned:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
        @ link register save eliminated.
        ldrb    r3, [r0]        @ zero_extendqisi2
        ldrb    r0, [r0, #1]    @ zero_extendqisi2
        orr     r0, r3, r0, lsl #8
        mov     pc, lr

Reply via email to