diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index ca7b1f6..de085b0 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1416,6 +1416,7 @@ OBJS = \
 	sel-sched-ir.o \
 	sel-sched-dump.o \
 	sel-sched.o \
+	selftest-rtl.o \
 	selftest-run-tests.o \
 	sese.o \
 	shrink-wrap.o \
diff --git a/gcc/selftest-rtl.c b/gcc/selftest-rtl.c
new file mode 100644
index 0000000..e44e720
--- /dev/null
+++ b/gcc/selftest-rtl.c
@@ -0,0 +1,55 @@
+/* Selftest support for RTL.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "selftest.h"
+#include "backend.h"
+#include "target.h"
+#include "rtl.h"
+
+#if CHECKING_P
+
+/* Implementation detail of ASSERT_RTX_EQ.  If val_expected and val_actual
+   fail pointer-equality, print the location, "FAIL: ", and print the
+   mismatching RTL expressions to stderr, then abort.  */
+
+void
+selftest::assert_rtx_eq (const location &loc,
+			 const char *desc_expected, const char *desc_actual,
+			 rtx val_expected, rtx val_actual)
+{
+  if (val_expected == val_actual)
+    ::selftest::pass (loc, "ASSERT_RTL_EQ");
+  else
+    {
+      ::selftest::begin_fail (loc);
+      fprintf (stderr, "ASSERT_RTL_EQ (%s, %s)\n",
+	       desc_expected, desc_actual);
+      fprintf (stderr, "  expected=%p:\n    ", (void *)val_expected);
+      print_rtl (stderr, val_expected);
+      fprintf (stderr, "\n  actual=%p:\n    ", (void *)val_actual);
+      print_rtl (stderr, val_actual);
+      fprintf (stderr, "\n");
+      abort ();
+   }
+}
+
+#endif /* #if CHECKING_P */
diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c
index bddf0b2..cd2883d 100644
--- a/gcc/selftest-run-tests.c
+++ b/gcc/selftest-run-tests.c
@@ -55,6 +55,7 @@ selftest::run_tests ()
   tree_c_tests ();
   gimple_c_tests ();
   rtl_tests_c_tests ();
+  simplify_rtx_c_tests ();
 
   /* Higher-level tests, or for components that other selftests don't
      rely on.  */
diff --git a/gcc/selftest.c b/gcc/selftest.c
index ed6e517..af2b3f6 100644
--- a/gcc/selftest.c
+++ b/gcc/selftest.c
@@ -26,6 +26,16 @@ along with GCC; see the file COPYING3.  If not see
 
 int selftest::num_passes;
 
+/* Implementation detail of various failure handlers.  Print
+   the location, followed by "FAIL: ".  */
+
+void
+selftest::begin_fail (const location &loc)
+{
+  fprintf (stderr, "%s:%i: %s: FAIL: ", loc.m_file, loc.m_line,
+	   loc.m_function);
+}
+
 /* Record the successful outcome of some aspect of a test.  */
 
 void
@@ -39,8 +49,8 @@ selftest::pass (const location &/*loc*/, const char */*msg*/)
 void
 selftest::fail (const location &loc, const char *msg)
 {
-  fprintf (stderr,"%s:%i: %s: FAIL: %s\n", loc.m_file, loc.m_line,
-	   loc.m_function, msg);
+  begin_fail (loc);
+  fprintf (stderr, "%s\n", msg);
   abort ();
 }
 
