[43/43] i386: Implement V2SF comparisons with SSE

Message ID 20190210001947.27278-44-hjl.tools@gmail.com
State New
Headers show
Series
  • V3: Emulate MMX intrinsics with SSE
Related show

Commit Message

H.J. Lu Feb. 10, 2019, 12:19 a.m.
In 64-bit mode, implement V2SF comparisons with SEE.  Only SSE register
source operand is allowed.

gcc/

	PR target/89028
	* config/i386/sse.md (V_128_64): New mode iterator.
	(VF_128_64): Likewise.
	(sseintvecmode): Add V2SF.
	(sseintvecmodelower): Likewise.
	(*sse_maskcmpv2sf3_comm): New.
	(*sse_maskcmpv2sf3): Likewise.
	(vcond<V_128:mode><VF_128:mode>): Renamed to ...
	(vcond<V_128_64:mode><VF_128_64:mode>): This.

gcc/testsuite/

	PR target/89028
	* gcc.target/i386/pr89028-10.c: New test.
	* gcc.target/i386/pr89028-11.c: Likewise.
	* gcc.target/i386/pr89028-12.c: Likewise.
	* gcc.target/i386/pr89028-13.c: Likewise.
---
 gcc/config/i386/sse.md                     | 61 ++++++++++++++++++----
 gcc/testsuite/gcc.target/i386/pr89028-10.c | 39 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr89028-11.c | 39 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr89028-12.c | 39 ++++++++++++++
 gcc/testsuite/gcc.target/i386/pr89028-13.c | 39 ++++++++++++++
 5 files changed, 208 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-10.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-11.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-12.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr89028-13.c

-- 
2.20.1

Patch

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 74c614a9f31..8105756f62c 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -246,6 +246,12 @@ 
 (define_mode_iterator V_128
   [V16QI V8HI V4SI V2DI V4SF (V2DF "TARGET_SSE2")])
 
+;; All 128bit and 64bit vector modes
+(define_mode_iterator V_128_64
+  [V16QI V8HI V4SI V2DI V4SF (V2DF "TARGET_SSE2")
+   (V8QI "TARGET_MMX_WITH_SSE") (V4HI "TARGET_MMX_WITH_SSE")
+   (V2SI "TARGET_MMX_WITH_SSE") (V2SF "TARGET_MMX_WITH_SSE")])
+
 ;; All 256bit vector modes
 (define_mode_iterator V_256
   [V32QI V16HI V8SI V4DI V8SF V4DF])
@@ -302,6 +308,10 @@ 
 (define_mode_iterator VF_128
   [V4SF (V2DF "TARGET_SSE2")])
 
+;; All 128bit and 64bit vector float modes
+(define_mode_iterator VF_128_64
+  [V4SF (V2DF "TARGET_SSE2") (V2SF "TARGET_MMX_WITH_SSE")])
+
 ;; All 256bit vector float modes
 (define_mode_iterator VF_256
   [V8SF V4DF])
@@ -734,6 +744,7 @@ 
   [(V16SF "V16SI") (V8DF  "V8DI")
    (V8SF  "V8SI")  (V4DF  "V4DI")
    (V4SF  "V4SI")  (V2DF  "V2DI")
+   (V2SF  "V2SI")
    (V16SI "V16SI") (V8DI  "V8DI")
    (V8SI  "V8SI")  (V4DI  "V4DI")
    (V4SI  "V4SI")  (V2DI  "V2DI")
@@ -749,6 +760,7 @@ 
   [(V16SF "v16si") (V8DF "v8di")
    (V8SF "v8si") (V4DF "v4di")
    (V4SF "v4si") (V2DF "v2di")
+   (V2SF "v2si")
    (V8SI "v8si") (V4DI "v4di")
    (V4SI "v4si") (V2DI "v2di")
    (V16HI "v16hi") (V8HI "v8hi")
@@ -2766,6 +2778,37 @@ 
    (set_attr "prefix" "orig,vex")
    (set_attr "mode" "<ssescalarmode>")])
 
