From fa55708817fe9641046a45a15517c8be79034e8d Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 17 Oct 2016 12:44:04 -0400
Subject: [PATCH 15/20] FIXME: Add "__RTL" to cc1

FIXME: ChangeLog needs updating

Changed in this version:

* Updated comment to c_parser_declaration_or_fndef to show the new syntax
* Use c_parser_next_token_is_keyword.
* Removed a stray "FIXME".
* Removed some debug code.
* Add more comments
* Fixed a typo in the ChangeLog ("__RID" -> "__RTL")

Blurb from original version

This patch implements Richi's idea of having a custom __RTL marker
in C function definitions, to indicate that the body of the function
is to be parsed as RTL, rather than C:

int __RTL test_fn_1 (int i)
{
 (function "times_two"
   (insn-chain
     (note 1 0 4 (nil) NOTE_INSN_DELETED)
     ;; etc
   ) ;; insn-chain
   (crtl
     (return_rtx
       (reg/i:SI 0 ax)
     ) ;; return_rtx
   ) ;; crtl
  ) ;; function
}

This allows for decls and types to be declared in C, and to use
the function decl from the C frontend.

I added support for running a single pass by giving __RTL an optional
parameter (the name of the pass).  For example:

int __RTL ("rtl-dfinit") test_fn_2 (int i)
{
 (function "times_two"
   (insn-chain
     (note 1 0 4 (nil) NOTE_INSN_DELETED)
     ;; etc
   ) ;; insn-chain
   (crtl
     (return_rtx
       (reg/i:SI 0 ax)
     ) ;; return_rtx
   ) ;; crtl
  ) ;; function
}

The top-level "function" directive is rather redundant; perhaps it should
be omitted?  This would give e.g.:

int __RTL ("rtl-dfinit") test_fn_3 (int i)
{
   (insn-chain
     (note 1 0 4 (nil) NOTE_INSN_DELETED)
     ;; etc
   ) ;; insn-chain
   (crtl
     (return_rtx
       (reg/i:SI 0 ax)
     ) ;; return_rtx
   ) ;; crtl
}

(Though maybe we want to keep it as a place to hold top-level metadata)

gcc/c-family/ChangeLog:
	* c-common.c (c_common_reswords): Add "__RTL".
	* c-common.h (enum rid): Add RID_RTL.

gcc/c/ChangeLog:
	* c-parser.c: Include "read-rtl-function.h" and
	"run-one-rtl-pass.h".
	(c_parser_declaration_or_fndef): In the "GNU extensions" part of
	the leading comment, add an alternate production for
	"function-definition", along with new "rtl-body-specifier" and
	"rtl-body-pass-specifier" productions.  Handle "__RTL" by calling
	c_parser_parse_rtl_body.  Convert a timevar_push/pop pair
	to an auto_timevar, to cope with early exit.
	(c_parser_parse_rtl_body): New function.

gcc/ChangeLog:
	* Makefile.in (OBJS): Add run-one-rtl-pass.o.
	* read-md.c (base_rtx_reader::read_char): Support filtering
	the input to a subset of line numbers.
	(base_rtx_reader::base_rtx_reader): Initialize fields
	m_first_line and m_last_line.
	(base_rtx_reader::read_file_fragment): New method.
	* read-md.h (base_rtx_reader::read_file_fragment): New decl.
	(base_rtx_reader::m_first_line): New field.
	(base_rtx_reader::m_last_line): New field.
	* read-rtl-function.c (function_reader::create_function): Only create
	cfun if it doesn't already exist.
	(read_rtl_function_body_from_file_range): New function.
	* read-rtl-function.h (read_rtl_function_body_from_file_range):
	New decl.
	* rtl.c (in_rtl_frontend_p): New global.
	* rtl.h (in_rtl_frontend_p): New global decl.
	* run-one-rtl-pass.c: New file.
	* run-one-rtl-pass.h: New file.
	* toplev.c (compile_file): Bail out after the parse_file
        langhook if within the RTL frontend.

gcc/testsuite/ChangeLog:
	* rtl.dg/rtl.exp: New file.
	* rtl.dg/x86_64/different-structs.c: New file.
	* rtl.dg/x86_64/test-return-const.c.after-expand.c: New file.
	* rtl.dg/x86_64/test-return-const.c.before-fwprop.c: New file.
	* rtl.dg/x86_64/test-rtl.c: New file.
	* rtl.dg/x86_64/times-two.c.after-expand.c: New file.
	* rtl.dg/x86_64/times-two.c.before-df.c: New file.

FIXME: WIP on consolidating test cases
---
 gcc/Makefile.in                                    |   1 +
 gcc/c-family/c-common.c                            |   1 +
 gcc/c-family/c-common.h                            |   3 +
 gcc/c/c-parser.c                                   | 113 +++++++++++++++-
 gcc/read-md.c                                      |  34 ++++-
 gcc/read-md.h                                      |   7 +
 gcc/read-rtl-function.c                            |  78 ++++++++---
 gcc/read-rtl-function.h                            |   3 +
 gcc/rtl.c                                          |   2 +
 gcc/rtl.h                                          |   1 +
 gcc/run-one-rtl-pass.c                             | 120 +++++++++++++++++
 gcc/run-one-rtl-pass.h                             |  25 ++++
 gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c        |  35 +++++
 gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c         |  47 +++++++
 gcc/testsuite/gcc.dg/rtl/rtl.exp                   |  41 ++++++
 gcc/testsuite/gcc.dg/rtl/test.c                    |  31 +++++
 gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c        |   8 ++
 gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c           | 116 ++++++++++++++++
 .../gcc.dg/rtl/x86_64/different-structs.c          |  95 +++++++++++++
 gcc/testsuite/gcc.dg/rtl/x86_64/final.c            | 150 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c   | 117 ++++++++++++++++
 gcc/testsuite/gcc.dg/rtl/x86_64/ira.c              | 111 +++++++++++++++
 gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c | 110 +++++++++++++++
 .../rtl/x86_64/test-return-const.c.after-expand.c  |  34 +++++
 .../rtl/x86_64/test-return-const.c.before-fwprop.c |  36 +++++
 gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c         | 115 ++++++++++++++++
 .../gcc.dg/rtl/x86_64/times-two.c.after-expand.c   |  49 +++++++
 .../gcc.dg/rtl/x86_64/times-two.c.before-df.c      |  60 +++++++++
 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c            | 112 +++++++++++++++
 gcc/toplev.c                                       |   7 +
 30 files changed, 1642 insertions(+), 20 deletions(-)
 create mode 100644 gcc/run-one-rtl-pass.c
 create mode 100644 gcc/run-one-rtl-pass.h
 create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/rtl.exp
 create mode 100644 gcc/testsuite/gcc.dg/rtl/test.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/final.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/ira.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c
 create mode 100644 gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 83c1f29..8f54b0b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1427,6 +1427,7 @@ OBJS = \
 	rtlhash.o \
 	rtlanal.o \
 	rtlhooks.o \
