[multiple changes]
authorRichard Guenther <rguenther@suse.de>
Tue, 24 Jan 2012 09:17:01 +0000 (09:17 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 24 Jan 2012 09:17:01 +0000 (09:17 +0000)
2012-01-24  Richard Guenther  <rguenther@suse.de>

Forward-port to trunk
2010-09-21  Jakub Jelinek  <jakub@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.

From-SVN: r183470

gcc/ChangeLog
gcc/expr.c

index 6455954d3030b68c23fdad559ae7945295aa59f7..554ad1eeff546997c387802be1c7f605c024619c 100644 (file)
@@ -1,3 +1,13 @@
+2012-01-24  Richard Guenther  <rguenther@suse.de>
+
+       Forward-port to trunk
+       2010-09-21  Jakub Jelinek  <jakub@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.
+
 2012-01-24  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/51957
index fb93346eb9932a7a3fafb4b62c9931c93ac6e957..e181ee3ef0d2ab3d17a868a5df8f74a33ef19c62 100644 (file)
@@ -10044,10 +10044,32 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
         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))