diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c
index 46f92ba2d2f4e85c4256be11be5c8b1d40c21499..7b59f81e26423c60f8bf1c975281d3904315b306 100644
--- a/gcc/gimple-ssa-store-merging.c
+++ b/gcc/gimple-ssa-store-merging.c
@@ -126,6 +126,7 @@
 #include "tree-eh.h"
 #include "target.h"
 #include "gimplify-me.h"
+#include "selftest.h"
 
 /* The maximum size (in bits) of the stores this pass should generate.  */
 #define MAX_STORE_BITSIZE (BITS_PER_WORD)
@@ -1499,3 +1500,141 @@ make_pass_store_merging (gcc::context *ctxt)
 {
   return new pass_store_merging (ctxt);
 }
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Selftests for store merging helpers.  */
+
+/* Assert that all elements of the byte arrays X and Y, both of length N
+   are equal.  */
+
+static void
+verify_array_eq (unsigned char *x, unsigned char *y, unsigned int n)
+{
+  for (unsigned int i = 0; i < n; i++)
+    {
+      if (x[i] != y[i])
+	{
+	  fprintf (stderr, "Arrays do not match.  X:\n");
+	  dump_char_array (stderr, x, n);
+	  fprintf (stderr, "Y:\n");
+	  dump_char_array (stderr, y, n);
+	}
+      ASSERT_EQ (x[i], y[i]);
+    }
+}
+
+/* Test shift_bytes_in_array and that it carries bits across between
+   bytes correctly.  */
+
+static void
+verify_shift_bytes_in_array (void)
+{
+   /* byte 1   | byte 0
+      00011111 | 11100000.  */
+  unsigned char orig[2] = { 0xe0, 0x1f };
+  unsigned char in[2];
+  memcpy (in, orig, sizeof orig);
+
+  unsigned char expected[2] = { 0x80, 0x7f };
+  shift_bytes_in_array (in, sizeof (in), 2);
+  verify_array_eq (in, expected, sizeof (in));
+
+  memcpy (in, orig, sizeof orig);
+  memcpy (expected, orig, sizeof orig);
+  /* Check that shifting by zero doesn't change anything.  */
+  shift_bytes_in_array (in, sizeof (in), 0);
+  verify_array_eq (in, expected, sizeof (in));
+
+}
+
+/* Test shift_bytes_in_array_right and that it carries bits across between
+   bytes correctly.  */
+
+static void
+verify_shift_bytes_in_array_right (void)
+{
+   /* byte 1   | byte 0
+      00011111 | 11100000.  */
+  unsigned char orig[2] = { 0x1f, 0xe0};
+  unsigned char in[2];
+  memcpy (in, orig, sizeof orig);
+  unsigned char expected[2] = { 0x07, 0xf8};
+  shift_bytes_in_array_right (in, sizeof (in), 2);
+  verify_array_eq (in, expected, sizeof (in));
+
+  memcpy (in, orig, sizeof orig);
+  memcpy (expected, orig, sizeof orig);
+  /* Check that shifting by zero doesn't change anything.  */
+  shift_bytes_in_array_right (in, sizeof (in), 0);
+  verify_array_eq (in, expected, sizeof (in));
+}
+
+/* Test clear_bit_region that it clears exactly the bits asked and
+   nothing more.  */
+
+static void
+verify_clear_bit_region (void)
+{
+  /* Start with all bits set and test clearing various patterns in them.  */
+  unsigned char orig[3] = { 0xff, 0xff, 0xff};
+  unsigned char in[3];
+  unsigned char expected[3];
+  memcpy (in, orig, sizeof in);
+
+  /* Check zeroing out all the bits.  */
+  clear_bit_region (in, 0, 3 * BITS_PER_UNIT);
+  expected[0] = expected[1] = expected[2] = 0;
+  verify_array_eq (in, expected, sizeof in);
+
+  memcpy (in, orig, sizeof in);
+  /* Leave the first and last bits intact.  */
+  clear_bit_region (in, 1, 3 * BITS_PER_UNIT - 2);
+  expected[0] = 0x1;
+  expected[1] = 0;
+  expected[2] = 0x80;
+  verify_array_eq (in, expected, sizeof in);
+}
+
+/* Test verify_clear_bit_region_be that it clears exactly the bits asked and
+   nothing more.  */
+
+static void
+verify_clear_bit_region_be (void)
+{
+  /* Start with all bits set and test clearing various patterns in them.  */
+  unsigned char orig[3] = { 0xff, 0xff, 0xff};
+  unsigned char in[3];
+  unsigned char expected[3];
+  memcpy (in, orig, sizeof in);
+
+  /* Check zeroing out all the bits.  */
+  clear_bit_region_be (in, BITS_PER_UNIT - 1, 3 * BITS_PER_UNIT);
+  expected[0] = expected[1] = expected[2] = 0;
+  verify_array_eq (in, expected, sizeof in);
+
+  memcpy (in, orig, sizeof in);
+  /* Leave the first and last bits intact.  */
+  clear_bit_region_be (in, BITS_PER_UNIT - 2, 3 * BITS_PER_UNIT - 2);
+  expected[0] = 0x80;
+  expected[1] = 0;
+  expected[2] = 0x1;
+  verify_array_eq (in, expected, sizeof in);
+}
+
+
+/* Run all of the selftests within this file.  */
+
+void
+store_merging_c_tests (void)
+{
+  verify_shift_bytes_in_array ();
+  verify_shift_bytes_in_array_right ();
+  verify_clear_bit_region ();
+  verify_clear_bit_region_be ();
+}
+
+} // namespace selftest
+#endif /* CHECKING_P.  */
diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c
index 54a9b0f6c7ebc79881f9cb33b0a4c3d97c59c405..a796e07a856076c96cf97805a8ea831dd5a21045 100644
--- a/gcc/selftest-run-tests.c
+++ b/gcc/selftest-run-tests.c
@@ -77,6 +77,8 @@ selftest::run_tests ()
   /* This one relies on most of the above.  */
   function_tests_c_tests ();
 
+  store_merging_c_tests ();
+
   /* Run any lang-specific selftests.  */
   lang_hooks.run_lang_selftests ();
 
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 845eb01b12511e3667e5a83dd69e5fbcd888b808..dcce474be6e1899e46f7a9c0d1560e0b7eb60369 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -179,6 +179,7 @@ extern void selftest_c_tests ();
 extern void spellcheck_c_tests ();
 extern void spellcheck_tree_c_tests ();
 extern void sreal_c_tests ();
+extern void store_merging_c_tests ();
 extern void typed_splay_tree_c_tests ();
 extern void tree_c_tests ();
 extern void tree_cfg_c_tests ();
