[PATCH] nvptx: Add support for popcount and widening multiply instructions
authorRoger Sayle <roger@nextmovesoftware.com>
Fri, 3 Jul 2020 11:56:29 +0000 (12:56 +0100)
committerRoger Sayle <roger@nextmovesoftware.com>
Fri, 3 Jul 2020 11:56:29 +0000 (12:56 +0100)
2020-07-01  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog:
* config/nvptx/nvptx.md (popcount<mode>2): New instructions.
(mulhishi3, mulsidi3, umulhisi3, umulsidi3): New instructions.

gcc/testsuite/ChangeLog:
* gcc.target/nvptx/popc-1.c: New test.
* gcc.target/nvptx/popc-2.c: New test.
* gcc.target/nvptx/popc-3.c: New test.
* gcc.target/nvptx/mul-wide.c: New test.
* gcc.target/nvptx/umul-wide.c: New test.

gcc/config/nvptx/nvptx.md
gcc/testsuite/gcc.target/nvptx/mul-wide.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/popc-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/popc-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/popc-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/nvptx/umul-wide.c [new file with mode: 0644]

index 089cdf04f2ed23b0a549e3e6455d5ed0004f1d59..5ceeac76c748aae468a7c5d0901f214c37ff6555 100644 (file)
   DONE;
 })
 
+(define_insn "popcount<mode>2"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+       (popcount:SI (match_operand:SDIM 1 "nvptx_register_operand" "R")))]
+  ""
+  "%.\\tpopc.b%T1\\t%0, %1;")
+
+;; Multiplication variants
+
+(define_insn "mulhisi3"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+       (mult:SI (sign_extend:SI
+                 (match_operand:HI 1 "nvptx_register_operand" "R"))
+                (sign_extend:SI
+                 (match_operand:HI 2 "nvptx_register_operand" "R"))))]
+  ""
+  "%.\\tmul.wide.s16\\t%0, %1, %2;")
+
+(define_insn "mulsidi3"
+  [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
+       (mult:DI (sign_extend:DI
+                 (match_operand:SI 1 "nvptx_register_operand" "R"))
+                (sign_extend:DI
+                 (match_operand:SI 2 "nvptx_register_operand" "R"))))]
+  ""
+  "%.\\tmul.wide.s32\\t%0, %1, %2;")
+
+(define_insn "umulhisi3"
+  [(set (match_operand:SI 0 "nvptx_register_operand" "=R")
+       (mult:SI (zero_extend:SI
+                 (match_operand:HI 1 "nvptx_register_operand" "R"))
+                (zero_extend:SI
+                 (match_operand:HI 2 "nvptx_register_operand" "R"))))]
+  ""
+  "%.\\tmul.wide.u16\\t%0, %1, %2;")
+
+(define_insn "umulsidi3"
+  [(set (match_operand:DI 0 "nvptx_register_operand" "=R")
+       (mult:DI (zero_extend:DI
+                 (match_operand:SI 1 "nvptx_register_operand" "R"))
+                (zero_extend:DI
+                 (match_operand:SI 2 "nvptx_register_operand" "R"))))]
+  ""
+  "%.\\tmul.wide.u32\\t%0, %1, %2;")
+
 ;; Shifts
 
 (define_insn "ashl<mode>3"
diff --git a/gcc/testsuite/gcc.target/nvptx/mul-wide.c b/gcc/testsuite/gcc.target/nvptx/mul-wide.c
new file mode 100644 (file)
index 0000000..d84ec2e
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int mulhisi3(short x, short y)
+{
+  return (int)x * (int)y;
+}
+
+long mulsidi3(int x, int y)
+{
+  return (long)x * (long)y;
+}
+
+/* { dg-final { scan-assembler-times "mul.wide.s16" 1 } } */
+/* { dg-final { scan-assembler-times "mul.wide.s32" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/nvptx/popc-1.c b/gcc/testsuite/gcc.target/nvptx/popc-1.c
new file mode 100644 (file)
index 0000000..40e8cfd
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int foo(unsigned int x)
+{
+  return __builtin_popcount(x);
+}
+
+/* { dg-final { scan-assembler-times "popc.b32" 1 } } */
diff --git a/gcc/testsuite/gcc.target/nvptx/popc-2.c b/gcc/testsuite/gcc.target/nvptx/popc-2.c
new file mode 100644 (file)
index 0000000..90bda4a
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned long foo(unsigned long x)
+{
+  return __builtin_popcountl(x);
+}
+
+/* { dg-final { scan-assembler-times "popc.b64" 1 } } */
+/* { dg-final { scan-assembler-times "cvt.s64.s32" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/nvptx/popc-3.c b/gcc/testsuite/gcc.target/nvptx/popc-3.c
new file mode 100644 (file)
index 0000000..d5d4e15
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int foo(unsigned long x)
+{
+  return __builtin_popcountl(x);
+}
+
+/* { dg-final { scan-assembler-times "popc.b64" 1 } } */
+/* { dg-final { scan-assembler-times "cvt.s64.s32" 0 } } */
+
diff --git a/gcc/testsuite/gcc.target/nvptx/umul-wide.c b/gcc/testsuite/gcc.target/nvptx/umul-wide.c
new file mode 100644 (file)
index 0000000..cc9f20d
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int umulhisi3(unsigned short x, unsigned short y)
+{
+  return (unsigned int)x * (unsigned int)y;
+}
+
+unsigned long umulsidi3(unsigned int x, unsigned int y)
+{
+  return (unsigned long)x * (unsigned long)y;
+}
+
+/* { dg-final { scan-assembler-times "mul.wide.u16" 1 } } */
+/* { dg-final { scan-assembler-times "mul.wide.u32" 1 } } */
+