@@ -51,8 +61,7 @@ selftest::fail_formatted (const location &loc, const char *fmt, ...)
 {
   va_list ap;
 
-  fprintf (stderr, "%s:%i: %s: FAIL: ", loc.m_file, loc.m_line,
-	   loc.m_function);
+  begin_fail (loc);
   va_start (ap, fmt);
   vfprintf (stderr, fmt, ap);
   va_end (ap);
diff --git a/gcc/selftest.h b/gcc/selftest.h
index c6becdd..2b76850 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -63,12 +63,23 @@ extern void fail (const location &loc, const char *msg);
 extern void fail_formatted (const location &loc, const char *fmt, ...)
  ATTRIBUTE_PRINTF_2;
 
+/* Implementation detail of various failure handlers.  Print
+   the location, followed by "FAIL: ".  */
+
+extern void begin_fail (const location &loc);
+
 /* Implementation detail of ASSERT_STREQ.  */
 
 extern void assert_streq (const location &loc,
 			  const char *desc_expected, const char *desc_actual,
 			  const char *val_expected, const char *val_actual);
 
+/* Implementation detail of ASSERT_RTX_EQ.  */
+
+extern void assert_rtx_eq (const location &loc,
+			   const char *desc_expected, const char *desc_actual,
+			   rtx val_expected, rtx val_actual);
+
 /* Declarations for specific families of tests (by source file), in
    alphabetical order.  */
 extern void bitmap_c_tests ();
@@ -84,6 +95,7 @@ extern void hash_set_tests_c_tests ();
 extern void input_c_tests ();
 extern void pretty_print_c_tests ();
 extern void rtl_tests_c_tests ();
+extern void simplify_rtx_c_tests ();
 extern void spellcheck_c_tests ();
 extern void spellcheck_tree_c_tests ();
 extern void tree_c_tests ();
@@ -183,6 +195,16 @@ extern int num_passes;
     ::selftest::fail (SELFTEST_LOCATION, desc);			\
   SELFTEST_END_STMT
 
+/* Evaluate rtx EXPECTED and ACTUAL and compare them (by pointer equality),
+   calling ::selftest::pass if they are equal, aborting if they are
+   non-equal.  */
+
+#define ASSERT_RTX_EQ(EXPECTED, ACTUAL) \
+  SELFTEST_BEGIN_STMT						    \
+  ::selftest::assert_rtx_eq (SELFTEST_LOCATION, #EXPECTED, #ACTUAL, \
+			     (EXPECTED), (ACTUAL));		    \
+  SELFTEST_END_STMT
+
 #define SELFTEST_BEGIN_STMT do {
 #define SELFTEST_END_STMT   } while (0)
 
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index a23a6f5..4ef342a 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "diagnostic-core.h"
 #include "varasm.h"
 #include "flags.h"
+#include "selftest.h"
 
 /* Simplification and canonicalization of RTL.  */
 
@@ -170,6 +171,29 @@ val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
   val &= (unsigned HOST_WIDE_INT) 1 << (width - 1);
   return val == 0;
 }
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Verify that the various *_signbit_p functions work correctly.  */
+
+static void
+test_sign_bits ()
+{
+  ASSERT_FALSE (val_signbit_p (QImode, 0));
+  ASSERT_TRUE (val_signbit_p (QImode, 0x80));
+
+  ASSERT_FALSE (val_signbit_known_set_p (SImode, 0));
+  ASSERT_TRUE (val_signbit_known_clear_p (SImode, 0));
+  ASSERT_TRUE (val_signbit_known_set_p (SImode, 0xffffffff));
+  ASSERT_FALSE (val_signbit_known_clear_p (SImode, 0xffffffff));
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
+
 
 /* Make a binary operation by properly ordering the operands and
    seeing if the expression folds.  */
@@ -6296,3 +6320,105 @@ simplify_rtx (const_rtx x)
     }
   return NULL;
 }
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Verify that simplify_rtx works correctly on various unary expressions.  */
+
+static void
+test_unary (machine_mode mode)
+{
+  /* (not (not reg)) -> reg.  */
+  rtx reg = gen_rtx_REG (mode, 0);
+  rtx expr = gen_rtx_NOT (mode, gen_rtx_NOT (mode, reg));
+  ASSERT_RTX_EQ (reg, simplify_rtx (expr));
+}
+
+/* Verify that simplify_rtx works correctly on various binary expressions.  */
+
+static void
+test_binary (machine_mode mode)
+{
+  rtx a = gen_rtx_REG (mode, 0);
+  rtx b = gen_rtx_REG (mode, 1);
+  /* (A & B) | A -> A.  */
+  ASSERT_RTX_EQ (a,
+		 simplify_rtx (gen_rtx_IOR (mode, gen_rtx_AND (mode, a, b),
+					    a)));
+
+  /* A | (A & B) -> A.  */
+  ASSERT_RTX_EQ (a,
+		 simplify_rtx (gen_rtx_IOR (mode, a,
+					    gen_rtx_AND (mode, a, b))));
+
+  if (!HONOR_SIGNED_ZEROS (mode) && CONST0_RTX(mode))
+    {
+      /* (A + 0) -> A.  */
+      ASSERT_RTX_EQ (a,
+		     simplify_rtx (gen_rtx_PLUS (mode, a, CONST0_RTX(mode))));
+
+      /* Currently this doesn't work for complex modes.  */
+      if (!COMPLEX_MODE_P (mode))
+	/* (0 + A) -> A.  */
+	ASSERT_RTX_EQ (a,
+		       simplify_rtx (gen_rtx_PLUS (mode, CONST0_RTX(mode), a)));
+    }
+
+}
+
+/* Verify that simplify_rtx works correctly on various ternary expressions.  */
+
+static void
+test_ternary (machine_mode mode)
+{
+  rtx a = gen_rtx_REG (mode, 0);
+  rtx b = gen_rtx_REG (mode, 1);
+  rtx c = gen_rtx_REG (mode, 2);
+
+  /* (1 ? a : b) -> a.  */
+  ASSERT_RTX_EQ (a,
+		 simplify_rtx (gen_rtx_IF_THEN_ELSE (mode,
+						     const1_rtx, a, b)));
+
+  /* (0 ? a : b) -> b.  */
+  ASSERT_RTX_EQ (b,
+		 simplify_rtx (gen_rtx_IF_THEN_ELSE (mode,
+						     const0_rtx, a, b)));
+
+  /* (c ? a : a) -> a.  */
+  ASSERT_RTX_EQ (a,
+		 simplify_rtx (gen_rtx_IF_THEN_ELSE (mode,
+						     c, a, a)));
+}
+
+/* Run all tests of simplify_rtx, using the given mode.  */
+
+static void
+run_tests_for_mode (machine_mode mode)
+{
+  test_unary (mode);
+  test_binary (mode);
+  test_ternary (mode);
+}
+
+/* Run all of the selftests within this file.  */
+
+void
+simplify_rtx_c_tests ()
+{
+  test_sign_bits ();
+
+  /* Run run_tests_for_mode for every machine mode available on the
+     target.  */
+  for (int i = VOIDmode; i < NUM_MACHINE_MODES; i++)
+    {
+      machine_mode mode = (machine_mode)i;
+      run_tests_for_mode (mode);
+    }
+}
+
+} // namespace selftest
+
+#endif /* CHECKING_P */