+	run-one-rtl-pass.o \
 	sbitmap.o \
 	sched-deps.o \
 	sched-ebb.o \
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index c4a0ce8..2441400 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -527,6 +527,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY },
   { "__volatile",	RID_VOLATILE,	0 },
   { "__volatile__",	RID_VOLATILE,	0 },
+  { "__RTL",		RID_RTL,	0 },
   { "alignas",		RID_ALIGNAS,	D_CXXONLY | D_CXX11 | D_CXXWARN },
   { "alignof",		RID_ALIGNOF,	D_CXXONLY | D_CXX11 | D_CXXWARN },
   { "asm",		RID_ASM,	D_ASM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 8ef1d74..cebc282 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -118,6 +118,9 @@ enum rid
 
   RID_FRACT, RID_ACCUM, RID_AUTO_TYPE, RID_BUILTIN_CALL_WITH_STATIC_CHAIN,
 
+  /* "__RTL", for the RTL-parsing extension to the C frontend.  */
+  RID_RTL,
+
   /* C11 */
   RID_ALIGNAS, RID_GENERIC,
 
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 6bc42da..693d1bd 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -59,6 +59,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-expr.h"
 #include "context.h"
 #include "gcc-rich-location.h"
+#include "read-rtl-function.h"
+#include "run-one-rtl-pass.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -1421,6 +1423,9 @@ static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
 static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
 static void c_parser_cilk_grainsize (c_parser *, bool *);
 
+static void c_parser_parse_rtl_body (c_parser *parser,
+				     const char *single_pass_name);
+
 /* Parse a translation unit (C90 6.7, C99 6.9).
 
    translation-unit:
@@ -1624,6 +1629,16 @@ static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
      declaration-specifiers declarator declaration-list[opt]
        compound-statement
 
+   function-definition:
+     declaration-specifiers rtl-body-specifier declarator declaration-list[opt]
+       compound-statement
+
+   rtl-body-specifier:
+     __RTL rtl-body-pass-specifier[opt]
+
+   rtl-body-pass-specifier:
+     ( string )
+
    attribute ;
 
    Objective-C:
@@ -1668,6 +1683,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
   tree all_prefix_attrs;
   bool diagnosed_no_specs = false;
   location_t here = c_parser_peek_token (parser)->location;
+  bool rtl_body_p = false;
+  const char *single_pass_name = NULL;
 
   if (static_assert_ok
       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
@@ -1752,6 +1769,33 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
       c_parser_skip_to_end_of_block_or_statement (parser);
       return;
     }
+
+  /* Handle GNU extension rtl-body-specifier by detecting "__RTL".  */
+  if (c_parser_next_token_is_keyword (parser, RID_RTL))
+    {
+      rtl_body_p = true;
+      c_parser_consume_token (parser);
+
+      /* Handle the optional rtl-body-pass-specifier: parens wrapping
+	 a string, giving a pass name.  */
+      if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+	{
+	  c_parser_consume_token (parser);
+	  c_token *tok = c_parser_peek_token (parser);
+	  if (tok->type != CPP_STRING)
+	    {
+	      c_parser_error (parser, "expected string");
+	      c_parser_skip_to_end_of_block_or_statement (parser);
+	      return;
+	    }
+	  gcc_assert (TREE_CODE (tok->value) == STRING_CST);
+	  single_pass_name = TREE_STRING_POINTER (tok->value);
+	  c_parser_consume_token (parser);
+
+	  c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+	}
+    }
+
   finish_declspecs (specs);
   bool auto_type_p = specs->typespec_word == cts_auto_type;
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
@@ -2146,7 +2190,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
         tv = TV_PARSE_INLINE;
       else
         tv = TV_PARSE_FUNC;
-      timevar_push (tv);
+      auto_timevar at (g_timer, tv);
 
       /* Parse old-style parameter declarations.  ??? Attributes are
 	 not allowed to start declaration specifiers here because of a
@@ -2173,6 +2217,15 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
 	c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
 	= c_parser_peek_token (parser)->location;
+
+      /* If we had an rtl-body-specifier, use the RTL parser now,
+	 consuming the function body.  */
+      if (rtl_body_p)
+	{
+	  c_parser_parse_rtl_body (parser, single_pass_name);
+	  return;
+	}
+
       fnbody = c_parser_compound_statement (parser);
       if (flag_cilkplus && contains_array_notation_expr (fnbody))
 	fnbody = expand_array_notation_exprs (fnbody);
@@ -2195,7 +2248,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
 	  finish_function ();
 	}
 
-      timevar_pop (tv);
       break;
     }
 }
@@ -18313,4 +18365,61 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
   return value_tree;
 }
 
+/* Parse the body of a function declaration marked with "__RTL".
+
+   The RTL parser works on the level of characters read from a
+   FILE *, whereas c_parser works at the level of tokens.
+   Square this circle by consuming all of the tokens up to and
+   including the closing brace, recording the start/end of the RTL
+   fragment, and reopening the file and re-reading the relevant
+   lines within the RTL parser.
+
+   This requires the opening and closing braces of the C function
+   to be on separate lines from the RTL they wrap.  */
+
+void
+c_parser_parse_rtl_body (c_parser *parser, const char *single_pass_name)
+{
+  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
+    return;
+
+  location_t start_loc = c_parser_peek_token (parser)->location;
+
+  /* Consume all tokens, up to the closing brace, handling
+     matching pairs of braces in the rtl dump.  */
+  int num_open_braces = 1;
+  while (1)
+    {
+      switch (c_parser_peek_token (parser)->type)
+	{
+	case CPP_OPEN_BRACE:
+	  num_open_braces++;
+	  break;
+	case CPP_CLOSE_BRACE:
+	  if (--num_open_braces == 0)
+	    goto found_closing_brace;
+	  break;
+	default:
+	  break;
+	}
+      c_parser_consume_token (parser);
+    }
+
+ found_closing_brace:
+  /* At the closing brace; record its location.  */
+  location_t end_loc = c_parser_peek_token (parser)->location;
+
+  /* Consume the closing brace.  */
+  c_parser_consume_token (parser);
+
+  /* Invoke the RTL parser.  */
+  if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
+    return;
+
+ /*  If -fsingle-pass=PASS_NAME was provided, locate and run PASS_NAME
+      on cfun, as created above.  */
+  if (single_pass_name)
+    run_one_rtl_pass_by_name (single_pass_name);
+}
+
 #include "gt-c-c-parser.h"
