Ping:
  https://gcc.gnu.org/ml/gcc-patches/2016-12/msg01616.html

(the patch has been successfully bootstrap&regrtested on
x86_64-pc-linux-gnu, and also tested on i686-pc-linux-gnu).

On Mon, 2016-12-19 at 12:12 -0500, David Malcolm wrote:
> 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&regrtest?
> (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 <rtx_expr_list *> (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 <rtx_expr_list *> (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] 
>  <function_decl 0x7f82b1429d00 sqrt>) [0 __builtin_sqrt S1 A8])
> +                    (const_int 0))) "test.c":19
> +        (expr_list:REG_CALL_DECL (symbol_ref:DI ("sqrt") [flags
> 0x41]  <function_decl 0x7f82b1429d00 sqrt>)
> +           (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> [ <retval> ])
> +                    (reg:SI <0> [ _2 ])) "../../src/times-two.c":3
> +                 (nil))
> +      (cinsn 14 (set (reg/i:SI ax)
> +                    (reg:SI <1> [ <retval> ])) "../../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

Reply via email to