]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
d: Allow vectors to be compared for identity [PR108946]
authorIain Buclaw <ibuclaw@gdcproject.org>
Thu, 2 Mar 2023 23:00:44 +0000 (00:00 +0100)
committerIain Buclaw <ibuclaw@gdcproject.org>
Fri, 3 Mar 2023 00:25:45 +0000 (01:25 +0100)
Vector equality and comparisons are now accepted by the language
implementation, but identity wasn't.  Implement it as an extra integer
comparison of the bit-casted bitmask.

PR d/108946

gcc/d/ChangeLog:

* d-target.cc (Target::isVectorOpSupported): Allow identity ops.
* expr.cc (ExprVisitor::visit (IdentityExp *)): Handle vector identity
comparisons.

gcc/testsuite/ChangeLog:

* gdc.dg/simd2a.d: Update test.
* gdc.dg/simd2b.d: Likewise.
* gdc.dg/simd2c.d: Likewise.
* gdc.dg/simd2d.d: Likewise.
* gdc.dg/simd2e.d: Likewise.
* gdc.dg/simd2f.d: Likewise.
* gdc.dg/simd2g.d: Likewise.
* gdc.dg/simd2h.d: Likewise.
* gdc.dg/simd2i.d: Likewise.
* gdc.dg/simd2j.d: Likewise.

12 files changed:
gcc/d/d-target.cc
gcc/d/expr.cc
gcc/testsuite/gdc.dg/simd2a.d
gcc/testsuite/gdc.dg/simd2b.d
gcc/testsuite/gdc.dg/simd2c.d
gcc/testsuite/gdc.dg/simd2d.d
gcc/testsuite/gdc.dg/simd2e.d
gcc/testsuite/gdc.dg/simd2f.d
gcc/testsuite/gdc.dg/simd2g.d
gcc/testsuite/gdc.dg/simd2h.d
gcc/testsuite/gdc.dg/simd2i.d
gcc/testsuite/gdc.dg/simd2j.d

index 5eab5706eadf2fbc294d28d3a42742f432cb8d01..4c7a212703e52794460908a02197d39af7835fcb 100644 (file)
@@ -323,11 +323,6 @@ Target::isVectorOpSupported (Type *type, EXP op, Type *)
       /* Logical operators must have a result type of bool.  */
       return false;
 
-    case EXP::identity:
-    case EXP::notIdentity:
-      /* Comparison operators must have a result type of bool.  */
-      return false;
-
     default:
       break;
     }
index c8ec37d7103075e1bdb683477c89429025e82f63..4311edcc2d6039d0d7684913bc81b43ea2852328 100644 (file)
@@ -313,6 +313,31 @@ public:
 
        this->result_ = build_struct_comparison (code, ts->sym, t1, t2);
       }
+    else if (tb1->ty == TY::Tvector && tb2->ty == TY::Tvector)
+      {
+       /* For vectors, identity is defined as all values being equal.  */
+       tree t1 = build_expr (e->e1);
+       tree t2 = build_expr (e->e2);
+       tree mask = build_boolop (code, t1, t2);
+
+       /* To reinterpret the vector comparison as a boolean expression, bitcast
+          the bitmask result and generate an additional integer comparison.  */
+       opt_scalar_int_mode mode =
+         int_mode_for_mode (TYPE_MODE (TREE_TYPE (mask)));
+       gcc_assert (mode.exists ());
+
+       tree type = lang_hooks.types.type_for_mode (mode.require (), 1);
+       if (type == NULL_TREE)
+         type = make_unsigned_type (GET_MODE_BITSIZE (mode.require ()));
+
+       /* In `t1 is t2', all mask bits must be set for vectors to be equal.
+          Otherwise any bit set is enough for vectors to be not-equal.  */
+       tree mask_eq = (code == EQ_EXPR)
+         ? build_all_ones_cst (type) : build_zero_cst (type);
+
+       this->result_ = build_boolop (code, mask_eq,
+                                     build_vconvert (type, mask));
+      }
     else
       {
        /* For operands of other types, identity is defined as being the
index 373d5d1e229b056438c4d89ac3bcf5b39c52fbc7..d47175fd38b38414b945f529937b5dae05ba8a77 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2a()
 {
     byte16 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2a()
     v1 = v2 ^ v3;
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index e72da0d9b777bcede341f02a81d572b130fa247d..a1b2a10caaf1a57466d166d35a8769338023dbe7 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2b()
 {
     ubyte16 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2b()
     v1 = v2 ^ v3;
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index dc4954e219438a0d71c6daae08782236865c0dfa..ca8d1000306466ad9051d2439a8262bb6c42413c 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2c()
 {
     short8 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2c()
     v1 = v2 ^ v3;
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index 2d782bac89cba5bccde44871786c83133c79c0a0..e928d4be6015d67de315b546216d313ce355417a 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2d()
 {
     ushort8 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2d()
     v1 = v2 ^ v3;
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index b6d4ed6ef3a8582bd6ec2881c66a51ae65032c5e..a611ea770c9f41203fc5a8db2ad2b96c16010669 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2e()
 {
     int4 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2e()
     v1 = v2 ^ v3;
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index df8f13fddd17e116504f46a3f73dacde1ad73aac..1e9d6c264a861dcd2cffffae481fcf8c72898779 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2f()
 {
     uint4 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2f()
     v1 = v2 ^ v3;
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index 028b25e7d170f08f3eacbf159d7e2904988438d0..7183304b22362b0911bd95751f90c9c27db77333 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2g()
 {
     long2 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2g()
     v1 = v2 ^ v3;
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index 6c3e91a88142dcc9716881643ef2aaaeecf863dc..8c55e0117afcf1b78f631a460aec0c26d3a27328 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2h()
 {
     ulong2 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2h()
     v1 = v2 ^ v3;
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index 2fa7f3ad86ea2acbecc24cd4463187f900d2fcca..d9ff6889ea237dd7161cb7803f1974279a416873 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2i()
 {
     float4 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2i()
     static assert(!__traits(compiles, v1 ^ v2));
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));
index 7c2d12f33cf5026899844ccffd825395b217298b..a84120f3cce2f9b436b8980fb92f4c72077abbe5 100644 (file)
@@ -5,6 +5,7 @@ import core.simd;
 void test2j()
 {
     double2 v1, v2 = 1, v3 = 1;
+    bool b1;
     v1 = v2;
     v1 = v2 + v3;
     v1 = v2 - v3;
@@ -16,8 +17,8 @@ void test2j()
     static assert(!__traits(compiles, v1 ^ v2));
     static assert(!__traits(compiles, v1 ~ v2));
     static assert(!__traits(compiles, v1 ^^ v2));
-    static assert(!__traits(compiles, v1 is v2));
-    static assert(!__traits(compiles, v1 !is v2));
+    b1 = v1 is v2;
+    b1 = v1 !is v2;
     static assert( __traits(compiles, v1 == v2));
     static assert( __traits(compiles, v1 != v2));
     static assert( __traits(compiles, v1 < v2));