diff mbox series

[C++] Sorry about <=> on VECTOR_TYPE.

Message ID 20191112045350.27934-1-jason@redhat.com
State New
Headers show
Series [C++] Sorry about <=> on VECTOR_TYPE. | expand

Commit Message

Jason Merrill Nov. 12, 2019, 4:53 a.m. UTC
I'm not sure what semantics we might eventually want for vector <=>, but let's
give a sorry for now.

Tested x86_64-pc-linux-gnu, applying to trunk.

---
 gcc/cp/typeck.c                             |  7 +++++++
 gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C | 11 +++++++++++
 2 files changed, 18 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C


base-commit: f15dc29a9734e360497f5bb40be6b25dcbc11645

Comments

Richard Biener Nov. 12, 2019, 8:10 a.m. UTC | #1
On Tue, Nov 12, 2019 at 5:54 AM Jason Merrill <jason@redhat.com> wrote:
>
> I'm not sure what semantics we might eventually want for vector <=>, but let's
> give a sorry for now.

Given our vector extension does elementwise comparisons I don't think we can
implement <=> in a reasonable manner.  What we could eventually do is
specify that <=> works on the whole vector, but then only unordered compares
are easy to define there...

So I think an error is more appropriate here, sorry indicates that
we're just not
implementing it.

Richard.

> Tested x86_64-pc-linux-gnu, applying to trunk.
>
> ---
>  gcc/cp/typeck.c                             |  7 +++++++
>  gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C | 11 +++++++++++
>  2 files changed, 18 insertions(+)
>  create mode 100644 gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C
>
> diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
> index 124d16a31fb..ff603f3d8d9 100644
> --- a/gcc/cp/typeck.c
> +++ b/gcc/cp/typeck.c
> @@ -5224,6 +5224,13 @@ cp_build_binary_op (const op_location_t &location,
>                           "types %qT and %qT", type0, type1);
>             }
>
> +         if (resultcode == SPACESHIP_EXPR)
> +           {
> +             if (complain & tf_error)
> +               sorry_at (location, "three-way comparison of vectors");
> +             return error_mark_node;
> +           }
> +
>           /* Always construct signed integer vector type.  */
>           intt = c_common_type_for_size
>             (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0);
> diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C
> new file mode 100644
> index 00000000000..83547691118
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C
> @@ -0,0 +1,11 @@
> +// { dg-do compile { target c++2a } }
> +
> +#include <compare>
> +
> +#define vector __attribute__((vector_size(4*sizeof(int)) ))
> +
> +int main()
> +{
> +  vector int a, b;
> +  a <=> b;                  // { dg-message "three-way comparison of vector" }
> +}
>
> base-commit: f15dc29a9734e360497f5bb40be6b25dcbc11645
> --
> 2.18.1
>
Jakub Jelinek Nov. 12, 2019, 9:02 a.m. UTC | #2
On Tue, Nov 12, 2019 at 09:10:58AM +0100, Richard Biener wrote:
> On Tue, Nov 12, 2019 at 5:54 AM Jason Merrill <jason@redhat.com> wrote:
> >
> > I'm not sure what semantics we might eventually want for vector <=>, but let's
> > give a sorry for now.
> 
> Given our vector extension does elementwise comparisons I don't think we can
> implement <=> in a reasonable manner.

Why?  We indeed can't return a vector of std::strong_ordering or
std::partial_ordering classes, but we could return a vector of either the
underlying integral values (0/1/-1/-127), or vector of enums from which one
could construct those std::strong_ordering or std::partial_ordering classes.
We do not support vectors of pointers and so the only possibilities are
strong orderings for integral vectors and partial orderings for floating
point vectors.

	Jakub
Richard Biener Nov. 12, 2019, 9:19 a.m. UTC | #3
On Tue, Nov 12, 2019 at 10:02 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Tue, Nov 12, 2019 at 09:10:58AM +0100, Richard Biener wrote:
> > On Tue, Nov 12, 2019 at 5:54 AM Jason Merrill <jason@redhat.com> wrote:
> > >
> > > I'm not sure what semantics we might eventually want for vector <=>, but let's
> > > give a sorry for now.
> >
> > Given our vector extension does elementwise comparisons I don't think we can
> > implement <=> in a reasonable manner.
>
> Why?  We indeed can't return a vector of std::strong_ordering or
> std::partial_ordering classes, but we could return a vector of either the
> underlying integral values (0/1/-1/-127), or vector of enums from which one
> could construct those std::strong_ordering or std::partial_ordering classes.
> We do not support vectors of pointers and so the only possibilities are
> strong orderings for integral vectors and partial orderings for floating
> point vectors.

But how to we actually emit (efficient) code for this?  A vector extension
should produce (efficient) vector code.

So unless there's convincing use-cases I'm not sure we need to do anything here.
In fact other unsupported operations on vectors produce errors, not sorry().

Richard.

