From 8fc0d5dd1470a358ba257b06fad9d188ac79cf07 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 3 Aug 2016 15:54:52 -0400
Subject: [PATCH 30/42] FIXME: initial version of rtl1, on top of dump reader

---
 gcc/gcc.c                                          |   1 +
 gcc/rtl/Make-lang.in                               | 149 +++++++
 gcc/rtl/config-lang.in                             |  36 ++
 gcc/rtl/lang-specs.h                               |  25 ++
 gcc/rtl/lang.opt                                   |  38 ++
 gcc/rtl/notes.rst                                  | 219 ++++++++++
 gcc/rtl/rtl-errors.c                               |  35 ++
 gcc/rtl/rtl-frontend.c                             | 475 +++++++++++++++++++++
 gcc/testsuite/lib/rtl-dg.exp                       |  64 +++
 gcc/testsuite/rtl.dg/dfinit.rtl                    |  90 ++++
 gcc/testsuite/rtl.dg/final.rtl                     |  51 +++
 gcc/testsuite/rtl.dg/good-include.rtl              |   6 +
 gcc/testsuite/rtl.dg/good-includee.md              |   1 +
 gcc/testsuite/rtl.dg/into-cfglayout.rtl            |  85 ++++
 gcc/testsuite/rtl.dg/ira.rtl                       |  84 ++++
 gcc/testsuite/rtl.dg/missing-include.rtl           |   1 +
 gcc/testsuite/rtl.dg/pro_and_epilogue.rtl          |  38 ++
 gcc/testsuite/rtl.dg/roundtrip/code-labels.rtl     |   2 +
 gcc/testsuite/rtl.dg/roundtrip/frame-pointer.rtl   |   4 +
 gcc/testsuite/rtl.dg/roundtrip/insn-with-mode.rtl  |   4 +
 gcc/testsuite/rtl.dg/roundtrip/jump-to-label.rtl   |   6 +
 gcc/testsuite/rtl.dg/roundtrip/jump-to-return.rtl  |   6 +
 .../rtl.dg/roundtrip/jump-to-simple-return.rtl     |   6 +
 .../rtl.dg/roundtrip/note-insn-basic-block.rtl     |   1 +
 .../rtl.dg/roundtrip/note-insn-deleted.rtl         |   1 +
 .../rtl.dg/roundtrip/reg-with-orig-regno.rtl       |   4 +
 gcc/testsuite/rtl.dg/roundtrip/roundtrip.exp       |  99 +++++
 .../rtl.dg/roundtrip/test-loop.cleaned.rtl         |  75 ++++
 .../rtl.dg/roundtrip/test-switch-after-expand.rtl  | 202 +++++++++
 gcc/testsuite/rtl.dg/rtl.exp                       |  43 ++
 gcc/testsuite/rtl.dg/test.c                        |  31 ++
 gcc/testsuite/rtl.dg/unknown-insn-uid.rtl          |   3 +
 gcc/testsuite/rtl.dg/unknown-rtx-code.rtl          |   1 +
 gcc/testsuite/rtl.dg/vregs.rtl                     |  80 ++++
 34 files changed, 1966 insertions(+)
 create mode 100644 gcc/rtl/Make-lang.in
 create mode 100644 gcc/rtl/config-lang.in
 create mode 100644 gcc/rtl/lang-specs.h
 create mode 100644 gcc/rtl/lang.opt
 create mode 100644 gcc/rtl/notes.rst
 create mode 100644 gcc/rtl/rtl-errors.c
 create mode 100644 gcc/rtl/rtl-frontend.c
 create mode 100644 gcc/testsuite/lib/rtl-dg.exp
 create mode 100644 gcc/testsuite/rtl.dg/dfinit.rtl
 create mode 100644 gcc/testsuite/rtl.dg/final.rtl
 create mode 100644 gcc/testsuite/rtl.dg/good-include.rtl
 create mode 100644 gcc/testsuite/rtl.dg/good-includee.md
 create mode 100644 gcc/testsuite/rtl.dg/into-cfglayout.rtl
 create mode 100644 gcc/testsuite/rtl.dg/ira.rtl
 create mode 100644 gcc/testsuite/rtl.dg/missing-include.rtl
 create mode 100644 gcc/testsuite/rtl.dg/pro_and_epilogue.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/code-labels.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/frame-pointer.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/insn-with-mode.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/jump-to-label.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/jump-to-return.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/jump-to-simple-return.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/note-insn-basic-block.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/note-insn-deleted.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/reg-with-orig-regno.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/roundtrip.exp
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/test-loop.cleaned.rtl
 create mode 100644 gcc/testsuite/rtl.dg/roundtrip/test-switch-after-expand.rtl
 create mode 100644 gcc/testsuite/rtl.dg/rtl.exp
 create mode 100644 gcc/testsuite/rtl.dg/test.c
 create mode 100644 gcc/testsuite/rtl.dg/unknown-insn-uid.rtl
 create mode 100644 gcc/testsuite/rtl.dg/unknown-rtx-code.rtl
 create mode 100644 gcc/testsuite/rtl.dg/vregs.rtl

diff --git a/gcc/gcc.c b/gcc/gcc.c
index d3e8c88..5c4595d 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1296,6 +1296,7 @@ static const struct compiler default_compilers[] =
   {".java", "#Java", 0, 0, 0}, {".class", "#Java", 0, 0, 0},
   {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0},
   {".go", "#Go", 0, 1, 0},