+(define_insn "*sse_maskcmpv2sf3_comm"
+  [(set (match_operand:V2SF 0 "register_operand" "=x,x")
+	(match_operator:V2SF 3 "sse_comparison_operator"
+	  [(match_operand:V2SF 1 "register_operand" "%0,x")
+	   (match_operand:V2SF 2 "register_operand" "x,x")]))]
+  "TARGET_MMX_WITH_SSE
+   && GET_RTX_CLASS (GET_CODE (operands[3])) == RTX_COMM_COMPARE"
+  "@
+   cmp%D3ps\t{%2, %0|%0, %2}
+   vcmp%D3ps\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "noavx,avx")
+   (set_attr "type" "ssecmp")
+   (set_attr "length_immediate" "1")
+   (set_attr "prefix" "orig,vex")
+   (set_attr "mode" "SF")])
+
+(define_insn "*sse_maskcmpv2sf3"
+  [(set (match_operand:V2SF 0 "register_operand" "=x,x")
+	(match_operator:V2SF 3 "sse_comparison_operator"
+	  [(match_operand:V2SF 1 "register_operand" "0,x")
+	   (match_operand:V2SF 2 "register_operand" "x,x")]))]
+  "TARGET_MMX_WITH_SSE"
+  "@
+   cmp%D3ps\t{%2, %0|%0, %2}
+   vcmp%D3ps\t{%2, %1, %0|%0, %1, %2}"
+  [(set_attr "isa" "noavx,avx")
+   (set_attr "type" "ssecmp")
+   (set_attr "length_immediate" "1")
+   (set_attr "prefix" "orig,vex")
+   (set_attr "mode" "SF")])
+
 (define_mode_attr cmp_imm_predicate
   [(V16SF "const_0_to_31_operand")  (V8DF "const_0_to_31_operand")
    (V16SI "const_0_to_7_operand")   (V8DI "const_0_to_7_operand")
@@ -3089,17 +3132,17 @@ 
   DONE;
 })
 
