aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@nextmovesoftware.com>2020-07-06 07:46:52 +0100
committerRoger Sayle <roger@nextmovesoftware.com>2020-07-06 07:46:52 +0100
commite6f323372efa29091cf052a276c15b9e6ebc00ae (patch)
tree91c29733a9092d427fcb4bd44c9015f68d3e72c9
parentcf2bfc7c8013b7fc72ec5f104156fce736c2b3e1 (diff)
downloadgcc-e6f323372efa29091cf052a276c15b9e6ebc00ae.zip
gcc-e6f323372efa29091cf052a276c15b9e6ebc00ae.tar.gz
gcc-e6f323372efa29091cf052a276c15b9e6ebc00ae.tar.bz2
nvptx: Add support for vadd.add and vsub.add instructions.
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.
-rw-r--r--gcc/config/nvptx/nvptx.md16
-rw-r--r--gcc/testsuite/gcc.target/nvptx/vadd_add.c15
-rw-r--r--gcc/testsuite/gcc.target/nvptx/vsub_add.c25
3 files changed, 56 insertions, 0 deletions
diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md
index 5ceeac7..6545b81 100644
--- a/gcc/config/nvptx/nvptx.md
+++ b/gcc/config/nvptx/nvptx.md
@@ -373,6 +373,22 @@
""
"%.\\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
index 0000000..dcb2394
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/vadd_add.c
@@ -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
index 0000000..3f632c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/vsub_add.c
@@ -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 } } */
+