On Mon, 23 Jan 2012, Richard Guenther wrote:

> 
> The VIEW_CONVERT_EXPR expansion path fails to handle the case where
> we promote alignment for !STRICT_ALIGNMENT targets but for modes
> that are supposed to be handled by movmisalign.
> 
> This is exposed in gcc.dg/torture/pr45678-2.c on i?86 when
> you apply the candidate patch for PR50444 in comment #15.
> 
> I'm now bootstrapping and regtesting this as a prerequesite.

Actually I discovered that Jakub fixed this on the 4.4 and 4.5
branches but left 4.6 unfixed ... thus I'm re-testing

2012-01-23  Richard Guenther  <rguent...@suse.de>

        Forward-port to trunk
        2010-09-21  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/45678
        * expr.c (expand_expr_real_1) <case VIEW_CONVERT_EXPR>: If
        op0 isn't sufficiently aligned and there is movmisalignM
        insn for mode, use it to load op0 into a temporary register.

Index: gcc/expr.c
===================================================================
*** gcc/expr.c  (revision 183423)
--- gcc/expr.c  (working copy)
*************** expand_expr_real_1 (tree exp, rtx target
*** 10044,10053 ****
--- 10044,10075 ----
         results.  */
        if (MEM_P (op0))
        {
+         enum insn_code icode;
+ 
          op0 = copy_rtx (op0);
  
          if (TYPE_ALIGN_OK (type))
            set_mem_align (op0, MAX (MEM_ALIGN (op0), TYPE_ALIGN (type)));
+         else if (mode != BLKmode
+                  && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode)
+                  /* If the target does have special handling for unaligned
+                     loads of mode then use them.  */
+                  && ((icode = optab_handler (movmisalign_optab, mode))
+                      != CODE_FOR_nothing))
+           {
+             rtx reg, insn;
+ 
+             op0 = adjust_address (op0, mode, 0);
+             /* We've already validated the memory, and we're creating a
+                new pseudo destination.  The predicates really can't
+                fail.  */
+             reg = gen_reg_rtx (mode);
+ 
+             /* Nor can the insn generator.  */
+             insn = GEN_FCN (icode) (reg, op0);
+             emit_insn (insn);
+             return reg;
+           }
          else if (STRICT_ALIGNMENT
                   && mode != BLKmode
                   && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))

Reply via email to