Index: src/gcc/testsuite/gcc.dg/torture/pr55755.c
===================================================================
--- /dev/null
+++ src/gcc/testsuite/gcc.dg/torture/pr55755.c
@@ -0,0 +1,43 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+struct S4
+{
+  unsigned f0:24;
+} __attribute__((__packed__));
+
+struct S4 g_10 = {
+  6210831
+};
+
+struct S5
+{
+  int i;
+  struct S4 l_8[2];
+}  __attribute__((__packed__));
+
+int a, b;
+
+struct S4 func_2 (int x)
+{
+  struct S5 l = {
+    0,
+    {{0}, {0}}
+  };
+  l.i = a;
+  g_10 = l.l_8[1];
+  for (; x<2; x++) {
+    struct S4 tmp = {
+      11936567
+    };
+    l.l_8[x] = tmp;
+  }
+  b = l.i;
+  return g_10;
+}
+
+int main (void)
+{
+  func_2 (0);
+  return 0;
+}
Index: src/gcc/testsuite/gcc.dg/tree-ssa/sra-13.c
===================================================================
--- /dev/null
+++ src/gcc/testsuite/gcc.dg/tree-ssa/sra-13.c
@@ -0,0 +1,114 @@
+/* Test that SRA replacement can deal with assignments that have
+   sub-replacements on one side and a single scalar replacement on another.  */
+/* { dg-do run } */
+/* { dg-options "-O1" } */
+
+struct A
+{
+  int i1, i2;
+};
+
+struct B
+{
+  long long int l;
+};
+
+union U
+{
+  struct A a;
+  struct B b;
+};
+
+int b, gi;
+long gl;
+union U gu1, gu2;
+
+int __attribute__ ((noinline, noclone))
+foo (void)
+{
+  union U x, y;
+  int r;
+
+  y = gu1;
+  if (b)
+    y.b.l = gl;
+
+  x = y;
+
+  if (!b)
+    r = x.a.i1;
+  else
+    r = 0;
+
+  gu2 = x;
+  return r;
+}
+
+long long int __attribute__ ((noinline, noclone))
+bar (void)
+{
+  union U x, y;
+  int r;
+
+  y = gu1;
+  if (b)
+    y.a.i1 = gi;
+
+  x = y;
+
+  if (!b)
+    r = x.b.l;
+  else
+    r = 0;
+
+  gu2 = x;
+  return r;
+}
+
+
+int
+main (void)
+{
+  int r;
+  long long int s;
+
+  b = 0;
+  gu1.a.i1 = 123;
+  gu1.a.i2 = 234;
+  r = foo ();
+  if (r != 123)
+    __builtin_abort ();
+  if (gu2.a.i1 != 123)
+    __builtin_abort ();
+  if (gu2.a.i2 != 234)
+    __builtin_abort ();
+
+  b = 1;
+  gl = 10000001;
+  gu1.b.l = 10000000;
+  r = foo ();
+  if (r != 0)
+    __builtin_abort ();
+  if (gu2.b.l != 10000001)
+    __builtin_abort ();
+
+  b = 0;
+  gu1.b.l = 20000000;
+  s = bar ();
+  if (s != 20000000)
+    __builtin_abort ();
+  if (gu2.b.l != 20000000)
+    __builtin_abort ();
+
+  b = 1;
+  gi = 456;
+  gu1.a.i1 = 123;
+  gu1.a.i2 = 234;
+  s = bar ();
+  if (s != 0)
+    __builtin_abort ();
+  if (gu2.a.i1 != 456)
+    __builtin_abort ();
+
+  return 0;
+}
Index: src/gcc/tree-sra.c
===================================================================
--- src.orig/gcc/tree-sra.c
+++ src/gcc/tree-sra.c
@@ -3087,15 +3087,13 @@ sra_modify_assign (gimple *stmt, gimple_
 	     ???  This should move to fold_stmt which we simply should
 	     call after building a VIEW_CONVERT_EXPR here.  */
 	  if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))
-	      && !contains_bitfld_comp_ref_p (lhs)
-	      && !access_has_children_p (lacc))
+	      && !contains_bitfld_comp_ref_p (lhs))
 	    {
 	      lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
 	      gimple_assign_set_lhs (*stmt, lhs);
 	    }
 	  else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
-		   && !contains_vce_or_bfcref_p (rhs)
-		   && !access_has_children_p (racc))
+		   && !contains_vce_or_bfcref_p (rhs))
 	    rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
 
 	  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
Index: src/gcc/testsuite/gcc.dg/tree-ssa/pr45144.c
===================================================================
--- src.orig/gcc/testsuite/gcc.dg/tree-ssa/pr45144.c
+++ src/gcc/testsuite/gcc.dg/tree-ssa/pr45144.c
@@ -43,5 +43,5 @@ bar (unsigned orig, unsigned *new)
   *new = foo (&a);
 }
 
-/* { dg-final { scan-tree-dump " = VIEW_CONVERT_EXPR<unsigned int>\\(a\\);" "optimized"} } */
+/* { dg-final { scan-tree-dump-not "unnamed-unsigned:19" "optimized"} } */
 /* { dg-final { cleanup-tree-dump "optimized" } } */