+  {".rtl", "#RTL", 0, 1, 0},
   /* Next come the entries for C.  */
   {".c", "@c", 0, 0, 1},
   {"@c",
diff --git a/gcc/rtl/Make-lang.in b/gcc/rtl/Make-lang.in
new file mode 100644
index 0000000..45dea07
--- /dev/null
+++ b/gcc/rtl/Make-lang.in
@@ -0,0 +1,149 @@
+# Make-lang.in -- Top level -*- makefile -*- fragment for RTL frontend.
+
+# 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/>.
+
+# This file provides the language dependent support in the main Makefile.
+
+# The name for selecting the RTL frontend in LANGUAGES.
+rtl: rtl1$(exeext)
+
+.PHONY: rtl
+
+# Use strict warnings.
+rtl-warn = $(STRICT_WARN)
+
+RTL_OBJS = \
+	rtl/rtl-errors.o \
+	rtl/rtl-frontend.o \
+	read-md.o \
+	read-rtl.o \
+	read-rtl-function.o
+
+rtl1$(exeext): $(RTL_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
+	+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	      $(RTL_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+
+# Build hooks:
+
+rtl.all.cross:
+rtl.start.encap:
+rtl.rest.encap:
+rtl.info:
+rtl.man:
+
+lang_checks += check-rtl
+lang_checks_parallelized += check-rtl
+check_rtl_parallelize = 10
+
+# Install hooks.
+
+rtl.install-common: installdirs
+	-rm -f $(DESTDIR)$(bindir)/$(GCCRTL_INSTALL_NAME)$(exeext)
+	$(INSTALL_PROGRAM) gccrtl$(exeext) $(DESTDIR)$(bindir)/$(GCCRTL_INSTALL_NAME)$(exeext)
+	-if test -f rtl1$(exeext); then \
+	  if test -f gccrtl-cross$(exeext); then \
+	    :; \
+	  else \
+	    rm -f $(DESTDIR)$(bindir)/$(GCCRTL_TARGET_INSTALL_NAME)$(exeext); \
+	    ( cd $(DESTDIR)$(bindir) && \
+	      $(LN) $(GCCRTL_INSTALL_NAME)$(exeext) $(GCCRTL_TARGET_INSTALL_NAME)$(exeext) ); \
+	  fi; \
+	fi
+
+rtl.install-plugin:
+
+rtl.install-info: $(DESTDIR)$(infodir)/gccrtl.info
+
+rtl.install-pdf: doc/gccrtl.pdf
+	@$(NORMAL_INSTALL)
+	test -z "$(pdfdir)" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)/gcc"
+	@for p in doc/gccrtl.pdf; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(pdf__strip_dir) \
+	  echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/gcc/$$f'"; \
+	  $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/gcc/$$f"; \
+	done
+
+rtl.install-html: $(build_htmldir)/rtl
+	@$(NORMAL_INSTALL)
+	test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)"
+	@for p in $(build_htmldir)/rtl; do \
+	  if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; fi; \
+	  f=$(html__strip_dir) \
+	  if test -d "$$d$$p"; then \
+	    echo " $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'"; \
+	    $(mkinstalldirs) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+	    echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+	    $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \
+	  else \
+	    echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
+	    $(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
+	  fi; \
+	done
+
+rtl.install-man: $(DESTDIR)$(man1dir)/$(GCCRTL_INSTALL_NAME)$(man1ext)
+
+$(DESTDIR)$(man1dir)/$(GCCRTL_INSTALL_NAME)$(man1ext): doc/gccrtl.1 installdirs
+	-rm -f $@
+	-$(INSTALL_DATA) $< $@
+	-chmod a-x $@
+
+rtl.uninstall:
+	rm -rf $(DESTDIR)$(bindir)/$(GCCRTL_INSTALL_NAME)$(exeext)
+	rm -rf $(DESTDIR)$(man1dir)/$(GCCRTL_INSTALL_NAME)$(man1ext)
+	rm -rf $(DESTDIR)$(bindir)/$(GCCRTL_TARGET_INSTALL_NAME)$(exeext)
+	rm -rf $(DESTDIR)$(infodir)/gccrtl.info*
+
+# Clean hooks.
+
+rtl.mostlyclean:
+	-rm -f rtl/*$(objext)
+	-rm -f rtl/*$(coverageexts)
+	-rm -f gccrtl$(exeext) gccrtl-cross$(exeext) rtl1$(exeext)
+rtl.clean:
+rtl.distclean:
+rtl.maintainer-clean:
+	-rm -f $(docobjdir)/gccrtl.1
+
+# Stage hooks.
+
+rtl.stage1: stage1-start
+	-mv rtl/*$(objext) stage1/rtl
+rtl.stage2: stage2-start
+	-mv rtl/*$(objext) stage2/rtl
+rtl.stage3: stage3-start
+	-mv rtl/*$(objext) stage3/rtl
+rtl.stage4: stage4-start
+	-mv rtl/*$(objext) stage4/rtl
+rtl.stageprofile: stageprofile-start
+	-mv rtl/*$(objext) stageprofile/rtl
+rtl.stagefeedback: stagefeedback-start
+	-mv rtl/*$(objext) stagefeedback/rtl
+
+CFLAGS-rtl/rtl-lang.o += -DDEFAULT_TARGET_VERSION=\"$(version)\" \
+	-DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\"
+
+RTLINCLUDES = -I $(srcdir)/rtl -I $(srcdir)/rtl/rtlfrontend
+
+CFLAGS-rtl/rtl-gcc.o += $(RTLINCLUDES)
+CFLAGS-rtl/rtl-linemap.o += $(RTLINCLUDES)
+
+rtl/%.o: rtl/rtlfrontend/%.c
+	$(COMPILE) $(RTLINCLUDES) $<
+	$(POSTCOMPILE)
diff --git a/gcc/rtl/config-lang.in b/gcc/rtl/config-lang.in
new file mode 100644
index 0000000..3b101ce
--- /dev/null
+++ b/gcc/rtl/config-lang.in
@@ -0,0 +1,36 @@
+# config-lang.in -- Top level configure fragment for RTL frontend.
+
+# 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/>.
+
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language	- name of language as it would appear in $(LANGUAGES)
+# compilers	- value to add to $(COMPILERS)
+
+language="rtl"
+
+compilers="rtl1\$(exeext)"
+
+target_libs=""
+
+gtfiles="\$(srcdir)/rtl/rtl-frontend.c"
+
+# Do not build by default.
+build_by_default="no"
diff --git a/gcc/rtl/lang-specs.h b/gcc/rtl/lang-specs.h
new file mode 100644
index 0000000..2af33ab
--- /dev/null
+++ b/gcc/rtl/lang-specs.h
@@ -0,0 +1,25 @@
+/* lang-specs.h -- gcc driver specs for RTL frontend.
+   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/>.  */
+
+/* This is the contribution to the `default_compilers' array in gcc.c
+   for the RTL frontend.  */
+
+{".rtl",  "@RTL", 0, 1, 0},
+{"@RTL",  "rtl1 %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}",
+    0, 1, 0},
diff --git a/gcc/rtl/lang.opt b/gcc/rtl/lang.opt
new file mode 100644
index 0000000..42adac0
--- /dev/null
+++ b/gcc/rtl/lang.opt
@@ -0,0 +1,38 @@
+; lang.opt -- Options for the gcc RTL front end.
+
+; 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/>.
+
+; See the GCC internals manual for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+Language
+RTL
+
+froundtrip=
+RTL Joined RejectNegative
+After loading the RTL input file, immediately dump it to the given path,
+for sanity-checking the loader.
+
+fsingle-pass=
+RTL Joined RejectNegative
+After loading the RTL input file, run the specified pass on it.
+
+
+; This comment is to ensure we retain the blank line above.
diff --git a/gcc/rtl/notes.rst b/gcc/rtl/notes.rst
new file mode 100644
index 0000000..9442ce3
--- /dev/null
+++ b/gcc/rtl/notes.rst
@@ -0,0 +1,219 @@
+RTL frontend
+============
+
+Purpose
+-------
+
+Historically GCC testing has been done by providing source files
+to be built with various command-line options (via DejaGnu
+directives), dumping state at pertinent places, and verifying
+properties of the state via these dumps.
+
+A strength of this approach is that we have excellent integration
+testing, as every test case exercises the toolchain as a whole, but
+it has the drawback that when testing a specific pass,
+we have little control of the input to that specific pass.  We
+provide input, and the various passes transform the state
+of the internal representation::
+
+  INPUT -> PASS-1 -> STATE-1 -> PASS-2 -> STATE-2 -> ...
+    -> etc ->
+    -> ... -> PASS-n-1 -> STATE-n-1 -> PASS-n -> STATE-n
+                          ^            ^         ^
+                          |            |         Output from the pass
+                          |            The pass we care about
+                          The actual input to the pass
+
+so the intervening passes before "PASS-n" could make changes to the
+IR that affect the input seen by our pass ("STATE-n-1" above).  This
+can break our test cases, sometimes in a form that's visible,
+sometimes invisibly (e.g. where a test case silently stops providing
+coverage).
+
+The aim of the RTL frontend is to provide a convenient way to test
+individual passes in the backend, by loading dumps of specific RTL
+state (possibly edited by hand), and then running just one specific
+pass on them, so that we effectively have this::
+
+  INPUT -> PASS-n -> OUTPUT
+
+thus fixing the problem above.
+
+My hope is that this makes it easy to write more fine-grained and
+robust test coverage for the RTL phase of GCC.  However I see this
+as *complementary* to the existing "integrated testing" approach:
+patches should include both RTL frontend tests *and* integrated tests,
+to avoid regressing the great integration testing we currently have.
+
+The idea is to use the existing dump format as a input format, since
+presumably existing GCC developers are very familiar with the dump
+format.
+
+One other potential benefit of this approach is to allow unit-testing
+of machine descriptions - we could provide specific RTL fragments,
+and have the rtl.dg testsuite directly verify that we recognize all
+instructions and addressing modes that a given target ought to support.
+
+Structure
+---------
+
+The RTL frontend is similar to a regular frontend: a ``gcc/rtl``
+subdirectory within the source tree contains frontend-specific hooks.
+These provide a new ``rtl`` frontend, which can be optionally
+enabled at configuration time within ``--enable-languages``.
+
+If enabled, it builds an ``rtl1`` binary, which is invoked by the
+``gcc`` driver on files with a ``.rtl`` extension.
+
+The testsuite is below ``gcc/testsuite/rtl.dg``.  There's also
+a ``roundtrip`` subdirectory below this, in which every ``.rtl``
+file is loaded and then dumped; ``roundtrip.exp`` verifies that
+the dump is identical to the original file, thus ensuring that
+the RTL loaders faithfully rebuild the input dump.
+
+Limitations
+-----------
+
+* It's a work-in-progress.  There will be bugs.
+
+* The existing RTL code is structured around a single function being
+  optimized, so, as a simplification, the RTL frontend can only handle
+  one function per input file.  Also, the dump format currently uses
+  comments to separate functions::
+
+    ;; Function test_1 (test_1, funcdef_no=0, decl_uid=1758, cgraph_uid=0, symbol_order=0)
+
+    ... various pass-specific things, sometimes expressed as comments,
+    sometimes not
+
+    ;;
+    ;; Full RTL generated for this function:
+    ;;
+    (note 1 0 6 NOTE_INSN_DELETED)
+    ;; etc, insns for function "test_1" go here
+    (insn 27 26 0 6 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+         (nil))
+
+    ;; Function test_2 (test_2, funcdef_no=1, decl_uid=1765, cgraph_uid=1, symbol_order=1)
+    ... various pass-specific things, sometimes expressed as comments,
+    sometimes not
+    ;;
+    ;; Full RTL generated for this function:
+    ;;
+    (note 1 0 5 NOTE_INSN_DELETED)
+    ;; etc, insns for function "test_2" go here
+    (insn 59 58 0 8 (use (reg/i:SF 21 xmm0)) ../../src/gcc/testsuite/rtl.dg/test.c:31 -1
+         (nil))
+
+  so that there's no clear separation of the instructions between the
+  two functions (and no metadata e.g. function names).
+
+  This could be fixed by adding a new clause to the dump e.g.::
+
+    (function "test_1" [
+      (note 1 0 6 NOTE_INSN_DELETED)
+      ;; etc, insns for function "test_1" go here
+      (insn 27 26 0 6 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+           (nil))
+      ])
+
+    (function "test_2" [
+      (note 1 0 5 NOTE_INSN_DELETED)
+      ;; etc, insns for function "test_2" go here
+      (insn 59 58 0 8 (use (reg/i:SF 21 xmm0)) ../../src/gcc/testsuite/rtl.dg/test.c:31 -1
+           (nil))
+      ])
+
+  or somesuch (this wouldn't be an rtx code, just something in rtl-frontend.c).
+  The RTL frontend could then compile each function in turn after parsing each
+  one (probably the easiest way to deal with the global state in the RTL parts
+  of the compiler).
+
+* The RTL frontend doesn't have any knowledge of the name of the function,
+  of parameters, types, locals, globals, etc.  It creates a single function.
+  The function is currently hardcoded to have this signature:
+
+     int test_1 (int, int, int);
+
+  since there's no syntax for specify otherwise, and we need to provide
+  a ``FUNCTION_DECL`` tree when building a function object (by calling
+  ``allocate_struct_function``).
+
+* Similarly, there are no types beyond the built-in ones; all expressions
+  are treated as being of type ``int``.  I suspect that this approach
+  will be too simplistic when it comes to e.g. aliasing.
+
+* There's no support for running more than one pass; fixing this would
+  require being able to run passes from a certain point onwards.
+
+* Roundtripping of recognized instructions may be an issue (i.e. those
+  with ``INSN_CODE`` != -1), such as the ``667 {jump}`` in the following::
+
+    (jump_insn 50 49 51 10
+      (set (pc)
+           (label_ref:DI 59)) ../../src/test-switch.c:18 667 {jump}
+           (nil) -> 59)
+
+  since the integer ID can change when the .md files are changed
+  (and the associated pattern name is very much target-specific).
+  It may be best to reset them to -1 in the input files (and delete the
+  operation name), giving::
+
+    (jump_insn 50 49 51 10
+      (set (pc)
+           (label_ref:DI 59)) ../../src/test-switch.c:18 -1
+           (nil) -> 59)
+
+* Currently there's no explicit CFG edge information in the dumps.
+  The ``rtl1`` frontend reconstructs the edges based on jump instructions.
+  As I understand the `distinction between cfgrtl and cfglayout modes
+  https://gcc.gnu.org/wiki/cfglayout_mode`_ , this is OK for "cfgrtl" mode,
+  but isn't going to work for "cfglayout" mode - in the latter,
+  unconditional jumps are represented purely by edges in the CFG, and this
+  information isn't currently present in the dumps  (perhaps we could add it
+  if it's an issue).
+
+Open Questions
+--------------
+
+* Register numbering: consider this fragment of RTL emitted during
+  expansion::
+
+    (reg/f:DI 82 virtual-stack-vars)
+
+  At the time of emission, register 82 is the ``VIRTUAL_STACK_VARS_REGNUM``,
+  and this value is effectively hardcoded into the dump.  Presumably this
+  is baking in assumptions about the target into the test.  Also, how likely is
+  this value to change?  When we reload the dump, should we notice that this
+  is tagged with ``virtual-stack-vars`` and override the specific register
+  number to use the current value of ``VIRTUAL_STACK_VARS_REGNUM`` on the
+  target ``rtl1`` was built for?
+
+TODO items
+----------
+
+* test with other architectures
+
+* roundtrip.exp: strip out comments in source when comparing roundtrip
+
+* example with "-g"
+
+* implement a fuzzer (or use AFL on the existing test cases)
+
+Cross-arch issues
+-----------------
+* roundtrip.exp fails: different register names so e.g. this from x86_64::
+
+     (reg:SI 5 di [ i ]))
+
+  becomes this after roundtripping on aarch64::
+
+     (reg:SI 5 x5 [ i ]))
+
+  (i.e. ``di`` vs ``x5``).
+
+* rtl.exp failures: unknown modes e.g. this from x86_64::
+
+    (reg:CCGC 17 flags)
+
+  fails on aarch64 due to the lack of a "CCGC" mode.
diff --git a/gcc/rtl/rtl-errors.c b/gcc/rtl/rtl-errors.c
new file mode 100644
index 0000000..0c6d4ab
--- /dev/null
+++ b/gcc/rtl/rtl-errors.c
@@ -0,0 +1,35 @@
+/* rtl-error.c - Replacement for errors.c for use by RTL frontend
+   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 "errors.h"
+
+/* FIXME.  */
+
+void
+fatal (const char *, ...)
+{
+  // TODO
+  abort ();
+}
+
+int have_error;
+
diff --git a/gcc/rtl/rtl-frontend.c b/gcc/rtl/rtl-frontend.c
new file mode 100644
index 0000000..1523457
--- /dev/null
+++ b/gcc/rtl/rtl-frontend.c
@@ -0,0 +1,475 @@
+/* rtl-frontend.c - Top-level of RTL frontend
+   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 "target.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "diagnostic.h"
+#include "opts.h"
+#include "fold-const.h"
+#include "gimplify.h"
+#include "stor-layout.h"
+#include "debug.h"
+#include "convert.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "common/common-target.h"
+#include "read-md.h"
+#include <mpfr.h>
+#include "rtl.h"
+#include "cfghooks.h"
+#include "stringpool.h"
+#include "function.h"
+#include "tree-cfg.h"
+#include "cfg.h"
+#include "basic-block.h"
+#include "cfgrtl.h"
+#include "deferred-locations.h"
+#include "emit-rtl.h"
+#include "cgraph.h"
+#include "tree-pass.h"
+#include "context.h"
+#include "pass_manager.h"
+#include "toplev.h"
+#include "bitmap.h"
+#include "df.h"
+#include "regs.h"
+#include "varasm.h"
+#include "insn-addr.h"
+#include "read-rtl-function.h"
+
+/* Language-dependent contents of a type.  */
+
+struct GTY(()) lang_type
+{
+  char dummy;
+};
+
+/* Language-dependent contents of a decl.  */
+
+struct GTY(()) lang_decl
+{
+  char dummy;
+};
+
+/* Language-dependent contents of an identifier.  This must include a
+   tree_identifier.  */
+
+struct GTY(()) lang_identifier
+{
+  struct tree_identifier common;
+};
+
+/* The resulting tree type.  */
+
+union GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
+	   chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
+lang_tree_node
+{
+  union tree_node GTY((tag ("0"),
+		       desc ("tree_node_structure (&%h)"))) generic;
+  struct lang_identifier GTY((tag ("1"))) identifier;
+};
+
+/* We don't use language_function.  */
+
+struct GTY(()) language_function
+{
+  int dummy;
+};
+
+/* Language hooks.  */
+
+/* Implementation of LANG_HOOKS_INIT for the RTL frontend.  */
+
+static bool
+rtl_langhook_init (void)
+{
+  in_rtl_frontend_p = true;
+
+  build_common_tree_nodes (false);
+
+  /* I don't know why this has to be done explicitly.  */
+  void_list_node = build_tree_list (NULL_TREE, void_type_node);
+
+  build_common_builtin_nodes ();
+
+  /* The default precision for floating point numbers.  This is used
+     for floating point constants with abstract type.  This may
+     eventually be controllable by a command line option.  */
+  mpfr_set_default_prec (256);
+
+  return true;
+}
+
+/* Implementation of LANG_HOOKS_OPTION_LANG_MASK for the RTL frontend.  */
+
+static unsigned int
+rtl_langhook_option_lang_mask (void)
+{
+  return CL_RTL;
+}
+
+/* The value of "-froundtrip=", if any.  */
+
+static const char *roundtrip_filename = NULL;
+
+/* The value of "-fsingle-pass=", if any.  */
+
+static const char *single_pass_name = NULL;
+
+/* Implementation of LANG_HOOKS_HANDLE_OPTION for the RTL frontend.  */
+
+static bool
+rtl_langhook_handle_option (
+    size_t scode,
+    const char *arg,
+    int value ATTRIBUTE_UNUSED,
+    int kind ATTRIBUTE_UNUSED,
+    location_t loc ATTRIBUTE_UNUSED,
+    const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
+{
+  enum opt_code code = (enum opt_code) scode;
+
+  switch (code)
+    {
+    case OPT_froundtrip_:
+      roundtrip_filename = xstrdup (arg);
+      break;
+
+    case OPT_fsingle_pass_:
+      single_pass_name =  xstrdup (arg);
+      break;
+
+    default:
+      break;
+    }
+  return true;
+}
+
+/*  Locate and run PASS_NAME on cfun.  */
+
+static void
+run_one_pass_by_name (const char *pass_name)
+{
+  opt_pass *pass = g->get_passes ()->get_pass_by_name (pass_name);
+  if (!pass)
+    {
+      error_at (UNKNOWN_LOCATION, "unrecognized pass: %qs", pass_name);
+      return;
+    }
+
+  /* Forcibly create the dataflow instance.  We'll need to do this on passes
+     that normally occur after pass_df_initialize/pass_df_initialize_no_opt.  */
+  /* FIXME: better conditional logic here.  */
+  if (0 == strcmp (pass_name, "rtl-ira")
+      || 0 == strcmp (pass_name, "rtl-reload")
+      || 0 == strcmp (pass_name, "rtl-pro_and_epilogue"))
+    {
+      opt_pass *df_pass = g->get_passes ()->get_pass_by_name ("rtl-dfinit");
+      gcc_assert (df_pass);
+      current_function_decl = cfun->decl;
+      df_pass->execute (cfun);
+
+      /* The dataflow instance should now exist.  */
+      gcc_assert (df);
+
+      df_analyze ();
+    }
+
+  /* Ensure reg_renumber is set up.  */
+  resize_reg_info ();
+
+  max_regno = max_reg_num ();
+
+  /* Pass "reload" sets the global "reload_completed", and many things
+     depend on this (e.g. instructions in .md files).  */
+  /* FIXME: better conditional logic here.  */
+  if (0 == strcmp (pass_name, "rtl-final"))
+    reload_completed = 1;
+
+  /* The INSN_ADDRESSES vec is normally set up by shorten_branches; we must
+     manually set it up for passes that run after this.  */
+  /* FIXME: better conditional logic here.  */
+  if (0 == strcmp (pass_name, "rtl-final"))
+    INSN_ADDRESSES_ALLOC (get_max_uid ());
+
+  /* Run the user-specified pass.  */
+  bitmap_obstack_initialize (NULL);
+  bitmap_obstack_initialize (&reg_obstack);
+  pass_init_dump_file (pass);
+  current_function_decl = cfun->decl;
+  pass->execute (cfun);
+  current_function_decl = NULL;
+  if (dump_file)
+    print_rtl_with_bb (dump_file, get_insns (), dump_flags);
+  pass_fini_dump_file (pass);
+  bitmap_obstack_release (&reg_obstack);
+}
+
+/* Implementation of LANG_HOOKS_PARSE_FILE for the RTL frontend.  */
+
+static void
+rtl_langhook_parse_file (void)
+{
+  in_rtl_frontend_p = true;
+
+  initialize_rtl ();
+  init_emit ();
+  init_varasm_status ();
+
+  auto_vec<const char *> argv (num_in_fnames + 1);
+  argv.safe_push (progname);
+  for (unsigned i = 0; i < num_in_fnames; i++)
+    argv.safe_push (in_fnames[i]);
+  if (!read_rtl_function_body (argv.length (), argv.address (), NULL))
+    return;
+
+  /* If -froundtrip=FILENAME was provided, immediately dump the
+     result, so that the testsuite can compare it against the
+     input dump.  */
+  if (roundtrip_filename)
+    {
+      FILE *out = fopen (roundtrip_filename, "w");
+      if (out)
+	{
+	  print_rtl_with_bb (out, get_insns (), 1024);
+	  fclose (out);
+	}
+      else
+	error_at (UNKNOWN_LOCATION, "unable to open %qs for -froundtrip",
+		  roundtrip_filename);
+    }
+
+/*  If -fsingle-pass=PASS_NAME was provided, locate and run PASS_NAME
+    on cfun, as created above.  */
+  if (single_pass_name)
+    run_one_pass_by_name (single_pass_name);
+}
+
+/* Implementation of LANG_HOOKS_TYPE_FOR_SIZE, taken from Go frontend.  */
+
+static tree
+rtl_langhook_type_for_size (unsigned int bits, int unsignedp)
+{
+  tree type;
+  if (unsignedp)
+    {
+      if (bits == INT_TYPE_SIZE)
+        type = unsigned_type_node;
+      else if (bits == CHAR_TYPE_SIZE)
+        type = unsigned_char_type_node;
+      else if (bits == SHORT_TYPE_SIZE)
+        type = short_unsigned_type_node;
+      else if (bits == LONG_TYPE_SIZE)
+        type = long_unsigned_type_node;
+      else if (bits == LONG_LONG_TYPE_SIZE)
+        type = long_long_unsigned_type_node;
+      else
+        type = make_unsigned_type(bits);
+    }
+  else
+    {
+      if (bits == INT_TYPE_SIZE)
+        type = integer_type_node;
+      else if (bits == CHAR_TYPE_SIZE)
+        type = signed_char_type_node;
+      else if (bits == SHORT_TYPE_SIZE)
+        type = short_integer_type_node;
+      else if (bits == LONG_TYPE_SIZE)
+        type = long_integer_type_node;
+      else if (bits == LONG_LONG_TYPE_SIZE)
+        type = long_long_integer_type_node;
+      else
+        type = make_signed_type(bits);
+    }
+  return type;
+}
+
+/* Implementation of LANG_HOOKS_TYPE_FOR_MODE, taken from Go frontend.  */
+
+static tree
+rtl_langhook_type_for_mode (machine_mode mode, int unsignedp)
+{
+  tree type;
+  /* Go has no vector types.  Build them here.  FIXME: It does not
+     make sense for the middle-end to ask the frontend for a type
+     which the frontend does not support.  However, at least for now
+     it is required.  See PR 46805.  */
+  if (VECTOR_MODE_P (mode))
+    {
+      tree inner;
+
+      inner = rtl_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
+      if (inner != NULL_TREE)
+	return build_vector_type_for_mode (inner, mode);
+      return NULL_TREE;
+    }
+
+  // FIXME: This static_cast should be in machmode.h.
+  enum mode_class mc = static_cast<enum mode_class>(GET_MODE_CLASS(mode));
+  if (mc == MODE_INT)
+    return rtl_langhook_type_for_size(GET_MODE_BITSIZE(mode), unsignedp);
+  else if (mc == MODE_FLOAT)
+    {
+      switch (GET_MODE_BITSIZE (mode))
+	{
+	case 32:
+	  return float_type_node;
+	case 64:
+	  return double_type_node;
+	default:
+	  // We have to check for long double in order to support
+	  // i386 excess precision.
+	  if (mode == TYPE_MODE(long_double_type_node))
+	    return long_double_type_node;
+	}
+    }
+  else if (mc == MODE_COMPLEX_FLOAT)
+    {
+      switch (GET_MODE_BITSIZE (mode))
+	{
+	case 64:
+	  return complex_float_type_node;
+	case 128:
+	  return complex_double_type_node;
+	default:
+	  // We have to check for long double in order to support
+	  // i386 excess precision.
+	  if (mode == TYPE_MODE(complex_long_double_type_node))
+	    return complex_long_double_type_node;
+	}
+    }
+
+#if HOST_BITS_PER_WIDE_INT >= 64
+  /* The middle-end and some backends rely on TImode being supported
+     for 64-bit HWI.  */
+  if (mode == TImode)
+    {
+      type = build_nonstandard_integer_type (GET_MODE_BITSIZE (TImode),
+					     unsignedp);
+      if (type && TYPE_MODE (type) == TImode)
+	return type;
+    }
+#endif
+  return NULL_TREE;
+}
+
+/* Implementation of LANG_HOOKS_BUILTIN_FUNCTION.  */
+
+static tree
+rtl_langhook_builtin_function (tree decl)
+{
+  return decl;
+}
+
+/* Implementation of LANG_HOOKS_GLOBAL_BINDINGS_P.
+   Return true if we are in the global binding level.  */
+
+static bool
+rtl_langhook_global_bindings_p (void)
+{
+  return current_function_decl == NULL_TREE;
+}
+
+/* Implementation of LANG_HOOKS_PUSHDECL.  */
+
+static tree
+rtl_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
+/* Implementation of LANG_HOOKS_GETDECLS.  */
+
+static tree
+rtl_langhook_getdecls (void)
+{
+  return NULL;
+}
+
+/* Functions called directly by the generic backend.  */
+
+/* Implementation of "convert" taken from the Go frontend.  */
+
+tree
+convert (tree type, tree expr)
+{
+  if (type == error_mark_node
+      || expr == error_mark_node
+      || TREE_TYPE (expr) == error_mark_node)
+    return error_mark_node;
+
+  if (type == TREE_TYPE (expr))
+    return expr;
+
+  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
+    return fold_convert (type, expr);
+
+  switch (TREE_CODE (type))
+    {
+    case VOID_TYPE:
+    case BOOLEAN_TYPE:
+      return fold_convert (type, expr);
+    case INTEGER_TYPE:
+      return fold (convert_to_integer (type, expr));
+    case POINTER_TYPE:
+      return fold (convert_to_pointer (type, expr));
+    case REAL_TYPE:
+      return fold (convert_to_real (type, expr));
+    case COMPLEX_TYPE:
+      return fold (convert_to_complex (type, expr));
+    default:
+      break;
+    }
+
+  gcc_unreachable ();
+}
+
+#undef LANG_HOOKS_NAME
+#undef LANG_HOOKS_INIT
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#undef LANG_HOOKS_HANDLE_OPTION
+#undef LANG_HOOKS_PARSE_FILE
+#undef LANG_HOOKS_TYPE_FOR_MODE
+#undef LANG_HOOKS_TYPE_FOR_SIZE
+#undef LANG_HOOKS_BUILTIN_FUNCTION
+#undef LANG_HOOKS_GLOBAL_BINDINGS_P
+#undef LANG_HOOKS_PUSHDECL
+#undef LANG_HOOKS_GETDECLS
+
+#define LANG_HOOKS_NAME			"GCC RTL frontend"
+#define LANG_HOOKS_INIT			rtl_langhook_init
+#define LANG_HOOKS_OPTION_LANG_MASK	rtl_langhook_option_lang_mask
+#define LANG_HOOKS_HANDLE_OPTION	rtl_langhook_handle_option
+#define LANG_HOOKS_PARSE_FILE		rtl_langhook_parse_file
+#define LANG_HOOKS_TYPE_FOR_MODE	rtl_langhook_type_for_mode
+#define LANG_HOOKS_TYPE_FOR_SIZE	rtl_langhook_type_for_size
+#define LANG_HOOKS_BUILTIN_FUNCTION	rtl_langhook_builtin_function
+#define LANG_HOOKS_GLOBAL_BINDINGS_P	rtl_langhook_global_bindings_p
+#define LANG_HOOKS_PUSHDECL		rtl_langhook_pushdecl
+#define LANG_HOOKS_GETDECLS		rtl_langhook_getdecls
+
+struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+
+#include "gt-rtl-rtl-frontend.h"
+#include "gtype-rtl.h"
diff --git a/gcc/testsuite/lib/rtl-dg.exp b/gcc/testsuite/lib/rtl-dg.exp
new file mode 100644
index 0000000..8aa5943
--- /dev/null
+++ b/gcc/testsuite/lib/rtl-dg.exp
@@ -0,0 +1,64 @@
+#   Copyright (C) 1997, 1999, 2000, 2003, 2007 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program 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/>.
+
+# Define rtl callbacks for dg.exp.
+
+# Load support procs.
+load_lib gcc-defs.exp
+
+proc rtl_target_compile { source dest type options } {
+    set result [target_compile $source $dest $type $options]
+    return $result
+}
+
+load_lib gcc-dg.exp
+
+proc rtl-dg-test { prog do_what extra_tool_flags } {
+    verbose "rtl-dg-test (rtl-dg.exp):" 3
+    verbose "  prog: $prog" 3
+    verbose "  do_what: $do_what" 3
+    verbose "  extra_tool_flags: $extra_tool_flags" 3
+
+    return [gcc-dg-test-1 rtl_target_compile $prog $do_what $extra_tool_flags]
+}
+
+
+proc rtl-dg-prune { system text } {
+    return [gcc-dg-prune $system $text]
+}
+
+# Modified dg-runtest that runs tests in both C++98 and C++11 modes
+# unless they specifically specify one or the other.
+proc rtl-dg-runtest { testcases default-extra-flags } {
+    global runtests
+
+    foreach test $testcases {
+	# look if this is dg-do-run test, in which case
+	# we cycle through the option list, otherwise we don't
+	if [expr [search_for $test "dg-do run"]] {
+	    set option_list $TORTURE_OPTIONS
+	} else {
+	    set option_list [list { -O } ]
+	}
+
+	set nshort [file tail [file dirname $test]]/[file tail $test]
+
+	foreach flags $option_list {
+	    verbose "Testing $nshort, $flags" 1
+	    dg-test $test $flags ${default-extra-flags}
+	}
+    }
+}
diff --git a/gcc/testsuite/rtl.dg/dfinit.rtl b/gcc/testsuite/rtl.dg/dfinit.rtl
new file mode 100644
index 0000000..cdde054
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/dfinit.rtl
@@ -0,0 +1,90 @@
+/* { dg-options "-fsingle-pass=rtl-dfinit -fdump-rtl-dfinit" } */
+
+/* Lightly-modified dump of test.c.247r.split1.  */
+
+;; Function test_1 (test_1, funcdef_no=0, decl_uid=1758, cgraph_uid=0, symbol_order=0)
+
+(note 1 0 6 (nil) NOTE_INSN_DELETED)
+(note 6 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+(insn 2 6 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
+        (reg:SI 5 di [ i ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 3 2 4 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32])
+        (reg:SI 4 si [ j ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 4 3 5 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+        (reg:SI 1 dx [ k ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(note 5 4 8 2 NOTE_INSN_FUNCTION_BEG)
+(insn 8 5 9 2 (set (reg:SI 89)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(insn 9 8 10 2 (set (reg:CCGC 17 flags)
+        (compare:CCGC (reg:SI 89)
+            (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32]))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(jump_insn 10 9 11 2 (set (pc)
+        (if_then_else (ge (reg:CCGC 17 flags)
+                (const_int 0 [0]))
+            (label_ref 16)
+            (pc))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil)
+ -> 16)
+(note 11 10 12 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
+(insn 12 11 13 3 (set (reg:SI 90)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 13 12 29 3 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (plus:SI (reg:SI 90)
+                    (const_int 4 [0x4])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+            (const_int 4 [0x4]))
+        (nil)))
+(jump_insn 29 13 30 3 (set (pc)
+        (label_ref 20)) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil)
+ -> 20)
+(barrier 30 29 16)
+(code_label 16 30 17 4 2 (nil) [1 uses])
+(note 17 16 18 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
+(insn 18 17 19 4 (set (reg:SI 91)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (nil))
+(insn 19 18 20 4 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (neg:SI (reg:SI 91)))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32]))
+        (nil)))
+(code_label 20 19 21 5 3 (nil) [1 uses])
+(note 21 20 22 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
+(insn 22 21 26 5 (set (reg:SI 88 [ <retval> ])
+        (reg:SI 87 [ _1 ])) -1
+     (nil))
+(insn 26 22 27 5 (set (reg/i:SI 0 ax)
+        (reg:SI 88 [ <retval> ])) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+(insn 27 26 0 5 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+
+
+/* Verify that the dataflow information matches what cc1 would have
+   generated.  In particular, in earlier versions of the RTL
+   frontend, the exit block use of reg 0 (ax) wasn't picked up
+   on, due to not setting up crtl->return_rtx based on
+   DECL_RESULT (fndecl).  */
+/* { dg-final { scan-rtl-dump ";;  exit block uses.*0 .ax. 6 .bp. 7 .sp. 20 .frame." "dfinit" } } */
+/* { dg-final { scan-rtl-dump ";;  regs ever live.*0 .ax. 1 .dx. 4 .si. 5 .di. 17 .flags." "dfinit" } } */
diff --git a/gcc/testsuite/rtl.dg/final.rtl b/gcc/testsuite/rtl.dg/final.rtl
new file mode 100644
index 0000000..0dc1a85
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/final.rtl
@@ -0,0 +1,51 @@
+/* { dg-options "-fsingle-pass=rtl-final -fdump-rtl-final" } */
+
+/* Lightly-modified dump of test.c.289r.dwarf2. */
+
+;; Function test_1 (test_1, funcdef_no=0, decl_uid=1758, cgraph_uid=0, symbol_order=0)
+
+(note 1 0 6 (nil) NOTE_INSN_DELETED)
+(note 6 1 32 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+(note 32 6 5 2 NOTE_INSN_PROLOGUE_END)
+(note 5 32 31 2 NOTE_INSN_FUNCTION_BEG)
+(insn:TI 31 5 27 2 (set (reg:SI 0 ax [93])
+        (plus:SI (reg/v:SI 1 dx [orig:90 k ] [90])
+            (const_int 4 [0x4]))) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 27 31 28 2 (parallel [
+            (set (reg:SI 1 dx [92])
+                (neg:SI (reg/v:SI 1 dx [orig:90 k ] [90])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (expr_list:REG_UNUSED (reg:CC 17 flags)
+        (nil)))
+(insn 28 27 29 2 (set (reg:CCGC 17 flags)
+        (compare:CCGC (reg/v:SI 5 di [orig:88 i ] [88])
+            (reg/v:SI 4 si [orig:89 j ] [89]))) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (expr_list:REG_DEAD (reg/v:SI 5 di [orig:88 i ] [88])
+        (expr_list:REG_DEAD (reg/v:SI 4 si [orig:89 j ] [89])
+            (nil))))
+(insn:TI 29 28 23 2 (set (reg:SI 0 ax [orig:87 <retval> ] [87])
+        (if_then_else:SI (ge (reg:CCGC 17 flags)
+                (const_int 0 [0]))
+            (reg:SI 1 dx [92])
+            (reg:SI 0 ax [93]))) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (expr_list:REG_DEAD (reg:CCGC 17 flags)
+        (expr_list:REG_DEAD (reg:SI 1 dx [92])
+            (nil))))
+(insn 23 29 34 2 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+(jump_insn:TI 34 23 33 2 (simple_return) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil)
+ -> simple_return)
+(barrier 33 34 30)
+(note 30 33 0 (nil) NOTE_INSN_DELETED)
+
+/* Verify that asm was emitted.  */
+/* { dg-final { scan-assembler "test_1:" } } */
+/* { dg-final { scan-assembler ".cfi_startproc" } } */
+/* { dg-final { scan-assembler ".cfi_endproc" } } */
+
+/* Verify that the "simple_return" was recognized.
+   FIXME: this assumes i386.md.  */
+/* { dg-final { scan-assembler "ret" } } */
diff --git a/gcc/testsuite/rtl.dg/good-include.rtl b/gcc/testsuite/rtl.dg/good-include.rtl
new file mode 100644
index 0000000..24be829
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/good-include.rtl
@@ -0,0 +1,6 @@
+/* Verify that we can include fragments from another dump.
+   We give the included file a .md suffix to avoid it being
+   run by rtl.exp.  */
+
+(include "good-includee.md")
+/* TODO: verify that we have the instruction from the above file.  */
diff --git a/gcc/testsuite/rtl.dg/good-includee.md b/gcc/testsuite/rtl.dg/good-includee.md
new file mode 100644
index 0000000..e63997f
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/good-includee.md
@@ -0,0 +1 @@
+(note 1 0 0 (nil) NOTE_INSN_DELETED)
diff --git a/gcc/testsuite/rtl.dg/into-cfglayout.rtl b/gcc/testsuite/rtl.dg/into-cfglayout.rtl
new file mode 100644
index 0000000..87c3c67
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/into-cfglayout.rtl
@@ -0,0 +1,85 @@
+/* { dg-options "-fsingle-pass=rtl-into_cfglayout -fdump-rtl-into_cfglayout" } */
+(note 1 0 6 (nil) NOTE_INSN_DELETED)
+(note 6 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+(insn 2 6 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
+        (reg:SI 5 di [ i ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 3 2 4 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32])
+        (reg:SI 4 si [ j ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 4 3 5 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+        (reg:SI 1 dx [ k ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(note 5 4 8 2 NOTE_INSN_FUNCTION_BEG)
+(insn 8 5 9 2 (set (reg:SI 89)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(insn 9 8 10 2 (set (reg:CCGC 17 flags)
+        (compare:CCGC (reg:SI 89)
+            (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32]))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(jump_insn 10 9 11 2 (set (pc)
+        (if_then_else (ge (reg:CCGC 17 flags)
+                (const_int 0 [0]))
+            (label_ref 16)
+            (pc))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil)
+ -> 16)
+(note 11 10 12 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
+(insn 12 11 13 4 (set (reg:SI 90)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 13 12 14 4 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (plus:SI (reg:SI 90)
+                    (const_int 4 [0x4])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+            (const_int 4 [0x4]))
+        (nil)))
+(jump_insn 14 13 15 4 (set (pc)
+        (label_ref 20)) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil)
+ -> 20)
+(barrier 15 14 16)
+(code_label 16 15 17 5 2 (nil) [1 uses])
+(note 17 16 18 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
+(insn 18 17 19 5 (set (reg:SI 91)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (nil))
+(insn 19 18 20 5 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (neg:SI (reg:SI 91)))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32]))
+        (nil)))
+(code_label 20 19 21 6 3 (nil) [1 uses])
+(note 21 20 22 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
+(insn 22 21 26 6 (set (reg:SI 88 [ <retval> ])
+        (reg:SI 87 [ _1 ])) -1
+     (nil))
+(insn 26 22 27 6 (set (reg/i:SI 0 ax)
+        (reg:SI 88 [ <retval> ])) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+(insn 27 26 0 6 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+
+/* The conversion to cfglayout should eliminate unconditional jump
+   instructions...  */
+/* { dg-final { scan-rtl-dump "Removing jump 14." "into_cfglayout" } }  */
+/* { dg-final { scan-rtl-dump-not "jump_insn 14" "into_cfglayout" } }  */
+/* { dg-final { scan-rtl-dump-not "barrier 15" "into_cfglayout" } }  */
+
+/* ...but conditional jumps should be preserved.  */
+/* { dg-final { scan-rtl-dump "jump_insn 10" "into_cfglayout" } }  */
diff --git a/gcc/testsuite/rtl.dg/ira.rtl b/gcc/testsuite/rtl.dg/ira.rtl
new file mode 100644
index 0000000..6f2e438
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/ira.rtl
@@ -0,0 +1,84 @@
+/* { dg-options "-fsingle-pass=rtl-ira -fdump-rtl-ira" } */
+
+/* Lightly-modified dump of test.c.251r.asmcons.  */
+
+;; Function test_1 (test_1, funcdef_no=0, decl_uid=1758, cgraph_uid=0, symbol_order=0)
+
+(note 1 0 6 (nil) NOTE_INSN_DELETED)
+(note 6 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+(insn 2 6 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
+        (reg:SI 5 di [ i ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 3 2 4 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32])
+        (reg:SI 4 si [ j ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 4 3 5 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+        (reg:SI 1 dx [ k ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(note 5 4 8 2 NOTE_INSN_FUNCTION_BEG)
+(insn 8 5 9 2 (set (reg:SI 89)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(insn 9 8 10 2 (set (reg:CCGC 17 flags)
+        (compare:CCGC (reg:SI 89)
+            (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32]))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(jump_insn 10 9 11 2 (set (pc)
+        (if_then_else (ge (reg:CCGC 17 flags)
+                (const_int 0 [0]))
+            (label_ref 16)
+            (pc))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil)
+ -> 16)
+(note 11 10 12 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
+(insn 12 11 13 3 (set (reg:SI 90)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 13 12 29 3 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (plus:SI (reg:SI 90)
+                    (const_int 4 [0x4])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+            (const_int 4 [0x4]))
+        (nil)))
+(jump_insn 29 13 30 3 (set (pc)
+        (label_ref 20)) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil)
+ -> 20)
+(barrier 30 29 16)
+(code_label 16 30 17 4 2 (nil) [1 uses])
+(note 17 16 18 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
+(insn 18 17 19 4 (set (reg:SI 91)
+        (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (nil))
+(insn 19 18 20 4 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (neg:SI (reg:SI 91)))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32]))
+        (nil)))
+(code_label 20 19 21 5 3 (nil) [1 uses])
+(note 21 20 22 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
+(insn 22 21 26 5 (set (reg:SI 88 [ <retval> ])
+        (reg:SI 87 [ _1 ])) -1
+     (nil))
+(insn 26 22 27 5 (set (reg/i:SI 0 ax)
+        (reg:SI 88 [ <retval> ])) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+(insn 27 26 0 5 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+
+/* Verify that IRA was run.  */
+/* { dg-final { scan-rtl-dump "Building IRA IR" "ira" } } */
diff --git a/gcc/testsuite/rtl.dg/missing-include.rtl b/gcc/testsuite/rtl.dg/missing-include.rtl
new file mode 100644
index 0000000..f99f3ef
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/missing-include.rtl
@@ -0,0 +1 @@
+(include "does-not-exist.rtl") /* { dg-error "include file .does-not-exist.rtl. not found" } */
diff --git a/gcc/testsuite/rtl.dg/pro_and_epilogue.rtl b/gcc/testsuite/rtl.dg/pro_and_epilogue.rtl
new file mode 100644
index 0000000..a63f908
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/pro_and_epilogue.rtl
@@ -0,0 +1,38 @@
+/* { dg-options "-fsingle-pass=rtl-pro_and_epilogue -fdump-rtl-pro_and_epilogue" } */
+
+/* Lightly-modified dump of test.c.259r.split2.  */
+
+;; Function test_1 (test_1, funcdef_no=0, decl_uid=1758, cgraph_uid=0, symbol_order=0)
+(note 1 0 6 (nil) NOTE_INSN_DELETED)
+(note 6 1 5 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+(note 5 6 31 2 NOTE_INSN_FUNCTION_BEG)
+(insn 31 5 27 2 (set (reg:SI 0 ax [93])
+        (plus:SI (reg/v:SI 1 dx [orig:90 k ] [90])
+            (const_int 4 [0x4]))) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 27 31 28 2 (parallel [
+            (set (reg:SI 1 dx [92])
+                (neg:SI (reg/v:SI 1 dx [orig:90 k ] [90])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 28 27 29 2 (set (reg:CCGC 17 flags)
+        (compare:CCGC (reg/v:SI 5 di [orig:88 i ] [88])
+            (reg/v:SI 4 si [orig:89 j ] [89]))) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 29 28 23 2 (set (reg:SI 0 ax [orig:87 <retval> ] [87])
+        (if_then_else:SI (ge (reg:CCGC 17 flags)
+                (const_int 0 [0]))
+            (reg:SI 1 dx [92])
+            (reg:SI 0 ax [93]))) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 23 29 30 2 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+(note 30 23 0 (nil) NOTE_INSN_DELETED)
+
+/* Verify that the prologue and epilogue were added.  */
+/* { dg-final { scan-rtl-dump-times "NOTE_INSN_PROLOGUE_END" 1 "pro_and_epilogue" } }  */
+
+/* We expect a jump_insn to "simple_return".  */
+/* { dg-final { scan-rtl-dump-times "simple_return" 2 "pro_and_epilogue" } }  */
+
diff --git a/gcc/testsuite/rtl.dg/roundtrip/code-labels.rtl b/gcc/testsuite/rtl.dg/roundtrip/code-labels.rtl
new file mode 100644
index 0000000..7c7fa4a
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/code-labels.rtl
@@ -0,0 +1,2 @@
+(code_label 1 0 2 6 3 (nil) [0 uses])
+(code_label 2 1 0 6 3 ("some_label_name") [57 uses])
diff --git a/gcc/testsuite/rtl.dg/roundtrip/frame-pointer.rtl b/gcc/testsuite/rtl.dg/roundtrip/frame-pointer.rtl
new file mode 100644
index 0000000..50e9e88
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/frame-pointer.rtl
@@ -0,0 +1,4 @@
+(insn 1 0 0 2 (set (mem/c:SI (plus:DI (reg/f:DI 20 frame)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
+        (reg:SI 5 di [ i ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
diff --git a/gcc/testsuite/rtl.dg/roundtrip/insn-with-mode.rtl b/gcc/testsuite/rtl.dg/roundtrip/insn-with-mode.rtl
new file mode 100644
index 0000000..1dd4c92
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/insn-with-mode.rtl
@@ -0,0 +1,4 @@
+(insn:TI 31 0 0 2 (set (reg:SI 0 ax [93])
+        (plus:SI (reg/v:SI 1 dx [orig:90 k ] [90])
+            (const_int 4 [0x4]))) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
diff --git a/gcc/testsuite/rtl.dg/roundtrip/jump-to-label.rtl b/gcc/testsuite/rtl.dg/roundtrip/jump-to-label.rtl
new file mode 100644
index 0000000..0ecd62a
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/jump-to-label.rtl
@@ -0,0 +1,6 @@
+(jump_insn 1 0 2 4 (set (pc)
+        (label_ref 3)) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil)
+ -> 3)
+(barrier 2 1 3)
+(code_label 3 2 0 5 2 (nil) [1 uses])
diff --git a/gcc/testsuite/rtl.dg/roundtrip/jump-to-return.rtl b/gcc/testsuite/rtl.dg/roundtrip/jump-to-return.rtl
new file mode 100644
index 0000000..d7802da
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/jump-to-return.rtl
@@ -0,0 +1,6 @@
+(jump_insn 1 0 2 4 (set (pc)
+        (label_ref 3)) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil)
+ -> return)
+(barrier 2 1 3)
+(code_label 3 2 0 5 2 (nil) [1 uses])
diff --git a/gcc/testsuite/rtl.dg/roundtrip/jump-to-simple-return.rtl b/gcc/testsuite/rtl.dg/roundtrip/jump-to-simple-return.rtl
new file mode 100644
index 0000000..541dd4b
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/jump-to-simple-return.rtl
@@ -0,0 +1,6 @@
+(jump_insn 1 0 2 4 (set (pc)
+        (label_ref 3)) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil)
+ -> simple_return)
+(barrier 2 1 3)
+(code_label 3 2 0 5 2 (nil) [1 uses])
diff --git a/gcc/testsuite/rtl.dg/roundtrip/note-insn-basic-block.rtl b/gcc/testsuite/rtl.dg/roundtrip/note-insn-basic-block.rtl
new file mode 100644
index 0000000..8e535a1
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/note-insn-basic-block.rtl
@@ -0,0 +1 @@
+(note 1 0 0 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
diff --git a/gcc/testsuite/rtl.dg/roundtrip/note-insn-deleted.rtl b/gcc/testsuite/rtl.dg/roundtrip/note-insn-deleted.rtl
new file mode 100644
index 0000000..e63997f
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/note-insn-deleted.rtl
@@ -0,0 +1 @@
+(note 1 0 0 (nil) NOTE_INSN_DELETED)
diff --git a/gcc/testsuite/rtl.dg/roundtrip/reg-with-orig-regno.rtl b/gcc/testsuite/rtl.dg/roundtrip/reg-with-orig-regno.rtl
new file mode 100644
index 0000000..f75d984
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/reg-with-orig-regno.rtl
@@ -0,0 +1,4 @@
+(insn 31 0 0 2 (set (reg:SI 0 ax [93])
+        (plus:SI (reg/v:SI 1 dx [orig:90 k ] [90])
+            (const_int 4 [0x4]))) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
diff --git a/gcc/testsuite/rtl.dg/roundtrip/roundtrip.exp b/gcc/testsuite/rtl.dg/roundtrip/roundtrip.exp
new file mode 100644
index 0000000..fbc7963
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/roundtrip.exp
@@ -0,0 +1,99 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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/>.
+
+# Verify that all of the .rtl files in this directory
+# "round trip" i.e. that loading and then dumping them leads to
+# identical content.
+
+load_lib rtl-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_RTLFLAGS
+if ![info exists DEFAULT_RTLFLAGS] then {
+    set DEFAULT_RTLFLAGS ""
+    # -fdump-tree-rtl-raw
+}
+
+# Compare INPUT_FILE and OUTPUT_FILE, and issue pass/fail
+# results if they have equal/non-equal content.
+
+proc verify-roundtrip { input_file output_file } {
+    verbose "verify-roundtrip:" 3
+    verbose "  input_file: $input_file" 3
+    verbose "  output_file: $output_file" 3
+    # Use "diff" from DejaGnu's utils.exp
+    set diff_result [diff $input_file $output_file]
+    if { $diff_result == 1 } then {
+	pass "$input_file and $output_file are identical"
+    } else {
+	if { $diff_result == -1 } then {
+	    fail "$input_file and $output_file are non-identical"
+	} else {
+	    fail "problem comparing $input_file with $output_file"
+	}
+    }
+}
+
+# Override the default implementation of rtl-dg-test:
+
+rename rtl-dg-test saved-rtl-dg-test
+
+# Alternate implementation of rtl-dg-test which adds a -froundtrip=
+# argument, and verifies that the output is identical to the input.
+
+proc rtl-dg-test { prog do_what extra_tool_flags } {
+    verbose "rtl-dg-test (roundtrip.exp):" 3
+    verbose "  prog: $prog" 3
+    verbose "  do_what: $do_what" 3
+    verbose "  extra_tool_flags: $extra_tool_flags" 3
+
+    # Generate an output filename by stripping off the path from
+    # $prog, and adding a ".roundtrip.rtl" suffix.
+    set output_file [file tail $prog]
+    set output_file "$output_file.roundtrip.rtl"
+
+    # Use it with -froundtrip=.
+    set options \
+	"$extra_tool_flags -froundtrip=$output_file"
+    verbose "options=$options" 3
+
+    set result [gcc-dg-test-1 rtl_target_compile $prog $do_what $options]
+
+    # Verify that the output file is identical to the input file.
+    verify-roundtrip $prog $output_file
+    remote_file build delete $output_file
+    return $result
+}
+
+
+# Initialize `dg'.
+dg-init
+
+# Gather a list of all tests, with the exception of those in directories
+# that are handled specially.
+set tests [lsort [find $srcdir/$subdir *.rtl]]
+
+verbose "roundtrip.exp tests: $tests" 1
+
+# Main loop.
+dg-runtest $tests "" $DEFAULT_RTLFLAGS
+
+# Restore the default implementation of rtl-dg-test:
+rename rtl-dg-test ""
+rename saved-rtl-dg-test rtl-dg-test
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rtl.dg/roundtrip/test-loop.cleaned.rtl b/gcc/testsuite/rtl.dg/roundtrip/test-loop.cleaned.rtl
new file mode 100644
index 0000000..c2930b9
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/test-loop.cleaned.rtl
@@ -0,0 +1,75 @@
+(note 1 0 6 (nil) NOTE_INSN_DELETED)
+(note 6 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+(insn 2 6 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
+        (reg:SI 5 di [ i ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 3 2 4 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32])
+        (reg:SI 4 si [ j ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 4 3 5 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+        (reg:SI 1 dx [ k ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(note 5 4 8 2 NOTE_INSN_FUNCTION_BEG)
+(insn 8 5 9 2 (set (reg:SI 89)
+        (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(insn 9 8 10 2 (set (reg:CCGC 17 flags)
+        (compare:CCGC (reg:SI 89)
+            (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                    (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32]))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(jump_insn 10 9 11 2 (set (pc)
+        (if_then_else (ge (reg:CCGC 17 flags)
+                (const_int 0 [0]))
+            (label_ref 16)
+            (pc))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil)
+ -> 16)
+(note 11 10 12 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
+(insn 12 11 13 4 (set (reg:SI 90)
+        (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 13 12 14 4 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (plus:SI (reg:SI 90)
+                    (const_int 4 [0x4])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+            (const_int 4 [0x4]))
+        (nil)))
+(jump_insn 14 13 15 4 (set (pc)
+        (label_ref 20)) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil)
+ -> 20)
+(barrier 15 14 16)
+(code_label 16 15 17 5 2 (nil) [1 uses])
+(note 17 16 18 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
+(insn 18 17 19 5 (set (reg:SI 91)
+        (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (nil))
+(insn 19 18 20 5 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (neg:SI (reg:SI 91)))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32]))
+        (nil)))
+(code_label 20 19 21 6 3 (nil) [1 uses])
+(note 21 20 22 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
+(insn 22 21 26 6 (set (reg:SI 88 [ <retval> ])
+        (reg:SI 87 [ _1 ])) -1
+     (nil))
+(insn 26 22 27 6 (set (reg/i:SI 0 ax)
+        (reg:SI 88 [ <retval> ])) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+(insn 27 26 0 6 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
diff --git a/gcc/testsuite/rtl.dg/roundtrip/test-switch-after-expand.rtl b/gcc/testsuite/rtl.dg/roundtrip/test-switch-after-expand.rtl
new file mode 100644
index 0000000..497e671
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/roundtrip/test-switch-after-expand.rtl
@@ -0,0 +1,202 @@
+(note 1 0 7 (nil) NOTE_INSN_DELETED)
+(note 7 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+(insn 2 7 3 2 (set (reg/v:SI 88 [ i ])
+        (reg:SI 5 di [ i ])) ../../src/test-switch.c:2 -1
+     (nil))
+(insn 3 2 4 2 (set (reg/v:SI 89 [ j ])
+        (reg:SI 4 si [ j ])) ../../src/test-switch.c:2 -1
+     (nil))
+(insn 4 3 5 2 (set (reg/v:SI 90 [ k ])
+        (reg:SI 1 dx [ k ])) ../../src/test-switch.c:2 -1
+     (nil))
+(note 5 4 9 2 NOTE_INSN_FUNCTION_BEG)
+(insn 9 5 10 2 (parallel [
+            (set (reg:SI 91)
+                (plus:SI (reg/v:SI 88 [ i ])
+                    (const_int 1 [0x1])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/test-switch.c:3 -1
+     (nil))
+(insn 10 9 11 2 (set (reg:CC 17 flags)
+        (compare:CC (reg:SI 91)
+            (const_int 25 [0x19]))) ../../src/test-switch.c:3 -1
+     (nil))
+(jump_insn 11 10 67 2 (set (pc)
+        (if_then_else (gtu (reg:CC 17 flags)
+                (const_int 0 [0]))
+            (label_ref 52)
+            (pc))) ../../src/test-switch.c:3 -1
+     (int_list:REG_BR_PROB 625 (nil))
+ -> 52)
+(note 67 11 12 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
+(insn 12 67 13 4 (set (reg:DI 92)
+        (zero_extend:DI (reg:SI 91))) ../../src/test-switch.c:3 -1
+     (nil))
+(insn 13 12 14 4 (set (reg/f:DI 93)
+        (label_ref:DI 17)) ../../src/test-switch.c:3 -1
+     (insn_list:REG_LABEL_OPERAND 17 (nil)))
+(insn 14 13 15 4 (set (reg:DI 94)
+        (mem/u/c:DI (plus:DI (ashift:DI (reg:DI 92)
+                    (const_int 3 [0x3]))
+                (reg/f:DI 93)) [0  S8 A8])) ../../src/test-switch.c:3 -1
+     (nil))
+(jump_insn 15 14 16 4 (parallel [
+            (set (pc)
+                (reg:DI 94))
+            (use (label_ref 17))
+        ]) ../../src/test-switch.c:3 -1
+     (nil)
+ -> 17)
+(barrier 16 15 17)
+(code_label 17 16 18 (nil) 4 (nil) [2 uses])
+(jump_table_data 18 17 19 (nil) (addr_vec:DI [
+            (label_ref:DI 66)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 20)
+            (label_ref:DI 35)
+            (label_ref:DI 40)
+            (label_ref:DI 46)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 52)
+            (label_ref:DI 25)
+            (label_ref:DI 30)
+        ]))
+(barrier 19 18 20)
+(code_label 20 19 21 5 5 (nil) [10 uses])
+(note 21 20 22 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
+(insn 22 21 23 5 (parallel [
+            (set (reg:SI 87 [ <retval> ])
+                (ashift:SI (reg/v:SI 88 [ i ])
+                    (const_int 1 [0x1])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/test-switch.c:8 -1
+     (nil))
+(jump_insn 23 22 24 5 (set (pc)
+        (label_ref:DI 59)) ../../src/test-switch.c:8 -1
+     (nil)
+ -> 59)
+(barrier 24 23 25)
+(code_label 25 24 26 6 9 (nil) [1 uses])
+(note 26 25 27 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
+(insn 27 26 28 6 (parallel [
+            (set (reg:SI 87 [ <retval> ])
+                (plus:SI (reg/v:SI 89 [ j ])
+                    (reg/v:SI 90 [ k ])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/test-switch.c:10 -1
+     (nil))
+(jump_insn 28 27 29 6 (set (pc)
+        (label_ref:DI 59)) ../../src/test-switch.c:10 -1
+     (nil)
+ -> 59)
+(barrier 29 28 30)
+(code_label 30 29 31 7 10 (nil) [1 uses])
+(note 31 30 32 7 [bb 7] NOTE_INSN_BASIC_BLOCK)
+(insn 32 31 33 7 (parallel [
+            (set (reg:SI 87 [ <retval> ])
+                (minus:SI (reg/v:SI 89 [ j ])
+                    (reg/v:SI 90 [ k ])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/test-switch.c:12 -1
+     (nil))
+(jump_insn 33 32 34 7 (set (pc)
+        (label_ref:DI 59)) ../../src/test-switch.c:12 -1
+     (nil)
+ -> 59)
+(barrier 34 33 35)
+(code_label 35 34 36 8 6 (nil) [1 uses])
+(note 36 35 37 8 [bb 8] NOTE_INSN_BASIC_BLOCK)
+(insn 37 36 38 8 (parallel [
+            (set (reg:SI 87 [ <retval> ])
+                (mult:SI (reg/v:SI 89 [ j ])
+                    (reg/v:SI 90 [ k ])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/test-switch.c:14 -1
+     (nil))
+(jump_insn 38 37 39 8 (set (pc)
+        (label_ref:DI 59)) ../../src/test-switch.c:14 -1
+     (nil)
+ -> 59)
+(barrier 39 38 40)
+(code_label 40 39 41 9 7 (nil) [1 uses])
+(note 41 40 42 9 [bb 9] NOTE_INSN_BASIC_BLOCK)
+(insn 42 41 43 9 (parallel [
+            (set (reg:SI 95)
+                (div:SI (reg/v:SI 89 [ j ])
+                    (reg/v:SI 90 [ k ])))
+            (set (reg:SI 96)
+                (mod:SI (reg/v:SI 89 [ j ])
+                    (reg/v:SI 90 [ k ])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/test-switch.c:16 -1
+     (nil))
+(insn 43 42 44 9 (set (reg:SI 87 [ <retval> ])
+        (reg:SI 95)) ../../src/test-switch.c:16 -1
+     (nil))
+(jump_insn 44 43 45 9 (set (pc)
+        (label_ref:DI 59)) ../../src/test-switch.c:16 -1
+     (nil)
+ -> 59)
+(barrier 45 44 46)
+(code_label 46 45 47 10 8 (nil) [1 uses])
+(note 47 46 48 10 [bb 10] NOTE_INSN_BASIC_BLOCK)
+(insn 48 47 49 10 (parallel [
+            (set (reg:SI 98)
+                (div:SI (reg/v:SI 89 [ j ])
+                    (reg/v:SI 90 [ k ])))
+            (set (reg:SI 97)
+                (mod:SI (reg/v:SI 89 [ j ])
+                    (reg/v:SI 90 [ k ])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/test-switch.c:18 -1
+     (nil))
+(insn 49 48 50 10 (set (reg:SI 87 [ <retval> ])
+        (reg:SI 97)) ../../src/test-switch.c:18 -1
+     (nil))
+(jump_insn 50 49 51 10 (set (pc)
+        (label_ref:DI 59)) ../../src/test-switch.c:18 -1
+     (nil)
+ -> 59)
+(barrier 51 50 52)
+(code_label 52 51 53 11 2 (nil) [11 uses])
+(note 53 52 54 11 [bb 11] NOTE_INSN_BASIC_BLOCK)
+(insn 54 53 63 11 (parallel [
+            (set (reg:SI 87 [ <retval> ])
+                (plus:SI (reg/v:SI 89 [ j ])
+                    (reg/v:SI 90 [ k ])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/test-switch.c:20 -1
+     (nil))
+(jump_insn 63 54 64 11 (set (pc)
+        (label_ref:DI 59)) ../../src/test-switch.c:20 -1
+     (nil)
+ -> 59)
+(barrier 64 63 66)
+(code_label 66 64 65 12 11 (nil) [1 uses])
+(note 65 66 6 12 [bb 12] NOTE_INSN_BASIC_BLOCK)
+(insn 6 65 59 12 (set (reg:SI 87 [ <retval> ])
+        (const_int 34 [0x22])) ../../src/test-switch.c:6 -1
+     (nil))
+(code_label 59 6 62 14 1 (nil) [7 uses])
+(note 62 59 60 14 [bb 14] NOTE_INSN_BASIC_BLOCK)
+(insn 60 62 61 14 (set (reg/i:SI 0 ax)
+        (reg:SI 87 [ <retval> ])) ../../src/test-switch.c:22 -1
+     (nil))
+(insn 61 60 0 14 (use (reg/i:SI 0 ax)) ../../src/test-switch.c:22 -1
+     (nil))
diff --git a/gcc/testsuite/rtl.dg/rtl.exp b/gcc/testsuite/rtl.dg/rtl.exp
new file mode 100644
index 0000000..4225f78
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/rtl.exp
@@ -0,0 +1,43 @@
+#   Copyright (C) 2016 Free Software Foundation, Inc.
+
+# This program 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 of the License, or
+# (at your option) any later version.
+# 
+# This program 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/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib rtl-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_RTLFLAGS
+if ![info exists DEFAULT_RTLFLAGS] then {
+    set DEFAULT_RTLFLAGS ""
+    # -fdump-tree-rtl-raw
+}
+
+# Initialize `dg'.
+dg-init
+
+# Gather a list of all tests, with the exception of those in directories
+# that are handled specially.
+set tests [lsort [find $srcdir/$subdir *.rtl]]
+set tests [prune $tests $srcdir/$subdir/roundtrip/*]
+
+verbose "rtl.exp tests: $tests" 1
+
+# Main loop.
+dg-runtest $tests "" $DEFAULT_RTLFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/rtl.dg/test.c b/gcc/testsuite/rtl.dg/test.c
new file mode 100644
index 0000000..ebb8aef
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/test.c
@@ -0,0 +1,31 @@
+int test_1 (int i, int j, int k)
+{
+  if (i < j)
+    return k + 4;
+  else
+    return -k;
+}
+
+/* Example showing:
+   - data structure
+   - loop
+   - call to "abort".  */
+
+struct foo
+{
+  int count;
+  float *data;
+};
+
+float test_2 (struct foo *lhs, struct foo *rhs)
+{
+  float result = 0.0f;
+
+  if (lhs->count != rhs->count)
+    __builtin_abort ();
+
+  for (int i = 0; i < lhs->count; i++)
+    result += lhs->data[i] * rhs->data[i];
+
+  return result;
+}
diff --git a/gcc/testsuite/rtl.dg/unknown-insn-uid.rtl b/gcc/testsuite/rtl.dg/unknown-insn-uid.rtl
new file mode 100644
index 0000000..c91bf4a
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/unknown-insn-uid.rtl
@@ -0,0 +1,3 @@
+(note 6 1 0 2 [bb 2] NOTE_INSN_BASIC_BLOCK) ;; { dg-error "insn with UID 1 not found for operand 0 ..PREV_INSN.. of insn 6" }
+
+(note 7 0 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK) ;; { dg-error "insn with UID 3 not found for operand 1 ..NEXT_INSN.. of insn 7" }
diff --git a/gcc/testsuite/rtl.dg/unknown-rtx-code.rtl b/gcc/testsuite/rtl.dg/unknown-rtx-code.rtl
new file mode 100644
index 0000000..7a66767
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/unknown-rtx-code.rtl
@@ -0,0 +1 @@
+(not-a-valid-kind-of-insn 1 0 0) ;; { dg-error "unknown rtx code" }
diff --git a/gcc/testsuite/rtl.dg/vregs.rtl b/gcc/testsuite/rtl.dg/vregs.rtl
new file mode 100644
index 0000000..23e4cc0
--- /dev/null
+++ b/gcc/testsuite/rtl.dg/vregs.rtl
@@ -0,0 +1,80 @@
+/* { dg-options "-fsingle-pass=rtl-vregs -fdump-rtl-vregs" } */
+(note 1 0 6 (nil) NOTE_INSN_DELETED)
+(note 6 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
+(insn 2 6 3 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])
+        (reg:SI 5 di [ i ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 3 2 4 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32])
+        (reg:SI 4 si [ j ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(insn 4 3 5 2 (set (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+        (reg:SI 1 dx [ k ])) ../../src/gcc/testsuite/rtl.dg/test.c:2 -1
+     (nil))
+(note 5 4 8 2 NOTE_INSN_FUNCTION_BEG)
+(insn 8 5 9 2 (set (reg:SI 89)
+        (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -4 [0xfffffffffffffffc])) [1 i+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(insn 9 8 10 2 (set (reg:CCGC 17 flags)
+        (compare:CCGC (reg:SI 89)
+            (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                    (const_int -8 [0xfffffffffffffff8])) [1 j+0 S4 A32]))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil))
+(jump_insn 10 9 11 2 (set (pc)
+        (if_then_else (ge (reg:CCGC 17 flags)
+                (const_int 0 [0]))
+            (label_ref 16)
+            (pc))) ../../src/gcc/testsuite/rtl.dg/test.c:3 -1
+     (nil)
+ -> 16)
+(note 11 10 12 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
+(insn 12 11 13 4 (set (reg:SI 90)
+        (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil))
+(insn 13 12 14 4 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (plus:SI (reg:SI 90)
+                    (const_int 4 [0x4])))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])
+            (const_int 4 [0x4]))
+        (nil)))
+(jump_insn 14 13 15 4 (set (pc)
+        (label_ref 20)) ../../src/gcc/testsuite/rtl.dg/test.c:4 -1
+     (nil)
+ -> 20)
+(barrier 15 14 16)
+(code_label 16 15 17 5 2 (nil) [1 uses])
+(note 17 16 18 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
+(insn 18 17 19 5 (set (reg:SI 91)
+        (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32])) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (nil))
+(insn 19 18 20 5 (parallel [
+            (set (reg:SI 87 [ _1 ])
+                (neg:SI (reg:SI 91)))
+            (clobber (reg:CC 17 flags))
+        ]) ../../src/gcc/testsuite/rtl.dg/test.c:6 -1
+     (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI 82 virtual-stack-vars)
+                    (const_int -12 [0xfffffffffffffff4])) [1 k+0 S4 A32]))
+        (nil)))
+(code_label 20 19 21 6 3 (nil) [1 uses])
+(note 21 20 22 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
+(insn 22 21 26 6 (set (reg:SI 88 [ <retval> ])
+        (reg:SI 87 [ _1 ])) -1
+     (nil))
+(insn 26 22 27 6 (set (reg/i:SI 0 ax)
+        (reg:SI 88 [ <retval> ])) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+(insn 27 26 0 6 (use (reg/i:SI 0 ax)) ../../src/gcc/testsuite/rtl.dg/test.c:7 -1
+     (nil))
+
+/* The 9 instances of "virtual-stack-vars" should now all be "frame".  */
+/* { dg-final { scan-rtl-dump-times "frame" 9 "vregs" } }  */
+/* { dg-final { scan-rtl-dump-not "virtual-stack-vars" "vregs" } }  */
-- 
1.8.5.3

