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 diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 512b6c71a75..03a5160a2e6 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" "=Yx,Yx") + (match_operator:V2SF 3 "sse_comparison_operator" + [(match_operand:V2SF 1 "register_operand" "%0,Yx") + (match_operand:V2SF 2 "register_operand" "Yx,Yx")]))] + "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" "=Yx,Yx") + (match_operator:V2SF 3 "sse_comparison_operator" + [(match_operand:V2SF 1 "register_operand" "0,Yx") + (match_operand:V2SF 2 "register_operand" "Yx,Yx")]))] + "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; +} -- 2.20.1