From 20a380171f5db5f356b173d573559bfeef1ebbff Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Mon, 18 Nov 2019 11:16:46 +0000 Subject: [PATCH] [mid-end][__RTL] Clean state despite unspecified __RTL startwith passes 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 * 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 * 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 * gcc.dg/rtl/aarch64/unspecified-pass-error.c: New test. From-SVN: r278393 --- gcc/ChangeLog | 6 +++ gcc/c/ChangeLog | 5 +++ gcc/c/c-parser.c | 8 ++-- gcc/run-rtl-passes.c | 37 +++++++++++-------- gcc/testsuite/ChangeLog | 4 ++ .../rtl/aarch64/unspecified-pass-error.c | 30 +++++++++++++++ 6 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/rtl/aarch64/unspecified-pass-error.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5d4d770fe10..78a918281a7a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-11-18 Matthew Malcomson + + * 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 PR rtl-optimization/92462 diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 0076e8368880..0658ea0d2a69 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,8 @@ +2019-11-18 Matthew Malcomson + + * 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 * c-parser.c (c_parser_std_attribute_specifier): Diagnose diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index e48760dfd633..2efa23424ffb 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -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" diff --git a/gcc/run-rtl-passes.c b/gcc/run-rtl-passes.c index f65c0af6dfd4..38765ebbc288 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 (®_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 (®_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 (®_obstack); + opt_pass *clean_slate = g->get_passes ()->get_clean_slate (); + gcc_assert (clean_slate); + execute_pass_list (cfun, clean_slate); + bitmap_obstack_release (®_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/ChangeLog b/gcc/testsuite/ChangeLog index 40a61126b1f7..87705b421fc3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-11-18 Matthew Malcomson + + * gcc.dg/rtl/aarch64/unspecified-pass-error.c: New test. + 2019-11-18 Christophe Lyon * 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 index 000000000000..596501e97704 --- /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; +} + -- 2.43.5