Add v2si support 2017-06-06 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. --- gcc/config/nvptx/nvptx-modes.def | 1 + gcc/config/nvptx/nvptx.c | 12 +++++ gcc/config/nvptx/nvptx.md | 29 +++++++++++ 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 +++++++ 9 files changed, 242 insertions(+) diff --git a/gcc/config/nvptx/nvptx-modes.def b/gcc/config/nvptx/nvptx-modes.def new file mode 100644 index 0000000..d49429c --- /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 beaad2c..d513ddb 100644 --- a/gcc/config/nvptx/nvptx.c +++ b/gcc/config/nvptx/nvptx.c @@ -234,6 +234,9 @@ nvptx_ptx_type_from_mode (machine_mode mode, bool promote) case DFmode: return ".f64"; + case V2SImode: + return ".v2.u32"; + default: gcc_unreachable (); } @@ -5357,6 +5360,12 @@ nvptx_goacc_reduction (gcall *call) } } +static bool +nvptx_vector_mode_supported (machine_mode mode) +{ + return mode == V2SImode; +} + #undef TARGET_OPTION_OVERRIDE #define TARGET_OPTION_OVERRIDE nvptx_option_override @@ -5471,6 +5480,9 @@ nvptx_goacc_reduction (gcall *call) #undef TARGET_GOACC_REDUCTION #define TARGET_GOACC_REDUCTION nvptx_goacc_reduction +#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 f2ed63b..ba0567c 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. @@ -201,6 +202,20 @@ %.\\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"))] "!MEM_P (operands[0]) || REG_P (operands[1])" @@ -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/gcc.target/nvptx/slp-run.c b/gcc/testsuite/gcc.target/nvptx/slp-run.c new file mode 100644 index 0000000..dedec471 --- /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 0000000..5dee147 --- /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 0000000..73f86bc --- /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 0000000..5821a5a --- /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 0000000..ce423d8 --- /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 0000000..269a974 --- /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; +}