nvptx: Add support for vadd.add and vsub.add instructions.
authorRoger Sayle <roger@nextmovesoftware.com>
Mon, 6 Jul 2020 06:46:52 +0000 (07:46 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Mon, 6 Jul 2020 06:46:52 +0000 (07:46 +0100)
The following patch adds support for three-input addition instructions to
the nvptx backend.  The PTX ISA's "vadd.u32.u32.u32.add d, a, b, c"
instruction effectively implements 32-bit d = a+b+c, and the
"vsub.u32.u32.u32 d,a,b,c" instruction that provides 32-bit d = (a-b)+c.
The hope is that these mnemonics help ptxas generate the low-level
hardware's IADD3 instruction.

2020-07-06  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog:
* config/nvptx/nvptx.md (*vadd_addsi4): New instruction.
(*vsub_addsi4): New instruction.

gcc/testsuite/ChangeLog:
* gcc.target/nvptx/vadd_add.c: New test.
* gcc.target/nvptx/vsub_add.c: New test.

gcc/config/nvptx/nvptx.md
gcc/testsuite/gcc.target/nvptx/vadd_add.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/vsub_add.c [new file with mode: 0644]

index 5ceeac76c748aae468a7c5d0901f214c37ff6555..6545b81f948daf84685e4ab66699c79a6da2215b 100644 (file)
   ""
   "%.\\tadd%t0\\t%0, %1, %2;")
 
+(define_insn "*vadd_addsi4"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+        (plus:SI (plus:SI (match_operand:SI 1 "nvptx_register_operand" "R")
+                         (match_operand:SI 2 "nvptx_register_operand" "R"))
+                (match_operand:SI 3 "nvptx_register_operand" "R")))]
+  ""
+  "%.\\tvadd%t0%t1%t2.add\\t%0, %1, %2, %3;")
+
+(define_insn "*vsub_addsi4"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+        (plus:SI (minus:SI (match_operand:SI 1 "nvptx_register_operand" "R")
+                          (match_operand:SI 2 "nvptx_register_operand" "R"))
+                (match_operand:SI 3 "nvptx_register_operand" "R")))]
+  ""
+  "%.\\tvsub%t0%t1%t2.add\\t%0, %1, %2, %3;")
+
 (define_insn "sub<mode>3"
   [(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
        (minus:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
diff --git a/gcc/testsuite/gcc.target/nvptx/vadd_add.c b/gcc/testsuite/gcc.target/nvptx/vadd_add.c
new file mode 100644 (file)
index 0000000..dcb2394
--- /dev/null
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int foo(int x, int y, int z)
+{
+  return x + y + z;
+}
+
+unsigned int bar(unsigned int x, unsigned int y, unsigned int z)
+{
+  return x + y + z;
+}
+
+/* { dg-final { scan-assembler-times "vadd.u32.u32.u32.add" 2 } } */
+
diff --git a/gcc/testsuite/gcc.target/nvptx/vsub_add.c b/gcc/testsuite/gcc.target/nvptx/vsub_add.c
new file mode 100644 (file)
index 0000000..3f632c9
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int foo(int x, int y, int z)
+{
+  return (x - y) + z;
+}
+
+int bar(int x, int y, int z)
+{
+  return x + (y - z);
+}
+
+unsigned int ufoo(unsigned int x, unsigned int y, unsigned int z)
+{
+  return (x - y) + z;
+}
+
+unsigned int ubar(unsigned int x, unsigned int y, unsigned int z)
+{
+  return x + (y - z);
+}
+
+/* { dg-final { scan-assembler-times "vsub.u32.u32.u32.add" 4 } } */
+