Changed in v2: * move test dumps into external files * update for addition of selftest::location to rtl_dump_test
Blurb from v1: This patch uses rtl_dump_test to start building out a test suite for cse. I attempted to create a reproducer for PR 71779; however I'm not yet able to replicate the bogus cse reported there via the test case. gcc/ChangeLog: * cse.c: Include selftest.h and selftest-rtl.h. (selftest::test_simple_cse): New function. (selftest::test_pr71779): New function. (selftest::cse_c_tests): New function. * selftest-run-tests.c (selftest::run_tests): Call selftest::cse_c_tests. * selftest.h (selftest::cse_c_tests): New decl. gcc/testsuite/ChangeLog: * selftests/pr71779.rtl: New file. * selftests/simple-cse.rtl: New file. --- gcc/cse.c | 70 ++++++++++++++++++++++++++++++++++ gcc/selftest-run-tests.c | 1 + gcc/selftest.h | 1 + gcc/testsuite/selftests/pr71779.rtl | 39 +++++++++++++++++++ gcc/testsuite/selftests/simple-cse.rtl | 12 ++++++ 5 files changed, 123 insertions(+) create mode 100644 gcc/testsuite/selftests/pr71779.rtl create mode 100644 gcc/testsuite/selftests/simple-cse.rtl diff --git a/gcc/cse.c b/gcc/cse.c index 7069fab..96beb68 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "dbgcnt.h" #include "rtl-iter.h" +#include "selftest.h" +#include "selftest-rtl.h" #ifndef LOAD_EXTEND_OP #define LOAD_EXTEND_OP(M) UNKNOWN @@ -7773,3 +7775,71 @@ make_pass_cse_after_global_opts (gcc::context *ctxt) { return new pass_cse_after_global_opts (ctxt); } + +#if CHECKING_P + +namespace selftest { + +/* Selftests for CSE. */ + +/* Simple test of eliminating a redundant (reg + 1) computation + i.e. that: + r101 = r100 + 1; + r102 = r100 + 1; <<< common subexpression + *r103 = r101 * r102; + can be CSE-ed to: + r101 = r100 + 1; + r102 = r101; <<< replaced + *r103 = r101 * r102; + by cse_main. */ + +static void +test_simple_cse () +{ + /* Only run this tests for i386. */ +#ifndef I386_OPTS_H + return; +#endif + + rtl_dump_test t (SELFTEST_LOCATION, locate_file ("simple-cse.rtl")); + dataflow_test df_test; + + int tem; + tem = cse_main (get_insns (), max_reg_num ()); + ASSERT_EQ (0, tem); + + /* Verify that insn 2's SET_SRC has been replaced with + the SET_DEST of insn 1. */ + ASSERT_EQ (SET_DEST (PATTERN (get_insn_by_uid (1))), + SET_SRC (PATTERN (get_insn_by_uid (2)))); +} + +/* Towards a regression test for PR 71779. */ + +static void +test_pr71779 () +{ + /* Only run this tests for target==aarch64. */ +#ifndef GCC_AARCH64_H + return; +#endif + + rtl_dump_test t (SELFTEST_LOCATION, locate_file ("pr71779.rtl")); + dataflow_test df_test; + + int tem; + tem = cse_main (get_insns (), max_reg_num ()); + ASSERT_EQ (0, tem); +} + +/* Run all of the selftests within this file. */ + +void +cse_c_tests () +{ + test_simple_cse (); + test_pr71779 (); +} + +} // namespace selftest +#endif /* CHECKING_P */ diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c index a10657f..f110a08 100644 --- a/gcc/selftest-run-tests.c +++ b/gcc/selftest-run-tests.c @@ -72,6 +72,7 @@ selftest::run_tests () rtl_tests_c_tests (); read_rtl_function_c_tests (); df_core_c_tests (); + cse_c_tests (); /* Higher-level tests, or for components that other selftests don't rely on. */ diff --git a/gcc/selftest.h b/gcc/selftest.h index 95bf9b2..e07fa26 100644 --- a/gcc/selftest.h +++ b/gcc/selftest.h @@ -201,6 +201,7 @@ extern const char *path_to_src_gcc; alphabetical order. */ extern void bitmap_c_tests (); extern void combine_c_tests (); +extern void cse_c_tests (); extern void df_core_c_tests (); extern void diagnostic_c_tests (); extern void diagnostic_show_locus_c_tests (); diff --git a/gcc/testsuite/selftests/pr71779.rtl b/gcc/testsuite/selftests/pr71779.rtl new file mode 100644 index 0000000..5c4463f --- /dev/null +++ b/gcc/testsuite/selftests/pr71779.rtl @@ -0,0 +1,39 @@ +;; 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. + +(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 diff --git a/gcc/testsuite/selftests/simple-cse.rtl b/gcc/testsuite/selftests/simple-cse.rtl new file mode 100644 index 0000000..ee1c42e --- /dev/null +++ b/gcc/testsuite/selftests/simple-cse.rtl @@ -0,0 +1,12 @@ +(function "test_of_cse" + (insn-chain + (insn 1 0 2 2 (set (reg:SI 101) + (plus:SI (reg:SI 100) + (const_int 1 [0x1]))) -1 (nil)) + (insn 2 1 3 2 (set (reg:SI 102) + (plus:SI (reg:SI 100) + (const_int 1 [0x1]))) -1 (nil)) + (insn 3 2 0 2 (set (mem:SI (reg:SI 103) [1 i+0 S4 A32]) + (mult:SI (reg:SI 101) (reg:SI 102))) -1 (nil)) + ) ;; insn-chain +) ;; function -- 1.8.5.3