+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.
--- /dev/null
+VECTOR_MODE (INT, SI, 2); /* V2SI */
case DFmode:
return ".f64";
+ case V2SImode:
+ return ".v2.u32";
+
default:
gcc_unreachable ();
}
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
#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"
(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" ""))]
+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
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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" } } */
+
--- /dev/null
+/* { 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" } } */
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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 \\}" } } */
--- /dev/null
+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;
+}