-(define_expand "vcond<V_128:mode><VF_128:mode>"
-  [(set (match_operand:V_128 0 "register_operand")
-	(if_then_else:V_128
+(define_expand "vcond<V_128_64:mode><VF_128_64:mode>"
+  [(set (match_operand:V_128_64 0 "register_operand")
+	(if_then_else:V_128_64
 	  (match_operator 3 ""
-	    [(match_operand:VF_128 4 "vector_operand")
-	     (match_operand:VF_128 5 "vector_operand")])
-	  (match_operand:V_128 1 "general_operand")
-	  (match_operand:V_128 2 "general_operand")))]
+	    [(match_operand:VF_128_64 4 "vector_operand")
+	     (match_operand:VF_128_64 5 "vector_operand")])
+	  (match_operand:V_128_64 1 "general_operand")
+	  (match_operand:V_128_64 2 "general_operand")))]
   "TARGET_SSE
-   && (GET_MODE_NUNITS (<V_128:MODE>mode)
-       == GET_MODE_NUNITS (<VF_128:MODE>mode))"
+   && (GET_MODE_NUNITS (<V_128_64:MODE>mode)
+       == GET_MODE_NUNITS (<VF_128_64:MODE>mode))"
 {
   bool ok = ix86_expand_fp_vcond (operands);
   gcc_assert (ok);
diff --git a/gcc/testsuite/gcc.target/i386/pr89028-10.c b/gcc/testsuite/gcc.target/i386/pr89028-10.c
new file mode 100644
index 00000000000..fdb14212292
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr89028-10.c
@@ -0,0 +1,39 @@ 
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse2 -mno-mmx" } */
+/* { dg-final { scan-assembler-times "cmpneqps" 5 } } */
+
+typedef int __v2si __attribute__ ((__vector_size__ (8)));
+typedef char __v8qi __attribute__ ((__vector_size__ (8)));
+typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+typedef float __v2sf __attribute__ ((__vector_size__ (8)));
+typedef long long __v1di __attribute__ ((__vector_size__ (8)));
+
+__v2sf
+foo1 (__v2sf x, __v2sf y)
+{
+  return x != y;
+}
+
+__v8qi
+foo2 (__v2sf x, __v2sf y)
+{
+  return x != y;
+}
+
+__v4hi
+foo3 (__v2sf x, __v2sf y)
+{
+  return x != y;
+}
+
+__v2si
+foo4 (__v2sf x, __v2sf y)
+{
+  return x != y;
+}
+
+__v1di
+foo5 (__v2sf x, __v2sf y)
+{
+  return x != y;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr89028-11.c b/gcc/testsuite/gcc.target/i386/pr89028-11.c
new file mode 100644
index 00000000000..9cf1ea79d2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr89028-11.c
@@ -0,0 +1,39 @@ 
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse2 -mno-mmx" } */
+/* { dg-final { scan-assembler-times "cmpeqps" 5 } } */
+
+typedef int __v2si __attribute__ ((__vector_size__ (8)));
+typedef char __v8qi __attribute__ ((__vector_size__ (8)));
+typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+typedef float __v2sf __attribute__ ((__vector_size__ (8)));
+typedef long long __v1di __attribute__ ((__vector_size__ (8)));
+
+__v2sf
+foo1 (__v2sf x, __v2sf y)
+{
+  return x == y;
+}
+
+__v8qi
+foo2 (__v2sf x, __v2sf y)
+{
+  return x == y;
+}
+
+__v4hi
+foo3 (__v2sf x, __v2sf y)
+{
+  return x == y;
+}
+
+__v2si
+foo4 (__v2sf x, __v2sf y)
+{
+  return x == y;
+}
+
+__v1di
+foo5 (__v2sf x, __v2sf y)
+{
+  return x == y;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr89028-12.c b/gcc/testsuite/gcc.target/i386/pr89028-12.c
new file mode 100644
index 00000000000..20f91c4b0cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr89028-12.c
@@ -0,0 +1,39 @@ 
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse2 -mno-mmx" } */
+/* { dg-final { scan-assembler-times "cmpleps" 5 } } */
+
+typedef int __v2si __attribute__ ((__vector_size__ (8)));
+typedef char __v8qi __attribute__ ((__vector_size__ (8)));
+typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+typedef float __v2sf __attribute__ ((__vector_size__ (8)));
+typedef long long __v1di __attribute__ ((__vector_size__ (8)));
+
+__v2sf
+foo1 (__v2sf x, __v2sf y)
+{
+  return x >= y;
+}
+
+__v8qi
+foo2 (__v2sf x, __v2sf y)
+{
+  return x >= y;
+}
+
+__v4hi
+foo3 (__v2sf x, __v2sf y)
+{
+  return x >= y;
+}
+
+__v2si
+foo4 (__v2sf x, __v2sf y)
+{
+  return x >= y;
+}
+
+__v1di
+foo5 (__v2sf x, __v2sf y)
+{
+  return x >= y;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr89028-13.c b/gcc/testsuite/gcc.target/i386/pr89028-13.c
new file mode 100644
index 00000000000..1bc3a54ab02
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr89028-13.c
@@ -0,0 +1,39 @@ 
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -msse2 -mno-mmx" } */
+/* { dg-final { scan-assembler-times "cmpltps" 5 } } */
+
+typedef int __v2si __attribute__ ((__vector_size__ (8)));
+typedef char __v8qi __attribute__ ((__vector_size__ (8)));
+typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+typedef float __v2sf __attribute__ ((__vector_size__ (8)));
+typedef long long __v1di __attribute__ ((__vector_size__ (8)));
+
+__v2sf
+foo1 (__v2sf x, __v2sf y)
+{
+  return x > y;
+}
+
+__v8qi
+foo2 (__v2sf x, __v2sf y)
+{
+  return x > y;
+}
+
+__v4hi
+foo3 (__v2sf x, __v2sf y)
+{
+  return x > y;
+}
+
+__v2si
+foo4 (__v2sf x, __v2sf y)
+{
+  return x > y;
+}
+
+__v1di
+foo5 (__v2sf x, __v2sf y)
+{
+  return x > y;
+}