Add v2si support for nvptx
authorTom de Vries <tom@codesourcery.com>
Wed, 19 Jul 2017 13:05:21 +0000 (13:05 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Wed, 19 Jul 2017 13:05:21 +0000 (13:05 +0000)
2017-07-19  Tom de Vries  <tom@codesourcery.com>

* 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<VECIM>_insn): New define_insn.
(define_expand "mov<VECIM>): 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
gcc/config/nvptx/nvptx-modes.def [new file with mode: 0644]
gcc/config/nvptx/nvptx.c
gcc/config/nvptx/nvptx.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/nvptx/slp-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/slp.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/v2si-cvt.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/v2si-run.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/v2si.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/vec.inc [new file with mode: 0644]

index c09e0f10e7570cfdd39388345ea677cf0e9cef42..f117bd96a5e36b076dc79d8eb463adb88b7bc14c 100644 (file)
@@ -1,3 +1,13 @@
+2017-07-19  Tom de Vries  <tom@codesourcery.com>
+
+       * 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<VECIM>_insn): New define_insn.
+       (define_expand "mov<VECIM>): New define_expand.
+
 2017-07-19  Tom de Vries  <tom@codesourcery.com>
 
        * 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 (file)
index 0000000..d49429c
--- /dev/null
@@ -0,0 +1 @@
+VECTOR_MODE (INT, SI, 2);  /* V2SI */
index ebfa1e7b00e269991029b8e3cd17f49a6c331acb..bc94713bf0a5b7130a8f516b210793f5e7801186 100644 (file)
@@ -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"
index f2b090594e37caf752491ce4c912b82e0ff44833..96a90e7f20d48b2e340c2d95ae02019156d7e3fa 100644 (file)
 (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.
    %.\\tsetp.eq.u32\\t%0, 1, 0;
    %.\\tsetp.eq.u32\\t%0, 1, 1;")
 
+(define_insn "*mov<mode>_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<mode>_insn"
   [(set (match_operand:QHSDIM 0 "nonimmediate_operand" "=R,R,m")
        (match_operand:QHSDIM 1 "general_operand" "Ri,m,R"))]
   ""
   "%.\\tmov%t0\\t%0, %%ar%1;")
 
+ (define_expand "mov<mode>"
+  [(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>mode);
+      emit_move_insn (tmp, operands[1]);
+      emit_move_insn (operands[0], tmp);
+      DONE;
+    }
+})
+
 (define_expand "mov<mode>"
   [(set (match_operand:QHSDISDFM 0 "nonimmediate_operand" "")
        (match_operand:QHSDISDFM 1 "general_operand" ""))]
index cad1ade6ea8b360c20765ba3fd0b266ef1f4a079..fd55c688b46ee7b365e579fee9d4ee23a38e96ef 100644 (file)
@@ -1,3 +1,12 @@
+2017-07-19  Tom de Vries  <tom@codesourcery.com>
+
+       * 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  <jakub@redhat.com>
 
        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 (file)
index 0000000..dedec47
--- /dev/null
@@ -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 (file)
index 0000000..5dee147
--- /dev/null
@@ -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 (file)
index 0000000..73f86bc
--- /dev/null
@@ -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 (file)
index 0000000..5821a5a
--- /dev/null
@@ -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 (file)
index 0000000..ce423d8
--- /dev/null
@@ -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 (file)
index 0000000..269a974
--- /dev/null
@@ -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;
+}