[mid-end][__RTL] Clean state despite unspecified __RTL startwith passes
authorMatthew Malcomson <matthew.malcomson@arm.com>
Mon, 18 Nov 2019 11:16:46 +0000 (11:16 +0000)
committerMatthew Malcomson <matmal01@gcc.gnu.org>
Mon, 18 Nov 2019 11:16:46 +0000 (11:16 +0000)
Hi there,

When compiling an __RTL function that has an unspecified "startwith"
pass we currently don't run the cleanup pass, this means that we ICE on
the next function (if it's a basic function).

This change ensures that the clean_state pass is run even if the
startwith pass is unspecified.

We also ensure the name of the startwith pass is always freed correctly.

As an example, before this change the following code would ICE when compiling
the function `foo_a`.

When compiled with
./aarch64-none-linux-gnu-gcc -O0 -S unspecified-pass-error.c -o test.s

```
int __RTL () badfoo ()
{
(function "badfoo"
  (insn-chain
    (block 2
      (edge-from entry (flags "FALLTHRU"))
      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
      (cinsn 101 (set (reg:DI x19) (reg:DI x0)))
      (cinsn 10 (use (reg/i:SI x19)))
      (edge-to exit (flags "FALLTHRU"))
    ) ;; block 2
  ) ;; insn-chain
) ;; function "foo2"
}

int
foo_a ()
{
  return 200;
}
```

Now it silently ignores the __RTL function and successfully compiles foo_a.

regtest done on aarch64
regtest done on x86_64

OK for trunk?

gcc/ChangeLog:

2019-11-18  Matthew Malcomson  <matthew.malcomson@arm.com>

* run-rtl-passes.c (run_rtl_passes): Accept and handle empty
"initial_pass_name" argument -- by running "*clean_state" pass.
Also free the "initial_pass_name" when done.

gcc/c/ChangeLog:

2019-11-18  Matthew Malcomson  <matthew.malcomson@arm.com>

* c-parser.c (c_parser_parse_rtl_body): Always call
run_rtl_passes, even if startwith pass is not provided.

gcc/testsuite/ChangeLog:

2019-11-18  Matthew Malcomson  <matthew.malcomson@arm.com>

* gcc.dg/rtl/aarch64/unspecified-pass-error.c: New test.

From-SVN: r278393

gcc/ChangeLog
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/run-rtl-passes.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/rtl/aarch64/unspecified-pass-error.c [new file with mode: 0644]

index f5d4d770fe1017b6b3124da5d9b6961d0e675295..78a918281a7a97038904263e726efcf7af1330b7 100644 (file)
@@ -1,3 +1,9 @@
+2019-11-18  Matthew Malcomson  <matthew.malcomson@arm.com>
+
+       * run-rtl-passes.c (run_rtl_passes): Accept and handle empty
+       "initial_pass_name" argument -- by running "*clean_state" pass.
+       Also free the "initial_pass_name" when done.
+
 2019-11-18  Richard Biener  <rguenther@suse.de>
 
        PR rtl-optimization/92462
index 0076e83688803729a53feec5bf1e4805a97288ff..0658ea0d2a69d65d1d342883ba78784d5e68e493 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-18  Matthew Malcomson  <matthew.malcomson@arm.com>
+
+       * c-parser.c (c_parser_parse_rtl_body): Always call
+       run_rtl_passes, even if startwith pass is not provided.
+
 2019-11-15  Joseph Myers  <joseph@codesourcery.com>
 
        * c-parser.c (c_parser_std_attribute_specifier): Diagnose
index e48760dfd633bee3f270fce83c84d1990b4441ad..2efa23424ffb5f2b707e9b8521ee15202b18e322 100644 (file)
@@ -21574,11 +21574,9 @@ c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
       return;
     }
 