diff --git a/gcc/read-md.c b/gcc/read-md.c
index e869e53..46e08fe 100644
--- a/gcc/read-md.c
+++ b/gcc/read-md.c
@@ -399,6 +399,16 @@ base_rtx_reader::read_char (void)
   else
     m_read_md_colno++;
 
+  /* If we're filtering lines, treat everything outside the
+     range of interest as a space.  */
+  if (m_first_line && m_last_line)
+    {
+      if (m_read_md_lineno < m_first_line)
+	return ' ';
+      if (m_read_md_lineno > m_last_line)
+	return EOF;
+    }
+
   return ch;
 }
 
@@ -981,7 +991,9 @@ base_rtx_reader::base_rtx_reader (bool compact)
   m_read_md_lineno (0),
   m_read_md_colno (0),
   m_first_dir_md_include (NULL),
-  m_last_dir_md_include_ptr (&m_first_dir_md_include)
+  m_last_dir_md_include_ptr (&m_first_dir_md_include),
+  m_first_line (0),
+  m_last_line (0)
 {
   /* Set the global singleton pointer.  */
   base_rtx_reader_ptr = this;
@@ -1284,6 +1296,26 @@ base_rtx_reader::read_md_files (int argc, const char **argv,
   return !have_error;
 }
 
+/* Read FILENAME, filtering to just the given lines.  */
+
+bool
+base_rtx_reader::read_file_fragment (const char *filename,
+				     int first_line,
+				     int last_line)
+{
+  m_read_md_filename = filename;
+  m_read_md_file = fopen (m_read_md_filename, "r");
+  if (m_read_md_file == 0)
+    {
+      perror (m_read_md_filename);
+      return false;
+    }
+  m_first_line = first_line;
+  m_last_line = last_line;
+  handle_toplevel_file ();
+  return !have_error;
+}
+
 /* class noop_reader : public base_rtx_reader */
 
 /* A dummy implementation which skips unknown directives.  */
diff --git a/gcc/read-md.h b/gcc/read-md.h
index dac76d3..2ad3bcd 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -98,6 +98,9 @@ class base_rtx_reader
   virtual ~base_rtx_reader ();
 
   bool read_md_files (int, const char **, bool (*) (const char *));
+  bool read_file_fragment (const char *filename,
+			   int first_line,
+			   int last_line);
 
   /* A hook that handles a single .md-file directive, up to but not
      including the closing ')'.  It takes two arguments: the file position
@@ -232,6 +235,10 @@ class base_rtx_reader
 
   /* A table of enum_type structures, hashed by name.  */
   htab_t m_enum_types;
+
+  /* If non-zero, filter the input to just this subset of lines.  */
+  int m_first_line;
+  int m_last_line;
 };
 
 /* Global singleton; constrast with rtx_reader_ptr below.  */
diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index c315907..3e7adb7 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -576,23 +576,31 @@ function_reader::create_function ()
   else
     rtl_register_cfg_hooks ();
 
-  /* Create cfun.  */
-  tree fn_name = get_identifier (m_name ? m_name : "test_1");
-  tree int_type = integer_type_node;
-  tree return_type = int_type;
-  tree arg_types[3] = {int_type, int_type, int_type};
-  tree fn_type = build_function_type_array (return_type, 3, arg_types);
-  tree fndecl = build_decl_stat (UNKNOWN_LOCATION, FUNCTION_DECL, fn_name,
-				 fn_type);
-  tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
-			     return_type);
-  DECL_ARTIFICIAL (resdecl) = 1;
-  DECL_IGNORED_P (resdecl) = 1;
-  DECL_RESULT (fndecl) = resdecl;
-  allocate_struct_function (fndecl, false);
-  /* This sets cfun.  */
-
-  current_function_decl = fndecl;
+  /* When run from selftests or "rtl1", cfun is NULL.
+     When run from "cc1" for a C function tagged with __RTL, cfun is the
+     tagged function.  */
+  if (!cfun)
+    {
+      tree fn_name = get_identifier (m_name ? m_name : "test_1");
+      tree int_type = integer_type_node;
+      tree return_type = int_type;
+      tree arg_types[3] = {int_type, int_type, int_type};
+      tree fn_type = build_function_type_array (return_type, 3, arg_types);
+      tree fndecl = build_decl_stat (UNKNOWN_LOCATION, FUNCTION_DECL, fn_name,
+				     fn_type);
+      tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
+				 return_type);
+      DECL_ARTIFICIAL (resdecl) = 1;
+      DECL_IGNORED_P (resdecl) = 1;
+      DECL_RESULT (fndecl) = resdecl;
+      allocate_struct_function (fndecl, false);
+      /* This sets cfun.  */
+      current_function_decl = fndecl;
+    }
+
+  gcc_assert (cfun);
+  gcc_assert (current_function_decl);
+  tree fndecl = current_function_decl;
 
   cfun->curr_properties = (PROP_cfg | PROP_rtl);
 
@@ -1657,6 +1665,42 @@ read_rtl_function_body (int argc, const char **argv,
   return true;
 }
 
+/* Run the RTL dump parser on the range of lines between START_LOC and
+   END_LOC (including those lines).  */
+
+bool
+read_rtl_function_body_from_file_range (location_t start_loc,
+					location_t end_loc)
+{
+  expanded_location exploc_start = expand_location (start_loc);
+  expanded_location exploc_end = expand_location (end_loc);
+
+  if (exploc_start.file != exploc_end.file)
+    {
+      error_at (end_loc, "start/end of RTL fragment are in different files");
+      return false;
+    }
+  if (exploc_start.line >= exploc_end.line)
+    {
+      error_at (end_loc,
+		"start of RTL fragment must be on an earlier line than end");
+      return false;
+    }
+
+  in_rtl_frontend_p = true;
+
+  initialize_rtl ();
+  init_emit ();
+  init_varasm_status ();
+
+  function_reader reader (NULL);
+  if (!reader.read_file_fragment (exploc_start.file, exploc_start.line,
+				  exploc_end.line - 1))
+    return false;
+
+  return true;
+}
+
 #if CHECKING_P
 
 namespace selftest {
diff --git a/gcc/read-rtl-function.h b/gcc/read-rtl-function.h
index 036fcce..d5d12ab 100644
--- a/gcc/read-rtl-function.h
+++ b/gcc/read-rtl-function.h
@@ -33,4 +33,7 @@ extern bool read_rtl_function_body (int argc, const char **argv,
 				    bool (*parse_opt) (const char *),
 				    function_reader_policy *policy);
 
+extern bool read_rtl_function_body_from_file_range (location_t start_loc,
+						    location_t end_loc);
+
 #endif /* GCC_READ_RTL_FUNCTION_H */
diff --git a/gcc/rtl.c b/gcc/rtl.c
index a445cdc..9729c82 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -878,3 +878,5 @@ rtl_check_failed_flag (const char *name, const_rtx r, const char *file,
      name, GET_RTX_NAME (GET_CODE (r)), func, trim_filename (file), line);
 }
 #endif /* ENABLE_RTL_FLAG_CHECKING */
