From cde71b653f2d9e2e63112557da31a3180b746d9c Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 8 Sep 2016 15:36:03 -0400
Subject: [PATCH 15/43] cse.c selftests

Changed in v2:
* move test dumps into external files
* update for addition of selftest::location to rtl_dump_test

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

