--- gcc/expr.c	2013-08-06 00:09:45.000000000 +0200
+++ gcc/expr.c	2013-09-03 00:46:28.000000000 +0200
@@ -4707,6 +4707,9 @@ expand_assignment (tree to, tree from, b
       mode = TYPE_MODE (TREE_TYPE (tem));
       if (TREE_CODE (tem) == MEM_REF
 	  && mode != BLKmode
+	  && offset == 0
+	  && bitpos + bitsize <= GET_MODE_BITSIZE (mode)
+	  && !volatilep
 	  && ((align = get_object_alignment (tem))
 	      < GET_MODE_ALIGNMENT (mode))
 	  && ((icode = optab_handler (movmisalign_optab, mode))
@@ -4773,6 +4776,8 @@ expand_assignment (tree to, tree from, b
 	  if (MEM_P (to_rtx)
 	      && GET_MODE (to_rtx) == BLKmode
 	      && GET_MODE (XEXP (to_rtx, 0)) != VOIDmode
+	      && bitregion_start == 0
+	      && bitregion_end == 0
 	      && bitsize > 0
 	      && (bitpos % bitsize) == 0
 	      && (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
--- gcc/testsuite/gcc.dg/torture/pr57748-1.c	1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.dg/torture/pr57748-1.c	2013-09-06 08:38:03.718686940 +0200
@@ -0,0 +1,49 @@
+/* PR middle-end/57748 */
+/* { dg-do run } */
+/* ICE in expand_assignment:
+   misalignp == true, !MEM_P (to_rtx), offset != 0, 
+   => gcc_assert (TREE_CODE (offset) == INTEGER_CST) */
+
+#include <stdlib.h>
+
+extern void abort (void);
+
+typedef long long V
+  __attribute__ ((vector_size (2 * sizeof (long long)), may_alias));
+
+typedef struct S { V a; V b[0]; } P __attribute__((aligned (1)));
+
+struct __attribute__((packed)) T { char c; P s; };
+
+void __attribute__((noinline, noclone))
+check (struct T *t)
+{
+  if (t->s.b[0][0] != 3 || t->s.b[0][1] != 4)
+    abort ();
+}
+
+int __attribute__((noinline, noclone))
+get_i (void)
+{
+  return 0;
+}
+
+void __attribute__((noinline, noclone))
+foo (P *p)
+{
+  V a = { 3, 4 };
+  int i = get_i ();
+  p->b[i] = a;
+}
+
+int
+main ()
+{
+  struct T *t = (struct T *) calloc (128, 1);
+
+  foo (&t->s);
+  check (t);
+
+  free (t);
+  return 0;
+}
--- gcc/testsuite/gcc.dg/torture/pr57748-2.c	1970-01-01 01:00:00.000000000 +0100
+++ gcc/testsuite/gcc.dg/torture/pr57748-2.c	2013-09-06 08:38:03.718686940 +0200
@@ -0,0 +1,43 @@
+/* PR middle-end/57748 */
+/* { dg-do run } */
+/* wrong code in expand_assignment:
+   misalignp == true, !MEM_P (to_rtx),
+   offset == 0, bitpos >= GET_MODE_PRECISION,
+   => result = NULL */
+
+#include <stdlib.h>
+
+extern void abort (void);
+
+typedef long long V
+  __attribute__ ((vector_size (2 * sizeof (long long)), may_alias));
+
+typedef struct S { V a; V b[0]; } P __attribute__((aligned (1)));
+
+struct __attribute__((packed)) T { char c; P s; };
+
+void __attribute__((noinline, noclone))
+check (struct T *t)
+{
+  if (t->s.b[0][0] != 3 || t->s.b[0][1] != 4)
+    abort ();
+}
+
+void __attribute__((noinline, noclone))
+foo (P *p)
+{
+  V a = { 3, 4 };
+  p->b[0] = a;
+}
+
+int
+main ()
+{
+  struct T *t = (struct T *) calloc (128, 1);
+
+  foo (&t->s);
+  check (t);
+
+  free (t);
+  return 0;
+}
