[mid-end][__RTL] Clean state despite unspecified __RTL startwith passes

Matthew Malcomson Matthew.Malcomson@arm.com
Thu Nov 14 18:38:00 GMT 2019


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).
I asked about this on the GCC mailing list a while ago and Richard mentioned
it might be a good idea to clear bad state so it doesn't leak to other
functions.
https://gcc.gnu.org/ml/gcc/2019-02/msg00106.html

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-14  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-14  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-14  Matthew Malcomson  <matthew.malcomson@arm.com>

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



###############     Attachment also inlined for ease of reply    ###############


diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 9589cc68c25b5b15bb364fdae56e24dedbe91601..05485833d306cd79c5405543175b63c2e7e62538 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -20868,11 +20868,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"
diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c
index f65c0af6dfd48aa9ca7ec29b63d7cd4108432178..38765ebbc288e7aef35d7c02693efd534c6b2ddc 100644
--- a/gcc/run-rtl-passes.c
+++ b/gcc/run-rtl-passes.c
@@ -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);
 }
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
index 0000000000000000000000000000000000000000..596501e977044132bd3e9a2d0afd0f8b2b789186
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/rtl/aarch64/unspecified-pass-error.c
@@ -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;
+}
+

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: unspecified-rtl-startwith.patch
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20191114/70e0b5c0/attachment.ksh>


More information about the Gcc-patches mailing list