x86: Use SET operation in MOVDIRI and MOVDIR64B
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 23 Sep 2020 19:11:45 +0000 (12:11 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 30 Sep 2020 12:34:37 +0000 (05:34 -0700)
Since MOVDIRI and MOVDIR64B write to memory, similar to UNSPEC_MOVNT,
use SET operation in MOVDIRI and MOVDIR64B patterns with UNSPEC instead
of UNSPECV.

gcc/

PR target/97184
* config/i386/i386.md (UNSPECV_MOVDIRI): Renamed to ...
(UNSPEC_MOVDIRI): This.
(UNSPECV_MOVDIR64B): Renamed to ...
(UNSPEC_MOVDIR64B): This.
(movdiri<mode>): Use SET operation.
(@movdir64b_<mode>): Likewise.

gcc/testsuite/

PR target/97184
* gcc.target/i386/movdir64b.c: New test.
* gcc.target/i386/movdiri32.c: Likewise.
* gcc.target/i386/movdiri64.c: Likewise.
* lib/target-supports.exp (check_effective_target_movdir): New.

gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/movdir64b.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/movdiri32.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/movdiri64.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp

index 93aae8123fd5962a71a5b71fe6e0d0c947524c8a..9dd12cf8643bf131532d36392395293e05a15178 100644 (file)
 
   ;; IRET support
   UNSPEC_INTERRUPT_RETURN
+
+  ;; For MOVDIRI and MOVDIR64B support
+  UNSPEC_MOVDIRI
+  UNSPEC_MOVDIR64B
 ])
 
 (define_c_enum "unspecv" [
   UNSPECV_SETSSBSY
   UNSPECV_CLRSSBSY
 
-  ;; For MOVDIRI and MOVDIR64B support
-  UNSPECV_MOVDIRI
-  UNSPECV_MOVDIR64B
-
   ;; For TSXLDTRK support
   UNSPECV_XSUSLDTRK
   UNSPECV_XRESLDTRK
 ;; MOVDIRI and MOVDIR64B
 
 (define_insn "movdiri<mode>"
-  [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
-                          (match_operand:SWI48 1 "register_operand" "r")]
-                         UNSPECV_MOVDIRI)]
+  [(set (match_operand:SWI48 0 "memory_operand" "=m")
+       (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
+                     UNSPEC_MOVDIRI))]
   "TARGET_MOVDIRI"
   "movdiri\t{%1, %0|%0, %1}"
   [(set_attr "type" "other")])
 
 (define_insn "@movdir64b_<mode>"
-  [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
-                       (match_operand:XI 1 "memory_operand")]
-                      UNSPECV_MOVDIR64B)]
+  [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
+       (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
+                  UNSPEC_MOVDIR64B))]
   "TARGET_MOVDIR64B"
   "movdir64b\t{%1, %0|%0, %1}"
   [(set_attr "type" "other")])
diff --git a/gcc/testsuite/gcc.target/i386/movdir64b.c b/gcc/testsuite/gcc.target/i386/movdir64b.c
new file mode 100644 (file)
index 0000000..70d872e
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do run { target movdir } } */
+/* { dg-options "-mmovdir64b -O2" } */
+
+#include <x86intrin.h>
+#include <string.h>
+
+unsigned long long int src[8] = {1, 2, 3, 4, 5, 6, 7, 8};
+unsigned long long int dest[8] __attribute__ ((aligned (64)))
+  = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+int
+main ()
+{
+  if (!__builtin_cpu_supports ("movdir64b"))
+    return 0;
+
+  _movdir64b (dest, src);
+
+  if (memcmp (dest, src, sizeof (dest)) != 0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/movdiri32.c b/gcc/testsuite/gcc.target/i386/movdiri32.c
new file mode 100644 (file)
index 0000000..604fa0d
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run { target movdir } } */
+/* { dg-options "-mmovdiri -O2" } */
+
+#include <x86intrin.h>
+
+unsigned int dest = -1;
+
+int
+main ()
+{
+  if (!__builtin_cpu_supports ("movdiri"))
+    return 0;
+
+  _directstoreu_u32 (&dest, 0xbadbeef);
+
+  if (dest != 0xbadbeef)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/movdiri64.c b/gcc/testsuite/gcc.target/i386/movdiri64.c
new file mode 100644 (file)
index 0000000..551b98e
--- /dev/null
@@ -0,0 +1,20 @@
+/* { dg-do run { target { movdir && { ! ia32 } } } } */
+/* { dg-options "-mmovdiri -O2" } */
+
+#include <x86intrin.h>
+
+unsigned long long int dest = -1LL;
+
+int
+main ()
+{
+  if (!__builtin_cpu_supports ("movdiri"))
+    return 0;
+
+  _directstoreu_u64 (&dest, 0x12345678badbeef);
+
+  if (dest != 0x12345678badbeef)
+    abort ();
+
+  return 0;
+}
index 8314e443c437fd14292de6876c2786945fff3393..2fb59e8759a7fb80d2938e1604b602a2fa20f277 100644 (file)
@@ -10552,3 +10552,20 @@ proc check_effective_target_ident_directive {} {
        int i;
     }]
 }
+
+# Return 1 if we're able to assemble movdiri and movdir64b
+
+proc check_effective_target_movdir { } {
+    return [check_no_compiler_messages movdir object {
+       void
+       foo (unsigned int *d, unsigned int s)
+       {
+         __builtin_ia32_directstoreu_u32 (d, s);
+       }
+       void
+       bar (void *d, const void *s)
+       {
+         __builtin_ia32_movdir64b (d, s);
+       }
+    } "-mmovdiri -mmovdir64b" ]
+}