+
+bool in_rtl_frontend_p = false;
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 5541a78..65d917e 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3755,5 +3755,6 @@ struct GTY(()) cgraph_rtl_info {
   unsigned function_used_regs_valid: 1;
 };
 
+extern bool in_rtl_frontend_p;
 
 #endif /* ! GCC_RTL_H */
diff --git a/gcc/run-one-rtl-pass.c b/gcc/run-one-rtl-pass.c
new file mode 100644
index 0000000..ecb7bf0
--- /dev/null
+++ b/gcc/run-one-rtl-pass.c
@@ -0,0 +1,120 @@
+/* run-one-rtl-pass.c - Run just one RTL pass
+   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 "memmodel.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"
+
+/*  Locate and run PASS_NAME on cfun.  */
+
+void
+run_one_rtl_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-cse1")
+      || 0 == strcmp (pass_name, "rtl-fwprop1")
+      || 0 == strcmp (pass_name, "rtl-combine")
+      || 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);
+}
diff --git a/gcc/run-one-rtl-pass.h b/gcc/run-one-rtl-pass.h
new file mode 100644
index 0000000..40d60ba
--- /dev/null
+++ b/gcc/run-one-rtl-pass.h
@@ -0,0 +1,25 @@
+/* run-one-rtl-pass.h - Run just one RTL pass
+   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/>.  */
+
+#ifndef GCC_RUN_ONE_RTL_PASS_H
+#define GCC_RUN_ONE_RTL_PASS_H
+
+extern void run_one_rtl_pass_by_name (const char *pass_name);
+
+#endif /* GCC_RUN_ONE_RTL_PASS_H */
diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c b/gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c
new file mode 100644
index 0000000..457519e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/aarch64/asr_div1.c
@@ -0,0 +1,35 @@
+/* { dg-do compile { target aarch64-*-* } } */
+/* { dg-options "-mtune=cortex-a53 -fdump-rtl-combine" } */
+
+/* Taken from
+     gcc/testsuite/gcc.dg/asr_div1.c -O2 -fdump-rtl-all -mtune=cortex-a53
+   for aarch64, hand editing the prev/next insns to 0 as needed, and
+   editing whitespace to avoid over-long lines.  */
+
+int __RTL("rtl-combine") f1 (int n)
+{
+(function "f1"
+  (insn-chain
+
+(insn 8 0 9 2 (set (reg:DI 78)
+        (lshiftrt:DI (reg:DI 76)
+            (const_int 32 [0x20])))
+        ../../src/gcc/testsuite/gcc.dg/asr_div1.c:14
+        641 {*aarch64_lshr_sisd_or_int_di3}
+     (expr_list:REG_DEAD (reg:DI 76)
+        (nil)))
+(insn 9 8 0 2 (set (reg:SI 79)
+        (ashiftrt:SI (subreg:SI (reg:DI 78) 0)
+            (const_int 3 [0x3])))
+        ../../src/gcc/testsuite/gcc.dg/asr_div1.c:14
+        642 {*aarch64_ashr_sisd_or_int_si3}
+     (expr_list:REG_DEAD (reg:DI 78)
+        (nil)))
+
+  ) ;; insn-chain
+) ;; function
+}
+
+/* Verify that insns 8 and 9 get combined into a shift of 35 (0x23) */
+/* { dg-final { scan-rtl-dump "allowing combination of insns 8 and 9" "combine" } } */
+/* { dg-final { scan-rtl-dump "modifying insn i3     9: r79:SI#0=r76:DI>>0x23" "combine" } } */
diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c b/gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c
new file mode 100644
index 0000000..545e85a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/aarch64/pr71779.c
@@ -0,0 +1,47 @@
+/* { dg-do compile { target aarch64-*-* } } */
+/* { dg-options "-fdump-rtl-cse1" } */
+
+/* Dump taken from comment 2 of PR 71779, of
+   "...the relevant memory access coming out of expand"
+   with basic block IDs added, and prev/next insns set to
+   0 at ends, and 'p' added to pseudo regnos.  */
+
+int __RTL("rtl-cse1") test (int n)
+{
+(function "fragment"
+  (insn-chain
+
+;; MEM[(struct isl_obj *)&obj1] = &isl_obj_map_vtable;
+(insn 1045 0 1046 2 (set (reg:SI 480)
+        (high:SI (symbol_ref:SI ("isl_obj_map_vtable")
+                    [flags 0xc0]
+                    <var_decl 0x7fa0363ea240 isl_obj_map_vtable>)))
+     y.c:12702 -1
+     (nil))
+(insn 1046 1045 1047 2 (set (reg/f:SI 479)
+        (lo_sum:SI (reg:SI 480)
+            (symbol_ref:SI ("isl_obj_map_vtable")
+               [flags 0xc0]
+               <var_decl 0x7fa0363ea240 isl_obj_map_vtable>)))
+     y.c:12702 -1
+     (expr_list:REG_EQUAL (symbol_ref:SI ("isl_obj_map_vtable")
+                             [flags 0xc0]
+                             <var_decl 0x7fa0363ea240 isl_obj_map_vtable>)
+        (nil)))
+(insn 1047 1046 1048 2 (set (reg:DI 481)
+        (subreg:DI (reg/f:SI 479) 0)) y.c:12702 -1
+     (nil))
+(insn 1048 1047 1049 2 (set (zero_extract:DI (reg/v:DI 191 [ obj1D.17368 ])
+            (const_int 32 [0x20])
+            (const_int 0 [0]))
+        (reg:DI 481)) y.c:12702 -1
+     (nil))
+;; Extra insn, to avoid all of the above from being deleted by DCE
+(insn 1049 1048 0 2 (set (mem:DI (reg:DI 191) [1 i+0 S4 A32])
+                         (const_int 1 [0x1])) -1 (nil))
+
+  ) ;; insn-chain
+) ;; function
+}
+
+/* TODO: scan the dump.  */
diff --git a/gcc/testsuite/gcc.dg/rtl/rtl.exp b/gcc/testsuite/gcc.dg/rtl/rtl.exp
new file mode 100644
index 0000000..3c6648b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/rtl.exp
@@ -0,0 +1,41 @@
+#   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 gcc-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.
+set tests [lsort [find $srcdir/$subdir *.c]]
+
+verbose "rtl.exp tests: $tests" 1
+
+# Main loop.
+dg-runtest $tests "" $DEFAULT_RTLFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/rtl/test.c b/gcc/testsuite/gcc.dg/rtl/test.c
new file mode 100644
index 0000000..ebb8aef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/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/gcc.dg/rtl/unknown-rtx-code.c b/gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c
new file mode 100644
index 0000000..dd252f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/unknown-rtx-code.c
@@ -0,0 +1,8 @@
+void __RTL test (void)
+{
+  (function "test"
+    (insn-chain
+      (not-a-valid-kind-of-insn 1 0 0) ;; { dg-error "unknown rtx code" }
+    ) ;; insn-chain
+  ) ;; function
+}
diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c b/gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c
new file mode 100644
index 0000000..51a5e9f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/dfinit.c
@@ -0,0 +1,116 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-dfinit" } */
+
+/* Lightly-modified dump of test.c.257r.split1 for x86_64.  */
+
+int __RTL("rtl-dfinit") test_1 (int i, int j, int k)
+{
+(function "test_1"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -8)) [1 j+0 S4 A32])
+                    (reg:SI si [ j ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])
+                    (reg:SI dx [ k ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %2)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cinsn (set (reg:CCGC flags)
+                    (compare:CCGC (reg:SI %2)
+                        (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -8)) [1 j+0 S4 A32]))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cjump_insn (set (pc)
+                    (if_then_else (ge (reg:CCGC flags)
+                            (const_int 0))
+                        (label_ref 16)
+                        (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (edge-to 3 (flags "FALLTHRU"))
+      (edge-to 4)
+    ) ;; block 2
+    (block 3
+      (edge-from 2 (flags "FALLTHRU"))
+      (cnote [bb 3] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %3)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (plus:SI (reg:SI %3)
+                                (const_int 4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32])
+                        (const_int 4))
+                    (nil)))
+      (cjump_insn (set (pc)
+                    (label_ref 20)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (edge-to 5)
+    ) ;; block 3
+    (cbarrier)
+    (block 4
+      (edge-from 2)
+      (clabel 16 2 (nil))
+      (cnote [bb 4] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %4)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (neg:SI (reg:SI %4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32]))
+                    (nil)))
+      (edge-to 5 (flags "FALLTHRU"))
+    ) ;; block 4
+    (block 5
+      (edge-from 4 (flags "FALLTHRU"))
+      (edge-from 3)
+      (clabel 20 3 (nil))
+      (cnote [bb 5] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %1 [ <retval> ])
+                    (reg:SI %0 [ _1 ]))
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (reg:SI %1 [ <retval> ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (cinsn (use (reg/i:SI ax)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 5
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_1"
+}
+
+/* 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/gcc.dg/rtl/x86_64/different-structs.c b/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c
new file mode 100644
index 0000000..5390146
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c
@@ -0,0 +1,95 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+extern double sqrt(double x);
+
+struct foo
+{
+  double x;
+  double y;
+};
+
+struct bar
+{
+  double x;
+  double y;
+};
+
+double __RTL test (struct foo *f, const struct bar *b)
+{
+#if 0
+  /* Result of "expand" on this C code, compiled for x86_64 with -Os.  */
+  f->x += b->x;
+  f->y += b->y;
+  return sqrt (f->x * f->x + f->y * f->y);
+#endif
+(function "test"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg/v/f:DI %10 [ f ])
+                    (reg:DI di [ f ])) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":18
+                 (nil))
+      (cinsn (set (reg/v/f:DI %11 [ b ])
+                    (reg:DI si [ b ])) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":18
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:DF %12)
+                    (mem:DF (reg/v/f:DI %10 [ f ]) [2 f_11(D)->x+0 S8 A64])) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":21
+                 (nil))
+      (cinsn (set (reg:DF %2 [ _3 ])
+                    (plus:DF (reg:DF %12)
+                        (mem:DF (reg/v/f:DI %11 [ b ]) [2 b_12(D)->x+0 S8 A64]))) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":21
+                 (nil))
+      (cinsn (set (mem:DF (reg/v/f:DI %10 [ f ]) [2 f_11(D)->x+0 S8 A64])
+                    (reg:DF %2 [ _3 ])) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":21
+                 (nil))
+      (cinsn (set (reg:DF %13)
+                    (mem:DF (plus:DI (reg/v/f:DI %10 [ f ])
+                            (const_int 8)) [2 f_11(D)->y+0 S8 A64])) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":22
+                 (nil))
+      (cinsn (set (reg:DF %5 [ _6 ])
+                    (plus:DF (reg:DF %13)
+                        (mem:DF (plus:DI (reg/v/f:DI %11 [ b ])
+                                (const_int 8)) [2 b_12(D)->y+0 S8 A64]))) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":22
+                 (nil))
+      (cinsn (set (mem:DF (plus:DI (reg/v/f:DI %10 [ f ])
+                            (const_int 8)) [2 f_11(D)->y+0 S8 A64])
+                    (reg:DF %5 [ _6 ])) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":22
+                 (nil))
+      (cinsn (set (reg:DF %14)
+                    (mult:DF (reg:DF %2 [ _3 ])
+                        (reg:DF %2 [ _3 ]))) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23
+                 (nil))
+      (cinsn (set (reg:DF %15)
+                    (mult:DF (reg:DF %5 [ _6 ])
+                        (reg:DF %5 [ _6 ]))) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23
+                 (nil))
+      (cinsn (set (reg:DF %16)
+                    (plus:DF (reg:DF %14)
+                        (reg:DF %15))) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23
+                 (nil))
+      (cinsn (set (reg:DF xmm0)
+                    (reg:DF %16)) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23
+                 (nil))
+      (ccall_insn/j (set (reg:DF xmm0)
+                    (call (mem:QI (symbol_ref:DI ("sqrt") [flags 0x41]  <function_decl 0x7f4fe01f9d00 sqrt>) [0 __builtin_sqrt S1 A8])
+                        (const_int 0))) "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23
+                 (expr_list:REG_CALL_DECL (symbol_ref:DI ("sqrt") [flags 0x41]  <function_decl 0x7f4fe01f9d00 sqrt>)
+                    (expr_list:REG_EH_REGION (const_int 0)
+                        (nil)))
+                (expr_list:DF (use (reg:DF xmm0))
+                    (nil)))
+      (edge-to exit (flags "ABNORMAL | SIBCALL"))
+    ) ;; block 2
+    (cbarrier)
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:DF xmm0)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test"
+
+}
diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/final.c b/gcc/testsuite/gcc.dg/rtl/x86_64/final.c
new file mode 100644
index 0000000..81d1031
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/final.c
@@ -0,0 +1,150 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-final" } */
+
+/* Lightly-modified dump of test.c.300r.dwarf2 for x86_64 target.  */
+
+int __RTL("rtl-final") test_1 (int i, int j, int k)
+{
+(function "test_1"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn/f (set (mem:DI (pre_dec:DI (reg/f:DI sp)) [0  S8 A8])
+                    (reg/f:DI bp)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote
+	.cfi_def_cfa_offset 16
+	 NOTE_INSN_CFI)
+      (cnote
+	.cfi_offset 6, -16
+	 NOTE_INSN_CFI)
+      (cinsn/f (set (reg/f:DI bp)
+                    (reg/f:DI sp)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote
+	.cfi_def_cfa_register 6
+	 NOTE_INSN_CFI)
+      (cinsn (set (mem/v:BLK (scratch:DI) [0  A8])
+                    (unspec:BLK [
+                            (mem/v:BLK (scratch:DI) [0  A8])
+                        ] UNSPEC_MEMORY_BLOCKAGE)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote NOTE_INSN_PROLOGUE_END)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -8)) [1 j+0 S4 A32])
+                    (reg:SI si [ j ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -12)) [1 k+0 S4 A32])
+                    (reg:SI dx [ k ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI ax [89])
+                    (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cinsn (set (reg:CCGC flags)
+                    (compare:CCGC (reg:SI ax [89])
+                        (mem/c:SI (plus:DI (reg/f:DI bp)
+                                (const_int -8)) [1 j+0 S4 A32]))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cjump_insn (set (pc)
+                    (if_then_else (ge (reg:CCGC flags)
+                            (const_int 0))
+                        (label_ref 16)
+                        (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (edge-to 3 (flags "FALLTHRU"))
+      (edge-to 4)
+    ) ;; block 2
+    (block 3
+      (edge-from 2 (flags "FALLTHRU"))
+      (cnote [bb 3] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI ax [90])
+                    (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI ax [orig:87 _1 ] [87])
+                            (plus:SI (reg:SI ax [90])
+                                (const_int 4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32])
+                        (const_int 4))
+                    (nil)))
+      (cjump_insn (set (pc)
+                    (label_ref 20)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (edge-to 5)
+    ) ;; block 3
+    (cbarrier)
+    (block 4
+      (edge-from 2)
+      (clabel 16 2 (nil))
+      (cnote [bb 4] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI ax [91])
+                    (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI ax [orig:87 _1 ] [87])
+                            (neg:SI (reg:SI ax [91])))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32]))
+                    (nil)))
+      (edge-to 5 (flags "FALLTHRU"))
+    ) ;; block 4
+    (block 5
+      (edge-from 4 (flags "FALLTHRU"))
+      (edge-from 3)
+      (clabel 20 3 (nil))
+      (cnote [bb 5] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (use (reg/i:SI ax)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (cnote NOTE_INSN_EPILOGUE_BEG)
+      (cinsn (set (mem/v:BLK (scratch:DI) [0  A8])
+                    (unspec:BLK [
+                            (mem/v:BLK (scratch:DI) [0  A8])
+                        ] UNSPEC_MEMORY_BLOCKAGE)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (cinsn/f (set (reg/f:DI bp)
+                    (mem:DI (post_inc:DI (reg/f:DI sp)) [0  S8 A8])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (expr_list:REG_CFA_DEF_CFA (plus:DI (reg/f:DI sp)
+                        (const_int 8))
+                    (nil)))
+      (cnote
+	.cfi_def_cfa 7, 8
+	 NOTE_INSN_CFI)
+      (cjump_insn (simple_return) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (edge-to exit)
+    ) ;; block 5
+    (cbarrier)
+    (cnote NOTE_INSN_DELETED)
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_1"
+}
+
+/* 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/gcc.dg/rtl/x86_64/into-cfglayout.c b/gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c
new file mode 100644
index 0000000..4c1cf8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/into-cfglayout.c
@@ -0,0 +1,117 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-into_cfglayout" } */
+
+/* Lightly-modified dump of test.c.222r.vregs for x86_64.  */
+
+int __RTL("rtl-into_cfglayout") test_1 (int i, int j, int k)
+{
+(function "test_1"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -8)) [1 j+0 S4 A32])
+                    (reg:SI si [ j ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])
+                    (reg:SI dx [ k ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %2)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cinsn (set (reg:CCGC flags)
+                    (compare:CCGC (reg:SI %2)
+                        (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -8)) [1 j+0 S4 A32]))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cjump_insn (set (pc)
+                    (if_then_else (ge (reg:CCGC flags)
+                            (const_int 0))
+                        (label_ref 16)
+                        (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (edge-to 4 (flags "FALLTHRU"))
+      (edge-to 5)
+    ) ;; block 2
+    (block 4
+      (edge-from 2 (flags "FALLTHRU"))
+      (cnote [bb 4] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %3)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (plus:SI (reg:SI %3)
+                                (const_int 4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32])
+                        (const_int 4))
+                    (nil)))
+      (cjump_insn (set (pc)
+                    (label_ref 20)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (edge-to 6)
+    ) ;; block 4
+    (cbarrier)
+    (block 5
+      (edge-from 2)
+      (clabel 16 2 (nil))
+      (cnote [bb 5] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %4)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (neg:SI (reg:SI %4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32]))
+                    (nil)))
+      (edge-to 6 (flags "FALLTHRU"))
+    ) ;; block 5
+    (block 6
+      (edge-from 4)
+      (edge-from 5 (flags "FALLTHRU"))
+      (clabel 20 3 (nil))
+      (cnote [bb 6] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %1 [ <retval> ])
+                    (reg:SI %0 [ _1 ]))
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (reg:SI %1 [ <retval> ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (cinsn (use (reg/i:SI ax)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 6
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_1"
+}
+
+/* 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/gcc.dg/rtl/x86_64/ira.c b/gcc/testsuite/gcc.dg/rtl/x86_64/ira.c
new file mode 100644
index 0000000..3d0efa4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/ira.c
@@ -0,0 +1,111 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-ira" } */
+
+/* Lightly-modified dump of test.c.261r.asmcons for x86_64.  */
+
+int __RTL ("rtl-ira") test_1 (int i, int j, int k)
+{
+(function "test_1"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -8)) [1 j+0 S4 A32])
+                    (reg:SI si [ j ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])
+                    (reg:SI dx [ k ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %2)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cinsn (set (reg:CCGC flags)
+                    (compare:CCGC (reg:SI %2)
+                        (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -8)) [1 j+0 S4 A32]))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cjump_insn (set (pc)
+                    (if_then_else (ge (reg:CCGC flags)
+                            (const_int 0))
+                        (label_ref 16)
+                        (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (edge-to 3 (flags "FALLTHRU"))
+      (edge-to 4)
+    ) ;; block 2
+    (block 3
+      (edge-from 2 (flags "FALLTHRU"))
+      (cnote [bb 3] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %3)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (plus:SI (reg:SI %3)
+                                (const_int 4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32])
+                        (const_int 4))
+                    (nil)))
+      (cjump_insn (set (pc)
+                    (label_ref 20)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (edge-to 5)
+    ) ;; block 3
+    (cbarrier)
+    (block 4
+      (edge-from 2)
+      (clabel 16 2 (nil))
+      (cnote [bb 4] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %4)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (neg:SI (reg:SI %4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32]))
+                    (nil)))
+      (edge-to 5 (flags "FALLTHRU"))
+    ) ;; block 4
+    (block 5
+      (edge-from 4 (flags "FALLTHRU"))
+      (edge-from 3)
+      (clabel 20 3 (nil))
+      (cnote [bb 5] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %1 [ <retval> ])
+                    (reg:SI %0 [ _1 ]))
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (reg:SI %1 [ <retval> ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (cinsn (use (reg/i:SI ax)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 5
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_1"
+}
+
+/* Verify that IRA was run.  */
+/* { dg-final { scan-rtl-dump "Building IRA IR" "ira" } } */
diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c b/gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c
new file mode 100644
index 0000000..d94206b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/pro_and_epilogue.c
@@ -0,0 +1,110 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-pro_and_epilogue" } */
+
+/* Lightly-modified dump of test.c.270r.split2 for x86_64.  */
+
+int __RTL("rtl-pro_and_epilogue") test_1 (int i, int j, int k)
+{
+(function "test_1"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -8)) [1 j+0 S4 A32])
+                    (reg:SI si [ j ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -12)) [1 k+0 S4 A32])
+                    (reg:SI dx [ k ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI ax [89])
+                    (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cinsn (set (reg:CCGC flags)
+                    (compare:CCGC (reg:SI ax [89])
+                        (mem/c:SI (plus:DI (reg/f:DI bp)
+                                (const_int -8)) [1 j+0 S4 A32]))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cjump_insn (set (pc)
+                    (if_then_else (ge (reg:CCGC flags)
+                            (const_int 0))
+                        (label_ref 16)
+                        (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (edge-to 3 (flags "FALLTHRU"))
+      (edge-to 4)
+    ) ;; block 2
+    (block 3
+      (edge-from 2 (flags "FALLTHRU"))
+      (cnote [bb 3] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI ax [90])
+                    (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI ax [orig:87 _1 ] [87])
+                            (plus:SI (reg:SI ax [90])
+                                (const_int 4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32])
+                        (const_int 4))
+                    (nil)))
+      (cjump_insn (set (pc)
+                    (label_ref 20)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (edge-to 5)
+    ) ;; block 3
+    (cbarrier)
+    (block 4
+      (edge-from 2)
+      (clabel 16 2 (nil))
+      (cnote [bb 4] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI ax [91])
+                    (mem/c:SI (plus:DI (reg/f:DI bp)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI ax [orig:87 _1 ] [87])
+                            (neg:SI (reg:SI ax [91])))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -12)) [1 k+0 S4 A32]))
+                    (nil)))
+      (edge-to 5 (flags "FALLTHRU"))
+    ) ;; block 4
+    (block 5
+      (edge-from 4 (flags "FALLTHRU"))
+      (edge-from 3)
+      (clabel 20 3 (nil))
+      (cnote [bb 5] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (use (reg/i:SI ax)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 5
+    (cnote NOTE_INSN_DELETED)
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_1"
+}
+
+/* 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/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c b/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c
new file mode 100644
index 0000000..b080f84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.after-expand.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+int __RTL test_returning_constant (void)
+{
+  /* C code:
+     return 42; */
+(function "test_returning_constant"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %0 [ _1 ])
+                    (const_int 42)) "../../src/test-return-const.c":3
+                 (nil))
+      (cinsn (set (reg:SI %1 [ <retval> ])
+                    (reg:SI %0 [ _1 ])) "../../src/test-return-const.c":3
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (reg:SI %1 [ <retval> ])) "../../src/test-return-const.c":4
+                 (nil))
+      (cinsn (use (reg/i:SI ax)) "../../src/test-return-const.c":4
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_returning_constant"
+}
diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c b/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c
new file mode 100644
index 0000000..37cd10c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/test-return-const.c.before-fwprop.c
@@ -0,0 +1,36 @@
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-fwprop1" } */
+
+int __RTL ("rtl-fwprop1") test_returning_constant (void)
+{
+  /* C code:
+     return 42; */
+(function "test_returning_constant"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %0 [ <retval> ])
+                    (const_int 42)) "../../src/test-return-const.c":3
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (const_int 42)) "../../src/test-return-const.c":4
+                 (expr_list:REG_DEAD (reg:SI %0 [ <retval> ])
+                    (nil)))
+      (cinsn (use (reg/i:SI ax)) "../../src/test-return-const.c":4
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_returning_constant"
+}
+
+/* Verify that insn 3 is eliminated.  */
+/* { dg-final { scan-rtl-dump "deferring deletion of insn with uid = 3" "fwprop1" } } */
+/* { dg-final { scan-rtl-dump "Deleted 1 trivially dead insns" "fwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c b/gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c
new file mode 100644
index 0000000..9bd1bf1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/test-rtl.c
@@ -0,0 +1,115 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+
+/* Test of embedding RTL dump in a C function, tagged with "__RTL".
+
+   This is a dump of test.c from immediately after "expand", for x86_64.  */
+
+int __RTL test_1 (int i, int j, int k)
+{
+  /*
+    if (i < j)
+      return k + 4;
+    else
+      return -k;
+  */
+(function "test_1"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -8)) [1 j+0 S4 A32])
+                    (reg:SI si [ j ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -12)) [1 k+0 S4 A32])
+                    (reg:SI dx [ k ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %2)
+                    (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cinsn (set (reg:CCGC flags)
+                    (compare:CCGC (reg:SI %2)
+                        (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                                (const_int -8)) [1 j+0 S4 A32]))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cjump_insn (set (pc)
+                    (if_then_else (ge (reg:CCGC flags)
+                            (const_int 0))
+                        (label_ref 16)
+                        (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (edge-to 4 (flags "FALLTHRU"))
+      (edge-to 5)
+    ) ;; block 2
+    (block 4
+      (edge-from 2 (flags "FALLTHRU"))
+      (cnote [bb 4] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %3)
+                    (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (plus:SI (reg:SI %3)
+                                (const_int 4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                                (const_int -12)) [1 k+0 S4 A32])
+                        (const_int 4))
+                    (nil)))
+      (cjump_insn (set (pc)
+                    (label_ref 20)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (edge-to 6)
+    ) ;; block 4
+    (cbarrier)
+    (block 5
+      (edge-from 2)
+      (clabel 16 2 (nil))
+      (cnote [bb 5] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %4)
+                    (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (neg:SI (reg:SI %4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                                (const_int -12)) [1 k+0 S4 A32]))
+                    (nil)))
+      (edge-to 6 (flags "FALLTHRU"))
+    ) ;; block 5
+    (block 6
+      (edge-from 4)
+      (edge-from 5 (flags "FALLTHRU"))
+      (clabel 20 3 (nil))
+      (cnote [bb 6] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %1 [ <retval> ])
+                    (reg:SI %0 [ _1 ]))
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (reg:SI %1 [ <retval> ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (cinsn (use (reg/i:SI ax)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 6
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_1"
+}
diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c
new file mode 100644
index 0000000..232ff0d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.after-expand.c
@@ -0,0 +1,49 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+
+int __RTL times_two (int i)
+{
+  /* C function:
+     return i * 2;  */
+(function "times_two"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/times-two.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %2)
+                    (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/times-two.c":3
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _2 ])
+                            (ashift:SI (reg:SI %2)
+                                (const_int 1)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/times-two.c":3
+                 (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                                (const_int -4)) [1 i+0 S4 A32])
+                        (const_int 1))
+                    (nil)))
+      (cinsn (set (reg:SI %1 [ <retval> ])
+                    (reg:SI %0 [ _2 ])) "../../src/times-two.c":3
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (reg:SI %1 [ <retval> ])) "../../src/times-two.c":4
+                 (nil))
+      (cinsn (use (reg/i:SI ax)) "../../src/times-two.c":4
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "times_two"
+}
diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c
new file mode 100644
index 0000000..0cccbd7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/times-two.c.before-df.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-dfinit" } */
+
+int __RTL ("rtl-dfinit") times_two (int i)
+{
+  /* C function:
+     return i * 2;  */
+(function "times_two"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/times-two.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %2)
+                    (mem/c:SI (plus:DI (reg/f:DI frame)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/times-two.c":3
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _2 ])
+                            (ashift:SI (reg:SI %2)
+                                (const_int 1)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/times-two.c":3
+                 (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI frame)
+                                (const_int -4)) [1 i+0 S4 A32])
+                        (const_int 1))
+                    (nil)))
+      (cinsn (set (reg:SI %1 [ <retval> ])
+                    (reg:SI %0 [ _2 ])) "../../src/times-two.c":3
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (reg:SI %1 [ <retval> ])) "../../src/times-two.c":4
+                 (nil))
+      (cinsn (use (reg/i:SI ax)) "../../src/times-two.c":4
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "times_two"
+}
+
+/* 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. 5 .di. 17 .flags." "dfinit" } } */
diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c b/gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c
new file mode 100644
index 0000000..6250aa7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/x86_64/vregs.c
@@ -0,0 +1,112 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-fdump-rtl-vregs" } */
+
+/* Lightly-modified dump of test.c.221r.expand for x86_64.  */
+
+int __RTL("rtl-vregs") test_1 (int i, int j, int k)
+{
+(function "test_1"
+  (insn-chain
+    (cnote NOTE_INSN_DELETED)
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -4)) [1 i+0 S4 A32])
+                    (reg:SI di [ i ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -8)) [1 j+0 S4 A32])
+                    (reg:SI si [ j ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cinsn (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -12)) [1 k+0 S4 A32])
+                    (reg:SI dx [ k ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2
+                 (nil))
+      (cnote NOTE_INSN_FUNCTION_BEG)
+      (cinsn (set (reg:SI %2)
+                    (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -4)) [1 i+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cinsn (set (reg:CCGC flags)
+                    (compare:CCGC (reg:SI %2)
+                        (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                                (const_int -8)) [1 j+0 S4 A32]))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (cjump_insn (set (pc)
+                    (if_then_else (ge (reg:CCGC flags)
+                            (const_int 0))
+                        (label_ref 16)
+                        (pc))) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":3
+                 (nil))
+      (edge-to 4 (flags "FALLTHRU"))
+      (edge-to 5)
+    ) ;; block 2
+    (block 4
+      (edge-from 2 (flags "FALLTHRU"))
+      (cnote [bb 4] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %3)
+                    (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (plus:SI (reg:SI %3)
+                                (const_int 4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (expr_list:REG_EQUAL (plus:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                                (const_int -12)) [1 k+0 S4 A32])
+                        (const_int 4))
+                    (nil)))
+      (cjump_insn (set (pc)
+                    (label_ref 20)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":4
+                 (nil))
+      (edge-to 6)
+    ) ;; block 4
+    (cbarrier)
+    (block 5
+      (edge-from 2)
+      (clabel 16 2 (nil))
+      (cnote [bb 5] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %4)
+                    (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                            (const_int -12)) [1 k+0 S4 A32])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (nil))
+      (cinsn (parallel [
+                        (set (reg:SI %0 [ _1 ])
+                            (neg:SI (reg:SI %4)))
+                        (clobber (reg:CC flags))
+                    ]) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":6
+                 (expr_list:REG_EQUAL (neg:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars)
+                                (const_int -12)) [1 k+0 S4 A32]))
+                    (nil)))
+      (edge-to 6 (flags "FALLTHRU"))
+    ) ;; block 5
+    (block 6
+      (edge-from 4)
+      (edge-from 5 (flags "FALLTHRU"))
+      (clabel 20 3 (nil))
+      (cnote [bb 6] NOTE_INSN_BASIC_BLOCK)
+      (cinsn (set (reg:SI %1 [ <retval> ])
+                    (reg:SI %0 [ _1 ]))
+                 (nil))
+      (cinsn (set (reg/i:SI ax)
+                    (reg:SI %1 [ <retval> ])) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (cinsn (use (reg/i:SI ax)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":7
+                 (nil))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 6
+  ) ;; insn-chain
+  (crtl
+    (return_rtx 
+      (reg/i:SI ax)
+    ) ;; return_rtx
+  ) ;; crtl
+) ;; function "test_1"
+}
+
+/* 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" } }  */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 1df80d0..9e266a3 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -479,6 +479,13 @@ compile_file (void)
   if (flag_syntax_only || flag_wpa)
     return;
  
+  /* The RTL frontend is currently only capable of running one pass; this
+     is done from within the parse_file langhook.
+     Hence we must return early here.  Fixing this would require
+     being able to run passes from a certain point onwards.  */
+  if (in_rtl_frontend_p)
+    return;
+
   /* Reset maximum_field_alignment, it can be adjusted by #pragma pack
      and this shouldn't influence any types built by the middle-end
      from now on (like gcov_info_type).  */
-- 
1.8.5.3

