From b98b34b708e321a292886e2dd368223d32a60e86 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Wed, 19 Jul 2017 13:05:21 +0000 Subject: [PATCH] Add v2si support for nvptx 2017-07-19 Tom de Vries * config/nvptx/nvptx-modes.def: New file. Add V2SImode. * config/nvptx/nvptx.c (nvptx_ptx_type_from_mode): Handle V2SImode. (nvptx_vector_mode_supported): New function. Allow V2SImode. (TARGET_VECTOR_MODE_SUPPORTED_P): Redefine to nvptx_vector_mode_supported. * config/nvptx/nvptx.md (VECIM): New mode iterator. Add V2SI. (mov_insn): New define_insn. (define_expand "mov): New define_expand. * gcc.target/nvptx/slp-run.c: New test. * gcc.target/nvptx/slp.c: New test. * gcc.target/nvptx/v2si-cvt.c: New test. * gcc.target/nvptx/v2si-run.c: New test. * gcc.target/nvptx/v2si.c: New test. * gcc.target/nvptx/vec.inc: New test. From-SVN: r250340 --- gcc/ChangeLog | 10 +++ gcc/config/nvptx/nvptx-modes.def | 1 + gcc/config/nvptx/nvptx.c | 12 ++++ gcc/config/nvptx/nvptx.md | 29 ++++++++ gcc/testsuite/ChangeLog | 9 +++ gcc/testsuite/gcc.target/nvptx/slp-run.c | 23 +++++++ gcc/testsuite/gcc.target/nvptx/slp.c | 25 +++++++ gcc/testsuite/gcc.target/nvptx/v2si-cvt.c | 39 +++++++++++ gcc/testsuite/gcc.target/nvptx/v2si-run.c | 83 +++++++++++++++++++++++ gcc/testsuite/gcc.target/nvptx/v2si.c | 12 ++++ gcc/testsuite/gcc.target/nvptx/vec.inc | 18 +++++ 11 files changed, 261 insertions(+) create mode 100644 gcc/config/nvptx/nvptx-modes.def create mode 100644 gcc/testsuite/gcc.target/nvptx/slp-run.c create mode 100644 gcc/testsuite/gcc.target/nvptx/slp.c create mode 100644 gcc/testsuite/gcc.target/nvptx/v2si-cvt.c create mode 100644 gcc/testsuite/gcc.target/nvptx/v2si-run.c create mode 100644 gcc/testsuite/gcc.target/nvptx/v2si.c create mode 100644 gcc/testsuite/gcc.target/nvptx/vec.inc diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c09e0f10e75..f117bd96a5e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2017-07-19 Tom de Vries + + * config/nvptx/nvptx-modes.def: New file. Add V2SImode. + * config/nvptx/nvptx.c (nvptx_ptx_type_from_mode): Handle V2SImode. + (nvptx_vector_mode_supported): New function. Allow V2SImode. + (TARGET_VECTOR_MODE_SUPPORTED_P): Redefine to nvptx_vector_mode_supported. + * config/nvptx/nvptx.md (VECIM): New mode iterator. Add V2SI. + (mov_insn): New define_insn. + (define_expand "mov): New define_expand. + 2017-07-19 Tom de Vries * config/nvptx/nvptx.c (nvptx_print_operand): Handle v2 vector mode. diff --git a/gcc/config/nvptx/nvptx-modes.def b/gcc/config/nvptx/nvptx-modes.def new file mode 100644 index 00000000000..d49429cf1b1 --- /dev/null +++ b/gcc/config/nvptx/nvptx-modes.def @@ -0,0 +1 @@ +VECTOR_MODE (INT, SI, 2); /* V2SI */ diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c index ebfa1e7b00e..bc94713bf0a 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -236,6 +236,9 @@ nvptx_ptx_type_from_mode (machine_mode mode, bool promote) case DFmode: return ".f64"; + case V2SImode: + return ".v2.u32"; + default: gcc_unreachable (); } @@ -5433,6 +5436,12 @@ nvptx_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, return true; } +static bool +nvptx_vector_mode_supported (machine_mode mode) +{ + return mode == V2SImode; +} + #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE nvptx_option_override @@ -5550,6 +5559,9 @@ nvptx_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, #undef TARGET_CANNOT_FORCE_CONST_MEM #define TARGET_CANNOT_FORCE_CONST_MEM nvptx_cannot_force_const_mem +#undef TARGET_VECTOR_MODE_SUPPORTED_P +#define TARGET_VECTOR_MODE_SUPPORTED_P nvptx_vector_mode_supported + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-nvptx.h" diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md index f2b090594e3..96a90e7f20d 100644 --- a/gcc/config/nvptx/nvptx.md +++ b/gcc/config/nvptx/nvptx.md @@ -184,6 +184,7 @@ (define_mode_iterator SDCM [SC DC]) (define_mode_iterator BITS [SI SF]) (define_mode_iterator BITD [DI DF]) +(define_mode_iterator VECIM [V2SI]) ;; This mode iterator allows :P to be used for patterns that operate on ;; pointer-sized quantities. Exactly one of the two alternatives will match. @@ -200,6 +201,20 @@ %.\\tsetp.eq.u32\\t%0, 1, 0; %.\\tsetp.eq.u32\\t%0, 1, 1;") +(define_insn "*mov_insn" + [(set (match_operand:VECIM 0 "nonimmediate_operand" "=R,R,m") + (match_operand:VECIM 1 "general_operand" "Ri,m,R"))] + "!MEM_P (operands[0]) || REG_P (operands[1])" +{ + if (which_alternative == 1) + return "%.\\tld%A1%u1\\t%0, %1;"; + if (which_alternative == 2) + return "%.\\tst%A0%u0\\t%0, %1;"; + + return nvptx_output_mov_insn (operands[0], operands[1]); +} + [(set_attr "subregs_ok" "true")]) + (define_insn "*mov_insn" [(set (match_operand:QHSDIM 0 "nonimmediate_operand" "=R,R,m") (match_operand:QHSDIM 1 "general_operand" "Ri,m,R"))] @@ -242,6 +257,20 @@ "" "%.\\tmov%t0\\t%0, %%ar%1;") + (define_expand "mov" + [(set (match_operand:VECIM 0 "nonimmediate_operand" "") + (match_operand:VECIM 1 "general_operand" ""))] + "" +{ + if (MEM_P (operands[0]) && !REG_P (operands[1])) + { + rtx tmp = gen_reg_rtx (mode); + emit_move_insn (tmp, operands[1]); + emit_move_insn (operands[0], tmp); + DONE; + } +}) + (define_expand "mov" [(set (match_operand:QHSDISDFM 0 "nonimmediate_operand" "") (match_operand:QHSDISDFM 1 "general_operand" ""))] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cad1ade6ea8..fd55c688b46 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2017-07-19 Tom de Vries + + * gcc.target/nvptx/slp-run.c: New test. + * gcc.target/nvptx/slp.c: New test. + * gcc.target/nvptx/v2si-cvt.c: New test. + * gcc.target/nvptx/v2si-run.c: New test. + * gcc.target/nvptx/v2si.c: New test. + * gcc.target/nvptx/vec.inc: New test. + 2017-07-19 Jakub Jelinek PR tree-optimization/81346 diff --git a/gcc/testsuite/gcc.target/nvptx/slp-run.c b/gcc/testsuite/gcc.target/nvptx/slp-run.c new file mode 100644 index 00000000000..dedec471bb9 --- /dev/null +++ b/gcc/testsuite/gcc.target/nvptx/slp-run.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -ftree-slp-vectorize" } */ + +#include "slp.c" + +int +main(void) +{ + unsigned int i; + for (i = 0; i < 1000; i += 1) + { + p[i] = i; + p2[i] = 0; + } + + foo (); + + for (i = 0; i < 1000; i += 1) + if (p2[i] != i) + return 1; + + return 0; +} diff --git a/gcc/testsuite/gcc.target/nvptx/slp.c b/gcc/testsuite/gcc.target/nvptx/slp.c new file mode 100644 index 00000000000..5dee147af9c --- /dev/null +++ b/gcc/testsuite/gcc.target/nvptx/slp.c @@ -0,0 +1,25 @@ +/* { dg-do assemble } */ +/* { dg-options "-O2 -ftree-slp-vectorize -save-temps" } */ + +int p[1000] __attribute__((aligned(8))); +int p2[1000] __attribute__((aligned(8))); + +void __attribute__((noinline, noclone)) +foo () +{ + int a, b; + + unsigned int i; + for (i = 0; i < 1000; i += 2) + { + a = p[i]; + b = p[i+1]; + + p2[i] = a; + p2[i+1] = b; + } +} + +/* { dg-final { scan-assembler "ld.v2.u32" } } */ +/* { dg-final { scan-assembler "st.v2.u32" } } */ + diff --git a/gcc/testsuite/gcc.target/nvptx/v2si-cvt.c b/gcc/testsuite/gcc.target/nvptx/v2si-cvt.c new file mode 100644 index 00000000000..73f86bcfa9e --- /dev/null +++ b/gcc/testsuite/gcc.target/nvptx/v2si-cvt.c @@ -0,0 +1,39 @@ +/* { dg-do assemble } */ +/* { dg-options "-O2 -save-temps" } */ + +typedef int __v2si __attribute__((__vector_size__(8))); + +int __attribute__((unused)) +vector_cvt (__v2si arg) +{ + __v2si val4 = arg; + char *p = (char*)&val4; + + if (p[0] != 1) + return 1; + if (p[1] != 2) + return 1; + if (p[2] != 3) + return 1; + + return 0; +} + +int +vector_cvt_2 (__v2si val, __v2si val2) +{ + char *p = (char*)&val; + char *p2 = (char*)&val2; + + if (p[0] != p2[0]) + return 1; + if (p[4] != p2[4]) + return 1; + + return 0; +} + +/* We want to test for 'mov.t' here, but given PR80845 we test for cvt.t.t + instead. + { dg-final { scan-assembler "(?n)cvt\\.u32\\.u32.*\\.x" } } */ +/* { dg-final { scan-assembler "(?n)cvt\\.u16\\.u32.*\\.x" } } */ diff --git a/gcc/testsuite/gcc.target/nvptx/v2si-run.c b/gcc/testsuite/gcc.target/nvptx/v2si-run.c new file mode 100644 index 00000000000..5821a5a95d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/nvptx/v2si-run.c @@ -0,0 +1,83 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include "v2si.c" + +void __attribute__((noinline, noclone)) +init_val ( __v2si *p) +{ + char *p2 = (char*)p; + p2[0] = 8; + p2[1] = 7; + p2[2] = 6; + p2[3] = 5; + p2[4] = 4; + p2[5] = 3; + p2[6] = 2; + p2[7] = 1; +} + +int +main (void) +{ + { + __v2si val; + __v2si val2; + __v2si val3; + + init_val(&val); + + /* Copy val to val2. */ + vector_store (&val2, val); + + /* Copy val2 to val3. */ + val3 = vector_load (&val2); + + /* Compare val to val3. */ + { + char *p = (char*)&val; + char *p2 = (char*)&val3; + + if (p[0] != p2[0]) + return 1; + if (p[1] != p2[1]) + return 1; + if (p[2] != p2[2]) + return 1; + if (p[3] != p2[3]) + return 1; + if (p[4] != p2[4]) + return 1; + if (p[5] != p2[5]) + return 1; + if (p[6] != p2[6]) + return 1; + if (p[7] != p2[7]) + return 1; + } + } + + { + __v2si val4 = vector_const (); + char *p = (char*)&val4; + + if (p[0] != 1) + return 1; + if (p[1] != 0) + return 1; + if (p[2] != 0) + return 1; + if (p[3] != 0) + return 1; + if (p[4] != 2) + return 1; + if (p[5] != 0) + return 1; + if (p[6] != 0) + return 1; + if (p[7] != 0) + return 1; + } + + return 0; +} diff --git a/gcc/testsuite/gcc.target/nvptx/v2si.c b/gcc/testsuite/gcc.target/nvptx/v2si.c new file mode 100644 index 00000000000..ce423d82c2c --- /dev/null +++ b/gcc/testsuite/gcc.target/nvptx/v2si.c @@ -0,0 +1,12 @@ +/* { dg-do assemble } */ +/* { dg-options "-O2 -save-temps" } */ + +typedef int __v2si __attribute__((__vector_size__(8))); + +#define TYPE __v2si +#include "vec.inc" + +/* { dg-final { scan-assembler ".reg\\.v2\\.u32" } } */ +/* { dg-final { scan-assembler "ld\\.v2\\.u32" } } */ +/* { dg-final { scan-assembler "st\\.v2\\.u32" } } */ +/* { dg-final { scan-assembler "(?n)mov\\.v2\\.u32.*\\{ 1, 2 \\}" } } */ diff --git a/gcc/testsuite/gcc.target/nvptx/vec.inc b/gcc/testsuite/gcc.target/nvptx/vec.inc new file mode 100644 index 00000000000..269a9749e26 --- /dev/null +++ b/gcc/testsuite/gcc.target/nvptx/vec.inc @@ -0,0 +1,18 @@ +TYPE __attribute__((noinline, noclone)) +vector_load (TYPE *p) +{ + return *p; +} + +void __attribute__((noinline, noclone)) +vector_store (TYPE *p, TYPE val) +{ + *p = val; +} + +TYPE __attribute__((noinline, noclone)) +vector_const () +{ + TYPE res = {1, 2}; + return res; +} -- 2.30.2