- /*  If a pass name was provided for START_WITH_PASS, run the backend
-     accordingly now, on the cfun created above, transferring
-     ownership of START_WITH_PASS.  */
-  if (start_with_pass)
-    run_rtl_passes (start_with_pass);
+ /*  Run the backend on the cfun created above, transferring ownership of
+     START_WITH_PASS.  */
+  run_rtl_passes (start_with_pass);
 }
 
 #include "gt-c-c-parser.h"
index f65c0af6dfd48aa9ca7ec29b63d7cd4108432178..38765ebbc288e7aef35d7c02693efd534c6b2ddc 100644 (file)
@@ -49,24 +49,31 @@ run_rtl_passes (char *initial_pass_name)
   switch_to_section (text_section);
   (*debug_hooks->assembly_start) ();
 
-  /* Pass "expand" normally sets this up.  */
+  if (initial_pass_name)
+    {
+      /* Pass "expand" normally sets this up.  */
 #ifdef INSN_SCHEDULING
-  init_sched_attrs ();
+      init_sched_attrs ();
 #endif
+      bitmap_obstack_initialize (NULL);
+      bitmap_obstack_initialize (&reg_obstack);
+      opt_pass *rest_of_compilation
+       = g->get_passes ()->get_rest_of_compilation ();
+      gcc_assert (rest_of_compilation);
+      execute_pass_list (cfun, rest_of_compilation);
 
-  bitmap_obstack_initialize (NULL);
-  bitmap_obstack_initialize (&reg_obstack);
-
-  opt_pass *rest_of_compilation
-    = g->get_passes ()->get_rest_of_compilation ();
-  gcc_assert (rest_of_compilation);
-  execute_pass_list (cfun, rest_of_compilation);
-
-  opt_pass *clean_slate = g->get_passes ()->get_clean_slate ();
-  gcc_assert (clean_slate);
-  execute_pass_list (cfun, clean_slate);
-
-  bitmap_obstack_release (&reg_obstack);
+      opt_pass *clean_slate = g->get_passes ()->get_clean_slate ();
+      gcc_assert (clean_slate);
+      execute_pass_list (cfun, clean_slate);
+      bitmap_obstack_release (&reg_obstack);
+    }
+  else
+    {
+      opt_pass *clean_slate = g->get_passes ()->get_clean_slate ();
+      gcc_assert (clean_slate);
+      execute_pass_list (cfun, clean_slate);
+    }
 
   cfun->curr_properties |= PROP_rtl;
+  free (initial_pass_name);
 }
index 40a61126b1f721e40439ee855662c158de1b99f4..87705b421fc3ff71570d9a6a5a4d02dd0e42a017 100644 (file)
@@ -1,3 +1,7 @@
+2019-11-18  Matthew Malcomson  <matthew.malcomson@arm.com>
+
+       * gcc.dg/rtl/aarch64/unspecified-pass-error.c: New test.
+
 2019-11-18  Christophe Lyon  <christophe.lyon@linaro.org>
 
        * lib/target-supports.exp
diff --git a/gcc/testsuite/gcc.dg/rtl/aarch64/unspecified-pass-error.c b/gcc/testsuite/gcc.dg/rtl/aarch64/unspecified-pass-error.c
new file mode 100644 (file)
index 0000000..596501e
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile { target aarch64-*-* } } */
+/* { dg-additional-options "-O0" } */
+
+/*
+   Ensure an __RTL function with an unspecified "startwith" pass doesn't cause
+   an assertion error on the next function.
+ */
+
+int __RTL () badfoo ()
+{
+(function "badfoo"
+  (insn-chain
+    (block 2
+      (edge-from entry (flags "FALLTHRU"))
+      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
+      (cinsn 101 (set (reg:DI x19) (reg:DI x0)))
+      (cinsn 10 (use (reg/i:SI x19)))
+      (edge-to exit (flags "FALLTHRU"))
+    ) ;; block 2
+  ) ;; insn-chain
+) ;; function "foo2"
+}
+
+/* Compile a valid C function to test the clean_state pass has been run.  */
+int
+foo_a ()
+{
+  return 200;
+}
+