diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-03-03 00:00:44 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2023-03-03 01:25:45 +0100 |
commit | 929c6b8cd12a3bd338a4c250274a9d86da5b2ea7 (patch) | |
tree | 44cc9a476333506c4dbecff672f3b91446af7727 /gcc/d | |
parent | ce1cea3e22f58bbddde017f8a92e59bae8892339 (diff) | |
download | gcc-929c6b8cd12a3bd338a4c250274a9d86da5b2ea7.zip gcc-929c6b8cd12a3bd338a4c250274a9d86da5b2ea7.tar.gz gcc-929c6b8cd12a3bd338a4c250274a9d86da5b2ea7.tar.bz2 |
d: Allow vectors to be compared for identity [PR108946]
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.
Diffstat (limited to 'gcc/d')
-rw-r--r-- | gcc/d/d-target.cc | 5 | ||||
-rw-r--r-- | gcc/d/expr.cc | 25 |
2 files changed, 25 insertions, 5 deletions
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc index 5eab570..4c7a212 100644 --- a/gcc/d/d-target.cc +++ b/gcc/d/d-target.cc @@ -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; } diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index c8ec37d..4311edc 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -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 |