This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 12/16] combine.c selftests (v2)
- From: David Malcolm <dmalcolm at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Wed, 5 Oct 2016 12:15:06 -0400
- Subject: [PATCH 12/16] combine.c selftests (v2)
- Authentication-results: sourceware.org; auth=none
- References: <1475684110-2521-1-git-send-email-dmalcolm@redhat.com>
Changed in v2:
* moved dumps from a string literal to external files (sharing
a dump with read-rtl-function.c)
* update for addition of selftest::location to rtl_dump_test
gcc/ChangeLog:
* combine.c: Include selftest.h and selftest-rtl.h.
(try_combine): Add assertion on this_basic_block.
(class selftest::combine_test): New subclass of
selftest::tl_dump_test.
(selftest::combine_test::combine_test): New ctor.
(selftest::test_combining_shifts): New function.
(selftest::test_non_combinable_shifts): New function.
(selftest::combine_c_tests): New function.
* selftest-run-tests.c (selftest::run_tests): Run
selftest::combine_c_tests.
* selftest.h (selftest::combine_c_tests): New decl.
gcc/testsuite/ChangeLog:
* selftests/non-combinable-shifts.rtl: New file.
---
gcc/combine.c | 121 ++++++++++++++++++++++
gcc/selftest-run-tests.c | 1 +
gcc/selftest.h | 1 +
gcc/testsuite/selftests/non-combinable-shifts.rtl | 18 ++++
4 files changed, 141 insertions(+)
create mode 100644 gcc/testsuite/selftests/non-combinable-shifts.rtl
diff --git a/gcc/combine.c b/gcc/combine.c
index b27aae5..ad1655e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -102,6 +102,8 @@ along with GCC; see the file COPYING3. If not see
#include "valtrack.h"
#include "rtl-iter.h"
#include "print-rtl.h"
+#include "selftest.h"
+#include "selftest-rtl.h"
#ifndef LOAD_EXTEND_OP
#define LOAD_EXTEND_OP(M) UNKNOWN
@@ -2625,6 +2627,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
rtx new_other_notes;
int i;
+ gcc_assert (this_basic_block);
+
/* Immediately return if any of I0,I1,I2 are the same insn (I3 can
never be). */
if (i1 == i2 || i0 == i2 || (i0 && i0 == i1))
@@ -14443,3 +14447,120 @@ make_pass_combine (gcc::context *ctxt)
{
return new pass_combine (ctxt);
}
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* A subclass of rtl_dump_test for testing combine.c. */
+
+class combine_test : public rtl_dump_test
+{
+ public:
+ combine_test (const location &loc, char *path);
+
+ private:
+ dataflow_test m_df_test;
+};
+
+/* combine_test's constructor. Read dumped RTL function from PATH,
+ taking ownership of PATH.
+ Initialize df and perform dataflow analysis. */
+
+combine_test::combine_test (const location &loc, char *path)
+: rtl_dump_test (loc, path),
+ m_df_test ()
+{
+ /* The dataflow instance should have been created by m_df_test's ctor. */
+ gcc_assert (df);
+
+ /* From rest_of_handle_combine. */
+ df_set_flags (/*DF_LR_RUN_DCE + */ DF_DEFER_INSN_RESCAN);
+ df_note_add_problem ();
+ df_analyze ();
+}
+
+/* Verify that combine_instructions works, for combining a pair of shifts.
+ Ideally we'd test try_combine by itself, but a fair amount of
+ refactoring would be needed to do so. */
+
+static void
+test_combining_shifts ()
+{
+ combine_test t (SELFTEST_LOCATION, locate_file ("asr_div1.rtl"));
+
+ rtx_insn *insn_8 = get_insn_by_uid (8);
+ ASSERT_TRUE (insn_8);
+
+ rtx_insn *insn_9 = get_insn_by_uid (9);
+ ASSERT_TRUE (insn_9);
+
+ int rebuild_jump_labels_after_combine
+ = combine_instructions (get_insns (), max_reg_num ());
+ ASSERT_FALSE (rebuild_jump_labels_after_combine);
+
+ /* Verify that insns 8 and 9 were combined. */
+ ASSERT_EQ (1, combine_merges);
+
+ /* insn 8 should now be deleted. */
+ ASSERT_EQ (NOTE, GET_CODE (insn_8));
+ ASSERT_EQ (NOTE_INSN_DELETED, NOTE_KIND (insn_8));
+
+ /* insn 9 should now be a shift of 35.
+ On aarch64 it's a set; on x86_64 it's a parallel of a set and a clobber
+ of CC. */
+ rtx set_in_9 = single_set (insn_9);
+ ASSERT_TRUE (set_in_9);
+ rtx src_of_9 = SET_SRC (set_in_9);
+ ASSERT_EQ (ASHIFTRT, GET_CODE (src_of_9));
+ rtx amt = XEXP (src_of_9, 1);
+ ASSERT_TRUE (CONST_INT_P (amt));
+ ASSERT_EQ (35, INTVAL (amt));
+}
+
+/* Test of failing to combine instructions.
+
+ Similar to test_combining_shifts, but with the input register
+ for the 2nd shift hand-edited (from 78 to 80) so that it doesn't come
+ from the output of the 1st shift, so that the shifts should *not*
+ be combinable. */
+
+static void
+test_non_combinable_shifts ()
+{
+ combine_test t (SELFTEST_LOCATION, locate_file ("non-combinable-shifts.rtl"));
+
+ rtx_insn *insn_8 = get_insn_by_uid (8);
+ ASSERT_TRUE (insn_8);
+
+ rtx_insn *insn_9 = get_insn_by_uid (9);
+ ASSERT_TRUE (insn_9);
+
+ int rebuild_jump_labels_after_combine
+ = combine_instructions (get_insns (), max_reg_num ());
+ ASSERT_FALSE (rebuild_jump_labels_after_combine);
+
+ /* Verify that no insns were combined. */
+ ASSERT_EQ (0, combine_merges);
+
+ /* insn 8 should not have be touched. */
+ ASSERT_EQ (INSN, GET_CODE (insn_8));
+}
+
+/* Run all of the selftests within this file. */
+
+void
+combine_c_tests ()
+{
+ /* Only run these tests for i386. */
+#ifndef I386_OPTS_H
+ return;
+#endif
+
+ test_combining_shifts ();
+ test_non_combinable_shifts ();
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
diff --git a/gcc/selftest-run-tests.c b/gcc/selftest-run-tests.c
index 5c95aaa..a10657f 100644
--- a/gcc/selftest-run-tests.c
+++ b/gcc/selftest-run-tests.c
@@ -75,6 +75,7 @@ selftest::run_tests ()
/* Higher-level tests, or for components that other selftests don't
rely on. */
+ combine_c_tests ();
diagnostic_show_locus_c_tests ();
diagnostic_c_tests ();
edit_context_c_tests ();
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 0033942..95bf9b2 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -200,6 +200,7 @@ extern const char *path_to_src_gcc;
/* Declarations for specific families of tests (by source file), in
alphabetical order. */
extern void bitmap_c_tests ();
+extern void combine_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/non-combinable-shifts.rtl b/gcc/testsuite/selftests/non-combinable-shifts.rtl
new file mode 100644
index 0000000..87da195
--- /dev/null
+++ b/gcc/testsuite/selftests/non-combinable-shifts.rtl
@@ -0,0 +1,18 @@
+(function "test"
+ (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 80) 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
--
1.8.5.3