diff mbox

simplify-rtx.c: start adding selftests (v2)

Message ID 1467833436-24291-1-git-send-email-dmalcolm@redhat.com
State New
Headers show

Commit Message

David Malcolm July 6, 2016, 7:30 p.m. UTC
On Sun, 2016-07-03 at 18:12 +0100, Richard Sandiford wrote:
> David Malcolm <dmalcolm@redhat.com> writes:
> > This patch starts adding selftests to simplify-rtx.c, to ensure
> > that
> > RTL expressions are simplified as we expect.
> >
> > It adds a new ASSERT_RTX_EQ macro that checks for pointer equality
> > of two rtx values.  If they're non-equal, it aborts, printing both
> > expressions.
>
> This might be a bit confusing when more tests are added, since
> pointer
> equality is only useful in certain specific cases (e.g. when you know
> you're dealing with CONST_INTs or pseudo registers).  How about
> making
> ASSERT_RTX_EQ check for rtx_equal_p equality and have something like
> ASSERT_RTX_PTR_EQ for cases where pointer equality really is needed?

> Also, how about using LAST_VIRTUAL_REGISTER + 1 as the base for
> register numbers?  DImode might not be valid for register 0 on
> all targets.

Thanks.  Here's an updated version which adds both ASSERT_RTX_EQ
and ASSERT_RTX_PTR_EQ.  The simplify-rtx.c tests can use the
stricter pointer equality test, so I updated them to use
ASSERT_RTX_PTR_EQ condition.

I added a selftest::make_test_reg to allocate pseudo regs, starting
at LAST_VIRTUAL_REGISTER + 1.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu

OK for trunk if it passes config-list.mk testing?

gcc/ChangeLog:
	* Makefile.in (OBJS): Add selftest-rtl.o.
	* selftest-rtl.c: New file.
	* selftest-run-tests.c (selftest::run_tests): Add call to
	simplify_rtx_c_tests.
	* selftest.c (selftest::begin_fail): New function.
	(selftest::fail): Reimplement in terms of begin_fail.
	(selftest::fail_formatted): Likewise.
	* selftest.h (selftest::begin_fail): New declaration.
	(selftest::assert_rtx_eq): New declaration.
	(selftest::assert_rtx_ptr_eq): New declaration.
	(selftest::simplify_rtx_c_tests): New declaration.
	(ASSERT_RTX_EQ): New macro.
	(ASSERT_RTX_PTR_EQ): New macro.
	* simplify-rtx.c: Include selftest.h.
	(selftest::make_test_reg): New function.
	(selftest::test_sign_bits): New function.
	(selftest::test_unary): New function.
	(selftest::test_binary): New function.
	(selftest::test_ternary): New function.
	(selftest::run_tests_for_mode): New function.
	(selftest::simplify_rtx_c_tests): New function.
---
 gcc/Makefile.in          |   1 +
 gcc/selftest-rtl.c       |  85 +++++++++++++++++++++++++++++
 gcc/selftest-run-tests.c |   1 +
 gcc/selftest.c           |  17 ++++--
 gcc/selftest.h           |  39 ++++++++++++++
 gcc/simplify-rtx.c       | 138 +++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 277 insertions(+), 4 deletions(-)
 create mode 100644 gcc/selftest-rtl.c

Comments

Jeff Law July 13, 2016, 7:38 p.m. UTC | #1
On 07/06/2016 01:30 PM, David Malcolm wrote:
>>
>> This might be a bit confusing when more tests are added, since
>> pointer equality is only useful in certain specific cases (e.g.
>> when you know you're dealing with CONST_INTs or pseudo registers).
>> How about making ASSERT_RTX_EQ check for rtx_equal_p equality and
>> have something like ASSERT_RTX_PTR_EQ for cases where pointer
>> equality really is needed?
>
>> Also, how about using LAST_VIRTUAL_REGISTER + 1 as the base for
>> register numbers?  DImode might not be valid for register 0 on all
>> targets.
>
> Thanks.  Here's an updated version which adds both ASSERT_RTX_EQ and
> ASSERT_RTX_PTR_EQ.  The simplify-rtx.c tests can use the stricter
> pointer equality test, so I updated them to use ASSERT_RTX_PTR_EQ
> condition.
Richard S. is definitely right here WRT using pointer equality vs deeper 
inspection.   The RTL structure sharing rules within GCC are something 
you have to be cognizant of here.  Thankfully the RTL structure sharing 
is reasonably well documented.
>
> I added a selftest::make_test_reg to allocate pseudo regs, starting
> at LAST_VIRTUAL_REGISTER + 1.
Also the right thing to do.  There's hard registers, then virtuals, then 
pseudos.

There's obviously much more we could do with the tests, but this is a 
reasonable start.

I note you iterate over all the modes -- which would include things like 
FP modes, BImode, and CC special modes and such.  I don't think we can 
necessarily be sure that the transformations you're testing are valid 
across all modes.

For example, does it even make sense to test (A & B) | A -> A for FP modes?

It almost seems like the iteration space has to be dependent on what 
you're testing.  Ie, some tests you want to iterate over the standard 
integer modes.  Other tests you might reasonably include FP modes.  CC 
modes I think should be forbidden for these tests.  THere may be others 
to ponder as well.


jeff
David Malcolm July 19, 2016, 3:46 p.m. UTC | #2
On Wed, 2016-07-13 at 13:38 -0600, Jeff Law wrote:
> On 07/06/2016 01:30 PM, David Malcolm wrote:
> > > 
> > > This might be a bit confusing when more tests are added, since
> > > pointer equality is only useful in certain specific cases (e.g.
> > > when you know you're dealing with CONST_INTs or pseudo
> > > registers).
> > > How about making ASSERT_RTX_EQ check for rtx_equal_p equality and
> > > have something like ASSERT_RTX_PTR_EQ for cases where pointer
> > > equality really is needed?
> > 
> > > Also, how about using LAST_VIRTUAL_REGISTER + 1 as the base for
> > > register numbers?  DImode might not be valid for register 0 on
> > > all
> > > targets.
> > 
> > Thanks.  Here's an updated version which adds both ASSERT_RTX_EQ
> > and
> > ASSERT_RTX_PTR_EQ.  The simplify-rtx.c tests can use the stricter
> > pointer equality test, so I updated them to use ASSERT_RTX_PTR_EQ
> > condition.
> Richard S. is definitely right here WRT using pointer equality vs
> deeper 
> inspection.   The RTL structure sharing rules within GCC are
> something 
> you have to be cognizant of here.  Thankfully the RTL structure
> sharing 
> is reasonably well documented.
> > 
> > I added a selftest::make_test_reg to allocate pseudo regs, starting
> > at LAST_VIRTUAL_REGISTER + 1.
> Also the right thing to do.  There's hard registers, then virtuals,
> then 
> pseudos.
> 
> There's obviously much more we could do with the tests, but this is a
> reasonable start.
> 
> I note you iterate over all the modes -- which would include things
> like 
> FP modes, BImode, and CC special modes and such.  I don't think we
> can 
> necessarily be sure that the transformations you're testing are valid
> across all modes.
> 
> For example, does it even make sense to test (A & B) | A -> A for FP
> modes?
> 
> It almost seems like the iteration space has to be dependent on what 
> you're testing.  Ie, some tests you want to iterate over the standard
> integer modes.  Other tests you might reasonably include FP modes. 
>  CC 
> modes I think should be forbidden for these tests.  THere may be
> others 
> to ponder as well.

Thanks.  My thinking here is to have the iteration over all modes, and
then filter it within the tests, with something like this at the top of
a test:

  if (!INTEGRAL_MODE_P (mode))
     return;

That said, and this is probably my relative unfamiliarity with RTL
speaking, but I'm not sure exactly how the modes should be filtered.

For example, my naive "run in all modes" approach ran into the issue
that although (A + 0) -> A works, (0 + A) -> A currently doesn't work
for complex modes (where "0" is CONST0_RTX(mode)).  Is that a bug?  If
so, since the run-in-all-modes approach uncovered it, was the testing
useful?

If that's the case, would it make sense to have some kind of
NORMAL_MODE_P (mode) filter, say, or conversely SPECIAL_MODE_P (mode),
and do an early-reject in the loop over all modes?  (to reject CCmode,
VOIDmode, BImode, I think; any others?).

Dave
Jeff Law July 29, 2016, 4:15 p.m. UTC | #3
On 07/19/2016 09:46 AM, David Malcolm wrote:

>> It almost seems like the iteration space has to be dependent on what
>> you're testing.  Ie, some tests you want to iterate over the standard
>> integer modes.  Other tests you might reasonably include FP modes.
>>  CC
>> modes I think should be forbidden for these tests.  THere may be
>> others
>> to ponder as well.
>
> Thanks.  My thinking here is to have the iteration over all modes, and
> then filter it within the tests, with something like this at the top of
> a test:
>
>   if (!INTEGRAL_MODE_P (mode))
>      return;
I guess that or something related can work.   I'm not offhand sure if 
BImode is considered integral or not :-)

I think you also have to worry about using a mode that is so side that 
the optimizers punt.  So for example you might want to verify that a+0 
== a in OImode, but there's a nonzero chance that the optimizers might 
punt OImode optimizations -- and it probably depends on the largest 
target mode that can be supported by a pair of HOST_WIDE_INTs.


> That said, and this is probably my relative unfamiliarity with RTL
> speaking, but I'm not sure exactly how the modes should be filtered.
It's not necessarily clear to me either.  I'm pointing on the most 
obvious problem areas.  I won't be at all surprised if we have to 
iterate on this a bit after installation.

>
> For example, my naive "run in all modes" approach ran into the issue
> that although (A + 0) -> A works, (0 + A) -> A currently doesn't work
> for complex modes (where "0" is CONST0_RTX(mode)).  Is that a bug?  If
> so, since the run-in-all-modes approach uncovered it, was the testing
> useful?
It depends.  0 + A isn't canonical, so I doubt the various folders have 
been written to handle it consistently.   There's going to be all kinds 
of stuff like that.

One might ask if the folders ought to canonicalize their inputs. 
Perhaps they should for the sake of consistency -- but the cost is the 
testing for something that isn't supposed to ever happen internally.

OTOH other things may be a preferred form, but not necessarily a 
canonical form.  So for example there's multiple ways to represent a 
zero extension.  There was a time when shift-add might be represented as 
a shift-add in one context, but mult-add in another (ugh).

So again, I don't think there's necessarily a clear answer here and the 
answer may change over time (as was the case with cleaning up the 
shift-add vs mult-add disaster).
>
> If that's the case, would it make sense to have some kind of
> NORMAL_MODE_P (mode) filter, say, or conversely SPECIAL_MODE_P (mode),
> and do an early-reject in the loop over all modes?  (to reject CCmode,
> VOIDmode, BImode, I think; any others?).
I'm not necessarily sure it's that simple, but we could start with that 
for basic folding and see what other knobs we need over time as the 
tests grow.

jeff
>
> Dave
>
diff mbox

Patch

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..20f4c21
--- /dev/null
+++ b/gcc/selftest-rtl.c
@@ -0,0 +1,85 @@ 
+/* 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
+
+/* Helper function for selftest::assert_rtx_eq and selftest::assert_rtx_ptr_eq.
+   Print VAL_EXPECTED and VAL_ACTUAL to stderr.  */
+
+static void
+print_non_equal_rtx (rtx val_expected, rtx val_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");
+}
+
+/* Implementation detail of ASSERT_RTX_EQ.  If val_expected and val_actual
+   fail rtx_equal_p, 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 (rtx_equal_p (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);
+      print_non_equal_rtx (val_expected, val_actual);
+      abort ();
+   }
+}
+
+/* Implementation detail of ASSERT_RTX_PTR_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_ptr_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_PTR_EQ");
+  else
+    {
+      ::selftest::begin_fail (loc);
+      fprintf (stderr, "ASSERT_RTL_PTR_EQ (%s, %s)\n",
+	       desc_expected, desc_actual);
+      print_non_equal_rtx (val_expected, val_actual);
+      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..e133989 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -63,12 +63,30 @@  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);
+
+/* Implementation detail of ASSERT_RTX_PTR_EQ.  */
+
+extern void assert_rtx_ptr_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 +102,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 +202,26 @@  extern int num_passes;
     ::selftest::fail (SELFTEST_LOCATION, desc);			\
   SELFTEST_END_STMT
 
+/* Evaluate rtx EXPECTED and ACTUAL and compare them (using rtx_equal_p),
+   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
+
+/* 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_PTR_EQ(EXPECTED, ACTUAL) \
+  SELFTEST_BEGIN_STMT							\
+  ::selftest::assert_rtx_ptr_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..db3c4eb 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,117 @@  simplify_rtx (const_rtx x)
     }
   return NULL;
 }
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Make a pseudo REG for use by selftests.  */
+
+static rtx
+make_test_reg (machine_mode mode)
+{
+  static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
+
+  return gen_rtx_REG (mode, test_reg_num++);
+}
+
+/* Verify that simplify_rtx works correctly on various unary expressions.  */
+
+static void
+test_unary (machine_mode mode)
+{
+  /* (not (not reg)) -> reg.  */
+  rtx reg = make_test_reg (mode);
+  rtx expr = gen_rtx_NOT (mode, gen_rtx_NOT (mode, reg));
+  ASSERT_RTX_PTR_EQ (reg, simplify_rtx (expr));
+}
+
+/* Verify that simplify_rtx works correctly on various binary expressions.  */
+
+static void
+test_binary (machine_mode mode)
+{
+  rtx a = make_test_reg (mode);
+  rtx b = make_test_reg (mode);
+  /* (A & B) | A -> A.  */
+  ASSERT_RTX_PTR_EQ (a,
+		     simplify_rtx (gen_rtx_IOR (mode, gen_rtx_AND (mode, a, b),
+						a)));
+
+  /* A | (A & B) -> A.  */
+  ASSERT_RTX_PTR_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_PTR_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_PTR_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 = make_test_reg (mode);
+  rtx b = make_test_reg (mode);
+  rtx c = make_test_reg (mode);
+
+  /* (1 ? a : b) -> a.  */
+  ASSERT_RTX_PTR_EQ (a,
+		 simplify_rtx (gen_rtx_IF_THEN_ELSE (mode,
+						     const1_rtx, a, b)));
+
+  /* (0 ? a : b) -> b.  */
+  ASSERT_RTX_PTR_EQ (b,
+		     simplify_rtx (gen_rtx_IF_THEN_ELSE (mode,
+							 const0_rtx, a, b)));
+
+  /* (c ? a : a) -> a.  */
+  ASSERT_RTX_PTR_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 */