http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48493

--- Comment #5 from Richard Guenther <rguenth at gcc dot gnu.org> 2011-06-21 
10:45:20 UTC ---
Of course it was.  The branch merge allows s to be allocated in registers
so we expand from

  MEM[(T * {ref-all})&s + 1B] = x_2(D);

and we run into the movmisalign_optab code in expand_assignment which
is supported for DImode with the commandline args.  But we probably
shouldn't try the movmisalign path when the destination is a CONCAT.

So something like the following might work (fixes the testcase, otehrwise
completely untested)

Index: expr.c
===================================================================
--- expr.c      (revision 175138)
+++ expr.c      (working copy)
@@ -4122,6 +4122,12 @@ expand_assignment (tree to, tree from, b
   rtx result;
   enum machine_mode mode;
   int align, icode;
+  enum machine_mode mode1;
+  HOST_WIDE_INT bitsize, bitpos;
+  tree offset;
+  int unsignedp;
+  int volatilep = 0;
+  tree tem;

   /* Don't crash if the lhs of the assignment was erroneous.  */
   if (TREE_CODE (to) == ERROR_MARK)
@@ -4134,9 +4140,18 @@ expand_assignment (tree to, tree from, b
   if (operand_equal_p (to, from, 0))
     return;

+  tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
+                            &unsignedp, &volatilep, true);
+
+  /* If we are going to use store_bit_field and extract_bit_field,
+     make sure to_rtx will be safe for multiple use.  */
+
+  to_rtx = expand_normal (tem);
+
   mode = TYPE_MODE (TREE_TYPE (to));
-  if ((TREE_CODE (to) == MEM_REF
-       || TREE_CODE (to) == TARGET_MEM_REF)
+  if (MEM_P (to_rtx)
+      && (TREE_CODE (to) == MEM_REF
+         || TREE_CODE (to) == TARGET_MEM_REF)
       && mode != BLKmode
       && ((align = MAX (TYPE_ALIGN (TREE_TYPE (to)),
                        get_object_alignment (to, BIGGEST_ALIGNMENT)))
@@ -4150,39 +4165,7 @@ expand_assignment (tree to, tree from, b
       reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
       reg = force_not_mem (reg);

-      if (TREE_CODE (to) == MEM_REF)
-       {
-         addr_space_t as
-             = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 1))));
-         tree base = TREE_OPERAND (to, 0);
-         address_mode = targetm.addr_space.address_mode (as);
-         op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL);
-         op0 = convert_memory_address_addr_space (address_mode, op0, as);
-         if (!integer_zerop (TREE_OPERAND (to, 1)))
-           {
-             rtx off
-                 = immed_double_int_const (mem_ref_offset (to), address_mode);
-             op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
-           }
-         op0 = memory_address_addr_space (mode, op0, as);
-         mem = gen_rtx_MEM (mode, op0);
-         set_mem_attributes (mem, to, 0);
-         set_mem_addr_space (mem, as);
-       }
-      else if (TREE_CODE (to) == TARGET_MEM_REF)
-       {
-         addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (to));
-         struct mem_address addr;
-
-         get_address_description (to, &addr);
-         op0 = addr_for_mem_ref (&addr, as, true);
-         op0 = memory_address_addr_space (mode, op0, as);
-         mem = gen_rtx_MEM (mode, op0);
-         set_mem_attributes (mem, to, 0);
-         set_mem_addr_space (mem, as);
-       }
-      else
-       gcc_unreachable ();
+      mem = to_rtx;
       if (TREE_THIS_VOLATILE (to))
        MEM_VOLATILE_P (mem) = 1;

@@ -4211,21 +4194,7 @@ expand_assignment (tree to, tree from, b
          && TREE_CODE (TREE_OPERAND (to, 0)) == ADDR_EXPR)
       || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
     {
-      enum machine_mode mode1;
-      HOST_WIDE_INT bitsize, bitpos;
-      tree offset;
-      int unsignedp;
-      int volatilep = 0;
-      tree tem;
-
       push_temp_slots ();
-      tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
-                                &unsignedp, &volatilep, true);
-
-      /* If we are going to use store_bit_field and extract_bit_field,
-        make sure to_rtx will be safe for multiple use.  */
-
-      to_rtx = expand_normal (tem);

       /* If the bitfield is volatile, we want to access it in the
         field's mode, not the computed mode.

Reply via email to