>
>         Jakub
>
Jakub Jelinek Nov. 12, 2019, 9:52 a.m. UTC | #4
On Tue, Nov 12, 2019 at 10:19:49AM +0100, Richard Biener wrote:
> On Tue, Nov 12, 2019 at 10:02 AM Jakub Jelinek <jakub@redhat.com> wrote:
> >
> > On Tue, Nov 12, 2019 at 09:10:58AM +0100, Richard Biener wrote:
> > > On Tue, Nov 12, 2019 at 5:54 AM Jason Merrill <jason@redhat.com> wrote:
> > > >
> > > > I'm not sure what semantics we might eventually want for vector <=>, but let's
> > > > give a sorry for now.
> > >
> > > Given our vector extension does elementwise comparisons I don't think we can
> > > implement <=> in a reasonable manner.
> >
> > Why?  We indeed can't return a vector of std::strong_ordering or
> > std::partial_ordering classes, but we could return a vector of either the
> > underlying integral values (0/1/-1/-127), or vector of enums from which one
> > could construct those std::strong_ordering or std::partial_ordering classes.
> > We do not support vectors of pointers and so the only possibilities are
> > strong orderings for integral vectors and partial orderings for floating
> > point vectors.
> 
> But how to we actually emit (efficient) code for this?  A vector extension
> should produce (efficient) vector code.

For integers perhaps:
typedef int V __attribute__((vector_size(16)));

V
spaceship (V x, V y)
{
  return (x < y) | ((x > y) & (V) { 1, 1, 1, 1 });
}
or
	vpcmpgtd	%xmm1, %xmm0, %xmm2
	vpcmpgtd	%xmm0, %xmm1, %xmm0
	vpand	.LC0(%rip), %xmm2, %xmm2
	vpor	%xmm0, %xmm2, %xmm0
for -mavx?  Sure, for floating point it might be longer without -ffast-math,
though scalar floating <=> doesn't expand to something short either.
I believe it is something like
  x == y ? 0 : x < y ? -1 : x > y ? 1 : -127
so for float it could be something like (not sure about qNaNs and exceptions
for either scalar or vector)
vcmplt_oqps | (vcmpgt_oqps & {1,1,1,1}) \
| (vcmpunordps & {-127,-127,-127,-127})?

	Jakub
Richard Biener Nov. 13, 2019, 2:46 p.m. UTC | #5
On Tue, Nov 12, 2019 at 10:52 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Tue, Nov 12, 2019 at 10:19:49AM +0100, Richard Biener wrote:
> > On Tue, Nov 12, 2019 at 10:02 AM Jakub Jelinek <jakub@redhat.com> wrote:
> > >
> > > On Tue, Nov 12, 2019 at 09:10:58AM +0100, Richard Biener wrote:
> > > > On Tue, Nov 12, 2019 at 5:54 AM Jason Merrill <jason@redhat.com> wrote:
> > > > >
> > > > > I'm not sure what semantics we might eventually want for vector <=>, but let's
> > > > > give a sorry for now.
> > > >
> > > > Given our vector extension does elementwise comparisons I don't think we can
> > > > implement <=> in a reasonable manner.
> > >
> > > Why?  We indeed can't return a vector of std::strong_ordering or
> > > std::partial_ordering classes, but we could return a vector of either the
> > > underlying integral values (0/1/-1/-127), or vector of enums from which one
> > > could construct those std::strong_ordering or std::partial_ordering classes.
> > > We do not support vectors of pointers and so the only possibilities are
> > > strong orderings for integral vectors and partial orderings for floating
> > > point vectors.
> >
> > But how to we actually emit (efficient) code for this?  A vector extension
> > should produce (efficient) vector code.
>
> For integers perhaps:
> typedef int V __attribute__((vector_size(16)));
>
> V
> spaceship (V x, V y)
> {
>   return (x < y) | ((x > y) & (V) { 1, 1, 1, 1 });
> }
> or
>         vpcmpgtd        %xmm1, %xmm0, %xmm2
>         vpcmpgtd        %xmm0, %xmm1, %xmm0
>         vpand   .LC0(%rip), %xmm2, %xmm2
>         vpor    %xmm0, %xmm2, %xmm0
> for -mavx?  Sure, for floating point it might be longer without -ffast-math,
> though scalar floating <=> doesn't expand to something short either.
> I believe it is something like
>   x == y ? 0 : x < y ? -1 : x > y ? 1 : -127
> so for float it could be something like (not sure about qNaNs and exceptions
> for either scalar or vector)
> vcmplt_oqps | (vcmpgt_oqps & {1,1,1,1}) \
> | (vcmpunordps & {-127,-127,-127,-127})?

Hmm, OK.  Since we don't have SPACESHIP_EXPR in GIMPLE the FE
has to lower it so indeed the above could be done.  Then
(vector <=> vector)[i] should be equal to vector[i] <=> vector[i] as well?

Richard.

>         Jakub
>
diff mbox series

Patch

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 124d16a31fb..ff603f3d8d9 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5224,6 +5224,13 @@  cp_build_binary_op (const op_location_t &location,
 			  "types %qT and %qT", type0, type1);
 	    }
 
+	  if (resultcode == SPACESHIP_EXPR)
+	    {
+	      if (complain & tf_error)
+		sorry_at (location, "three-way comparison of vectors");
+	      return error_mark_node;
+	    }
+
 	  /* Always construct signed integer vector type.  */
 	  intt = c_common_type_for_size
 	    (GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (type0))), 0);
diff --git a/gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C b/gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C
new file mode 100644
index 00000000000..83547691118
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/spaceship-vec1.C
@@ -0,0 +1,11 @@ 
+// { dg-do compile { target c++2a } }
+
+#include <compare>
+
+#define vector __attribute__((vector_size(4*sizeof(int)) ))
+
+int main()
+{
+  vector int a, b;
+  a <=> b;		     // { dg-message "three-way comparison of vector" }
+}