diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 9f087e5c27a..753bf63c33c 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -99,7 +99,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dbgcnt.h"
 #include "builtins.h"
 #include "tree-sra.h"
-
+#include "langhooks.h"
 
 /* Enumeration of all aggregate reductions we can do.  */
 enum sra_mode { SRA_MODE_EARLY_IPA,   /* early call regularization */
@@ -2983,6 +2983,54 @@ create_total_scalarization_access (struct access *parent, HOST_WIDE_INT from,
   return access;
 }
 
+/* Create accesses to cover padding within PARENT, spanning from FROM to TO,
+   link it in between its children in between LAST_PTR and NEXT_SIBLING.  */
+
+static struct access **
+total_scalarization_fill_padding (struct access *parent, HOST_WIDE_INT from,
+				  HOST_WIDE_INT to, struct access **last_ptr,
+				  struct access *next_sibling)
+{
+  do
+    {
+      /* Diff cannot be bigger than max_scalarization_size in
+	 analyze_all_variable_accesses.  */
+      HOST_WIDE_INT diff = to - from;
+      gcc_assert (diff >= BITS_PER_UNIT);
+      HOST_WIDE_INT stsz = 1 << floor_log2 (diff);
+      tree type;
+      scalar_int_mode mode;
+
+      while (true)
+	{
+	  type = lang_hooks.types.type_for_size (stsz, 1);
+	  if (type
+	      && is_a <scalar_int_mode> (TYPE_MODE (type), &mode)
+	      && GET_MODE_BITSIZE (mode) == stsz)
+	    break;
+	  stsz /= 2;
+	  gcc_checking_assert (stsz >= BITS_PER_UNIT);
+	}
+
+      do {
+	tree expr = build_ref_for_offset (UNKNOWN_LOCATION, parent->base,
+					  from, parent->reverse, type, NULL,
+					  false);
+	struct access *access
+	  = create_total_scalarization_access (parent, from, stsz, type,
+					       expr, last_ptr, next_sibling);
+	access->grp_no_warning = 1;
+	last_ptr = &access->next_sibling;
+
+	from += stsz;
+      }
+      while (to - from >= stsz);
+      gcc_assert (from <= to);
+    }
+  while (from < to);
+  return last_ptr;
+}
+
 static bool totally_scalarize_subtree (struct access *root);
 
 /* Move **LAST_PTR along the chain of siblings until it points to an access
@@ -2991,16 +3039,35 @@ static bool totally_scalarize_subtree (struct access *root);
    false.  */
 
 static bool
-total_skip_all_accesses_until_pos (HOST_WIDE_INT pos, struct access ***last_ptr)
+total_skip_all_accesses_until_pos (struct access *root, HOST_WIDE_INT pos,
+				   HOST_WIDE_INT *covered,
+				   struct access ***last_ptr)
 {
   struct access *next_child = **last_ptr;
   while (next_child && next_child->offset < pos)
     {
       if (next_child->offset + next_child->size > pos)
 	return true;
+
+      if (*covered < next_child->offset)
+	{
+	  *last_ptr = total_scalarization_fill_padding (root, *covered,
+							next_child->offset,
+							*last_ptr, next_child);
+	  gcc_assert (next_child == **last_ptr);
+	}
+      *covered = next_child->offset + next_child->size;
       *last_ptr = &next_child->next_sibling;
       next_child = **last_ptr;
     }
+
+  if (*covered < pos)
+    {
+      *last_ptr = total_scalarization_fill_padding (root, *covered, pos,
+						   *last_ptr, next_child);
+      *covered = pos;
+    }
+
   return false;
 }
 
@@ -3112,18 +3179,22 @@ total_skip_children_over_scalar_type (HOST_WIDE_INT pos, HOST_WIDE_INT size,
    create an artificial access for the type at this position.  */
 
 static bool
-total_should_skip_creating_access (tree type, HOST_WIDE_INT pos,
-				   HOST_WIDE_INT size,
+total_should_skip_creating_access (struct access *root, tree type,
+				   HOST_WIDE_INT pos, HOST_WIDE_INT size,
+				   HOST_WIDE_INT *covered,
 				   struct access ***last_ptr)
 {
-  if (total_skip_all_accesses_until_pos (pos, last_ptr))
+  if (total_skip_all_accesses_until_pos (root, pos, covered, last_ptr))
     {
       *last_ptr = NULL;
       return false;
     }
 
   if (total_handle_child_matching_pos_size (pos, size, type, last_ptr))
-    return true;
+    {
+      *covered = pos + size;
+      return true;
+    }
   if (!*last_ptr)
     return false;
 
@@ -3138,7 +3209,10 @@ total_should_skip_creating_access (tree type, HOST_WIDE_INT pos,
 
   if (is_gimple_reg_type (type)
       && total_skip_children_over_scalar_type (pos, size, last_ptr))
-    return true;
+    {
+      *covered = pos + size;
+      return true;
+    }
 
   return false;
 }
@@ -3166,6 +3240,7 @@ totally_scalarize_subtree (struct access *root)
   gcc_checking_assert (!is_gimple_reg_type (root->type));
 
  struct access **last_ptr = &root->first_child;
+ HOST_WIDE_INT covered = root->offset;
 
   switch (TREE_CODE (root->type))
     {
@@ -3182,7 +3257,8 @@ totally_scalarize_subtree (struct access *root)
 
 	    HOST_WIDE_INT pos = root->offset + int_bit_position (fld);
 
-	    if (total_should_skip_creating_access (ft, pos, fsize, &last_ptr))
+	    if (total_should_skip_creating_access (root, ft, pos, fsize,
+						   &covered, &last_ptr))
 	      continue;
 	    if (!last_ptr)
 	      return false;
@@ -3204,6 +3280,7 @@ totally_scalarize_subtree (struct access *root)
 	    if (!is_gimple_reg_type (ft)
 		&& !totally_scalarize_subtree (new_child))
 	      return false;
+	    covered = pos + fsize;
 	  }
       break;
     case ARRAY_TYPE:
@@ -3236,8 +3313,8 @@ totally_scalarize_subtree (struct access *root)
 	     pos += el_size, ++idx)
 	  {
 	    gcc_checking_assert (last_ptr);
-	    if (total_should_skip_creating_access (elemtype, pos, el_size,
-						   &last_ptr))
+	    if (total_should_skip_creating_access (root, elemtype, pos, el_size,
+						   &covered, &last_ptr))
 	      continue;
 	    if (!last_ptr)
 	      return false;
@@ -3261,6 +3338,7 @@ totally_scalarize_subtree (struct access *root)
 	      return false;
 
 	    last_ptr = &new_child->next_sibling;
+	    covered = pos + el_size;
 	  }
       }
       break;
@@ -3269,6 +3347,10 @@ totally_scalarize_subtree (struct access *root)
     }
 
  out:
+  HOST_WIDE_INT limit = root->offset + root->size;
+  if (covered < limit)
+    total_scalarization_fill_padding (root, covered, limit, last_ptr, NULL);
+
   return true;
 }
 
