From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18066 invoked by alias); 19 Dec 2016 16:39:28 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 18048 invoked by uid 89); 19 Dec 2016 16:39:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-5.0 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=*insn, DImode, dimode, PLUS X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 19 Dec 2016 16:39:25 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EBDE637EE1; Mon, 19 Dec 2016 16:39:23 +0000 (UTC) Received: from c64.redhat.com (vpn-230-239.phx2.redhat.com [10.3.230.239]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id uBJGdKF4012845; Mon, 19 Dec 2016 11:39:23 -0500 From: David Malcolm To: gcc-patches@gcc.gnu.org, Uros Bizjak , Jan Hubicka Cc: Bernd Schmidt , David Malcolm Subject: [PATCH] Add x86_64-specific selftests for RTL function reader (v2) Date: Mon, 19 Dec 2016 16:43:00 -0000 Message-Id: <1482167564-63098-1-git-send-email-dmalcolm@redhat.com> In-Reply-To: <1480644013-3660-4-git-send-email-dmalcolm@redhat.com> References: <1480644013-3660-4-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes X-SW-Source: 2016-12/txt/msg01617.txt.bz2 Note to i386 maintainters: this patch is part of the RTL frontend. It adds selftests for verifying that the RTL dump reader works as expected, with a mixture of real and hand-written "dumps" to exercise various aspects of the loader. Many RTL dumps contain target-specific features (e.g. names of hard regs), and so these selftests need to be target-specific, and hence this patch puts them in i386.c. Tested on i686-pc-linux-gnu and x86_64-pc-linux-gnu. OK for trunk, assuming bootstrap®rtest? (this is dependent on patch 8a within the kit). Changed in v2: - fixed selftest failures on i686: * config/i386/i386.c (selftest::ix86_test_loading_dump_fragment_1): Fix handling of "frame" reg. (selftest::ix86_test_loading_call_insn): Require TARGET_SSE. - updated to use "<3>" syntax for pseudos, rather than "$3" Blurb from v1: This patch adds more selftests for class function_reader, where the dumps to be read contain x86_64-specific features. In an earlier version of the patch kit, these were handled using preprocessor conditionals. This version instead runs them via a target hook for running target-specific selftests, thus putting them within i386.c. gcc/ChangeLog: * config/i386/i386.c (selftest::ix86_test_loading_dump_fragment_1): New function. (selftest::ix86_test_loading_call_insn): New function. (selftest::ix86_test_loading_full_dump): New function. (selftest::ix86_test_loading_unspec): New function. (selftest::ix86_run_selftests): Call the new functions. gcc/testsuite/ChangeLog: * selftests/x86_64: New subdirectory. * selftests/x86_64/call-insn.rtl: New file. * selftests/x86_64/copy-hard-reg-into-frame.rtl: New file. * selftests/x86_64/times-two.rtl: New file. * selftests/x86_64/unspec.rtl: New file. --- gcc/config/i386/i386.c | 210 +++++++++++++++++++++ gcc/testsuite/selftests/x86_64/call-insn.rtl | 17 ++ .../selftests/x86_64/copy-hard-reg-into-frame.rtl | 15 ++ gcc/testsuite/selftests/x86_64/times-two.rtl | 51 +++++ gcc/testsuite/selftests/x86_64/unspec.rtl | 20 ++ 5 files changed, 313 insertions(+) create mode 100644 gcc/testsuite/selftests/x86_64/call-insn.rtl create mode 100644 gcc/testsuite/selftests/x86_64/copy-hard-reg-into-frame.rtl create mode 100644 gcc/testsuite/selftests/x86_64/times-two.rtl create mode 100644 gcc/testsuite/selftests/x86_64/unspec.rtl diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 1cd1cd8..dc1a86f 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -51200,6 +51200,209 @@ ix86_test_dumping_memory_blockage () " ] UNSPEC_MEMORY_BLOCKAGE)))\n", pat, &r); } +/* Verify loading an RTL dump; specifically a dump of copying + a param on x86_64 from a hard reg into the frame. + This test is target-specific since the dump contains target-specific + hard reg names. */ + +static void +ix86_test_loading_dump_fragment_1 () +{ + rtl_dump_test t (SELFTEST_LOCATION, + locate_file ("x86_64/copy-hard-reg-into-frame.rtl")); + + rtx_insn *insn = get_insn_by_uid (1); + + /* The block structure and indentation here is purely for + readability; it mirrors the structure of the rtx. */ + tree mem_expr; + { + rtx pat = PATTERN (insn); + ASSERT_EQ (SET, GET_CODE (pat)); + { + rtx dest = SET_DEST (pat); + ASSERT_EQ (MEM, GET_CODE (dest)); + /* Verify the "/c" was parsed. */ + ASSERT_TRUE (RTX_FLAG (dest, call)); + ASSERT_EQ (SImode, GET_MODE (dest)); + { + rtx addr = XEXP (dest, 0); + ASSERT_EQ (PLUS, GET_CODE (addr)); + ASSERT_EQ (DImode, GET_MODE (addr)); + { + rtx lhs = XEXP (addr, 0); + /* Verify that the "frame" REG was consolidated. */ + ASSERT_RTX_PTR_EQ (frame_pointer_rtx, lhs); + } + { + rtx rhs = XEXP (addr, 1); + ASSERT_EQ (CONST_INT, GET_CODE (rhs)); + ASSERT_EQ (-4, INTVAL (rhs)); + } + } + /* Verify the "[1 i+0 S4 A32]" was parsed. */ + ASSERT_EQ (1, MEM_ALIAS_SET (dest)); + /* "i" should have been handled by synthesizing a global int + variable named "i". */ + mem_expr = MEM_EXPR (dest); + ASSERT_NE (mem_expr, NULL); + ASSERT_EQ (VAR_DECL, TREE_CODE (mem_expr)); + ASSERT_EQ (integer_type_node, TREE_TYPE (mem_expr)); + ASSERT_EQ (IDENTIFIER_NODE, TREE_CODE (DECL_NAME (mem_expr))); + ASSERT_STREQ ("i", IDENTIFIER_POINTER (DECL_NAME (mem_expr))); + /* "+0". */ + ASSERT_TRUE (MEM_OFFSET_KNOWN_P (dest)); + ASSERT_EQ (0, MEM_OFFSET (dest)); + /* "S4". */ + ASSERT_EQ (4, MEM_SIZE (dest)); + /* "A32. */ + ASSERT_EQ (32, MEM_ALIGN (dest)); + } + { + rtx src = SET_SRC (pat); + ASSERT_EQ (REG, GET_CODE (src)); + ASSERT_EQ (SImode, GET_MODE (src)); + ASSERT_EQ (5, REGNO (src)); + tree reg_expr = REG_EXPR (src); + /* "i" here should point to the same var as for the MEM_EXPR. */ + ASSERT_EQ (reg_expr, mem_expr); + } + } +} + +/* Verify that the RTL loader copes with a call_insn dump. + This test is target-specific since the dump contains a target-specific + hard reg name. */ + +static void +ix86_test_loading_call_insn () +{ + /* The test dump includes register "xmm0", where requires TARGET_SSE + to exist. */ + if (!TARGET_SSE) + return; + + rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/call-insn.rtl")); + + rtx_insn *insn = get_insns (); + ASSERT_EQ (CALL_INSN, GET_CODE (insn)); + + /* "/j". */ + ASSERT_TRUE (RTX_FLAG (insn, jump)); + + rtx pat = PATTERN (insn); + ASSERT_EQ (CALL, GET_CODE (SET_SRC (pat))); + + /* Verify REG_NOTES. */ + { + /* "(expr_list:REG_CALL_DECL". */ + ASSERT_EQ (EXPR_LIST, GET_CODE (REG_NOTES (insn))); + rtx_expr_list *note0 = as_a (REG_NOTES (insn)); + ASSERT_EQ (REG_CALL_DECL, REG_NOTE_KIND (note0)); + + /* "(expr_list:REG_EH_REGION (const_int 0 [0])". */ + rtx_expr_list *note1 = note0->next (); + ASSERT_EQ (REG_EH_REGION, REG_NOTE_KIND (note1)); + + ASSERT_EQ (NULL, note1->next ()); + } + + /* Verify CALL_INSN_FUNCTION_USAGE. */ + { + /* "(expr_list:DF (use (reg:DF 21 xmm0))". */ + rtx_expr_list *usage + = as_a (CALL_INSN_FUNCTION_USAGE (insn)); + ASSERT_EQ (EXPR_LIST, GET_CODE (usage)); + ASSERT_EQ (DFmode, GET_MODE (usage)); + ASSERT_EQ (USE, GET_CODE (usage->element ())); + ASSERT_EQ (NULL, usage->next ()); + } +} + +/* Verify that the RTL loader copes a dump from print_rtx_function. + This test is target-specific since the dump contains target-specific + hard reg names. */ + +static void +ix86_test_loading_full_dump () +{ + rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/times-two.rtl")); + + ASSERT_STREQ ("times_two", IDENTIFIER_POINTER (DECL_NAME (cfun->decl))); + + rtx_insn *insn_1 = get_insn_by_uid (1); + ASSERT_EQ (NOTE, GET_CODE (insn_1)); + + rtx_insn *insn_7 = get_insn_by_uid (7); + ASSERT_EQ (INSN, GET_CODE (insn_7)); + ASSERT_EQ (PARALLEL, GET_CODE (PATTERN (insn_7))); + + rtx_insn *insn_15 = get_insn_by_uid (15); + ASSERT_EQ (INSN, GET_CODE (insn_15)); + ASSERT_EQ (USE, GET_CODE (PATTERN (insn_15))); + + /* Verify crtl->return_rtx. */ + ASSERT_EQ (REG, GET_CODE (crtl->return_rtx)); + ASSERT_EQ (0, REGNO (crtl->return_rtx)); + ASSERT_EQ (SImode, GET_MODE (crtl->return_rtx)); +} + +/* Verify that the RTL loader copes with UNSPEC and UNSPEC_VOLATILE insns. + In particular, verify that it correctly loads the 2nd operand. + This test is target-specific since these are machine-specific + operands (and enums). */ + +static void +ix86_test_loading_unspec () +{ + rtl_dump_test t (SELFTEST_LOCATION, locate_file ("x86_64/unspec.rtl")); + + ASSERT_STREQ ("test_unspec", IDENTIFIER_POINTER (DECL_NAME (cfun->decl))); + + ASSERT_TRUE (cfun); + + /* Test of an UNSPEC. */ + rtx_insn *insn = get_insns (); + ASSERT_EQ (INSN, GET_CODE (insn)); + rtx set = single_set (insn); + ASSERT_NE (NULL, set); + rtx dst = SET_DEST (set); + ASSERT_EQ (MEM, GET_CODE (dst)); + rtx src = SET_SRC (set); + ASSERT_EQ (UNSPEC, GET_CODE (src)); + ASSERT_EQ (BLKmode, GET_MODE (src)); + ASSERT_EQ (UNSPEC_MEMORY_BLOCKAGE, XINT (src, 1)); + + rtx v0 = XVECEXP (src, 0, 0); + + /* Verify that the two uses of the first SCRATCH have pointer + equality. */ + rtx scratch_a = XEXP (dst, 0); + ASSERT_EQ (SCRATCH, GET_CODE (scratch_a)); + + rtx scratch_b = XEXP (v0, 0); + ASSERT_EQ (SCRATCH, GET_CODE (scratch_b)); + + ASSERT_EQ (scratch_a, scratch_b); + + /* Verify that the two mems are thus treated as equal. */ + ASSERT_TRUE (rtx_equal_p (dst, v0)); + + /* Verify the the insn is recognized. */ + ASSERT_NE(-1, recog_memoized (insn)); + + /* Test of an UNSPEC_VOLATILE, which has its own enum values. */ + insn = NEXT_INSN (insn); + ASSERT_EQ (INSN, GET_CODE (insn)); + + set = single_set (insn); + ASSERT_NE (NULL, set); + + src = SET_SRC (set); + ASSERT_EQ (UNSPEC_VOLATILE, GET_CODE (src)); + ASSERT_EQ (UNSPECV_RDTSCP, XINT (src, 1)); +} + /* Run all target-specific selftests. */ static void @@ -51207,6 +51410,13 @@ ix86_run_selftests (void) { ix86_test_dumping_hard_regs (); ix86_test_dumping_memory_blockage (); + + /* Various tests of loading RTL dumps, here because they contain + ix86-isms (e.g. names of hard regs). */ + ix86_test_loading_dump_fragment_1 (); + ix86_test_loading_call_insn (); + ix86_test_loading_full_dump (); + ix86_test_loading_unspec (); } } // namespace selftest diff --git a/gcc/testsuite/selftests/x86_64/call-insn.rtl b/gcc/testsuite/selftests/x86_64/call-insn.rtl new file mode 100644 index 0000000..8f3a781 --- /dev/null +++ b/gcc/testsuite/selftests/x86_64/call-insn.rtl @@ -0,0 +1,17 @@ +(function "test" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (ccall_insn/j 1 + (set (reg:DF xmm0) + (call (mem:QI (symbol_ref:DI ("sqrt") [flags 0x41] ) [0 __builtin_sqrt S1 A8]) + (const_int 0))) "test.c":19 + (expr_list:REG_CALL_DECL (symbol_ref:DI ("sqrt") [flags 0x41] ) + (expr_list:REG_EH_REGION (const_int 0) + (nil))) + (expr_list:DF (use (reg:DF xmm0)) + (nil))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain +) ;; function "test" diff --git a/gcc/testsuite/selftests/x86_64/copy-hard-reg-into-frame.rtl b/gcc/testsuite/selftests/x86_64/copy-hard-reg-into-frame.rtl new file mode 100644 index 0000000..4598a1c --- /dev/null +++ b/gcc/testsuite/selftests/x86_64/copy-hard-reg-into-frame.rtl @@ -0,0 +1,15 @@ +(function "copy_hard_reg_into_frame" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cinsn 1 (set (mem/c:SI + (plus:DI + (reg/f:DI frame) + (const_int -4)) + [1 i+0 S4 A32]) + (reg:SI di [ i ])) "test.c":2 + (nil)) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain +) ;; function diff --git a/gcc/testsuite/selftests/x86_64/times-two.rtl b/gcc/testsuite/selftests/x86_64/times-two.rtl new file mode 100644 index 0000000..8cec47a --- /dev/null +++ b/gcc/testsuite/selftests/x86_64/times-two.rtl @@ -0,0 +1,51 @@ +;; Dump of this C function: +;; +;; int times_two (int i) +;; { +;; return i * 2; +;; } +;; +;; after expand for target==x86_64 + +(function "times_two" + (insn-chain + (cnote 1 NOTE_INSN_DELETED) + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 4 [bb 2] NOTE_INSN_BASIC_BLOCK) + (cinsn 2 (set (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) + (const_int -4)) [1 i+0 S4 A32]) + (reg:SI di [ i ])) "../../src/times-two.c":2 + (nil)) + (cnote 3 NOTE_INSN_FUNCTION_BEG) + (cinsn 6 (set (reg:SI <2>) + (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) + (const_int -4)) [1 i+0 S4 A32])) "../../src/times-two.c":3 + (nil)) + (cinsn 7 (parallel [ + (set (reg:SI <0> [ _2 ]) + (ashift:SI (reg:SI <2>) + (const_int 1))) + (clobber (reg:CC flags)) + ]) "../../src/times-two.c":3 + (expr_list:REG_EQUAL (ashift:SI (mem/c:SI (plus:DI (reg/f:DI virtual-stack-vars) + (const_int -4)) [1 i+0 S4 A32]) + (const_int 1)) + (nil))) + (cinsn 10 (set (reg:SI <1> [ ]) + (reg:SI <0> [ _2 ])) "../../src/times-two.c":3 + (nil)) + (cinsn 14 (set (reg/i:SI ax) + (reg:SI <1> [ ])) "../../src/times-two.c":4 + (nil)) + (cinsn 15 (use (reg/i:SI ax)) "../../src/times-two.c":4 + (nil)) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain + (crtl + (return_rtx + (reg/i:SI ax) + ) ;; return_rtx + ) ;; crtl +) ;; function "times_two" diff --git a/gcc/testsuite/selftests/x86_64/unspec.rtl b/gcc/testsuite/selftests/x86_64/unspec.rtl new file mode 100644 index 0000000..ac822ac --- /dev/null +++ b/gcc/testsuite/selftests/x86_64/unspec.rtl @@ -0,0 +1,20 @@ +(function "test_unspec" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cinsn 1 (set (mem/v:BLK (0|scratch:DI) [0 A8]) + (unspec:BLK [ + (mem/v:BLK (reuse_rtx 0) [0 A8]) + ] UNSPEC_MEMORY_BLOCKAGE)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2 + (nil)) + + (cinsn 2 (set (mem/v:BLK (1|scratch:DI) [0 A8]) + (unspec_volatile:BLK [ + (mem/v:BLK (reuse_rtx 1) [0 A8]) + ] UNSPECV_RDTSCP)) "../../src/gcc/testsuite/gcc.dg/rtl/test.c":2 + (nil)) + + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain +) ;; function -- 1.8.5.3