Thread overview
__vector equality compare: LDC vs {GDC, DMD}
Jul 27, 2022
Bruce Carneal
Jul 27, 2022
kinke
Jul 27, 2022
Bruce Carneal
Jul 27, 2022
Iain Buclaw
Jul 27, 2022
kinke
July 27, 2022

LDC produces a boolean from a comparison of __vector(s), (v0 == v1).

GDC and DMD error out on that, requiring (v0.array == v1.array) to get the boolean.

I've already updated the few dependencies, all in unittest code, that I had on this LDC-unique behavior, with very little effort. I suspect this would, at most, be a minor portability issue for other SIMD coders as well since you're usually looking for masks or cmov-like functionality out of your conditionals, not scalar booleans.

That said, I am curious: is this behavior intentional or accidental?

A small argument for adopting the DMD/GDC behavior is that any future useful SIMD relOp DIP would probably have to call out a breaking change if you don't.

July 27, 2022

On Wednesday, 27 July 2022 at 03:50:50 UTC, Bruce Carneal wrote:

>

That said, I am curious: is this behavior intentional or accidental?

Intentional (based on the front-end type of (in)equality and identity expressions being a scalar bool, no special case for vectors): https://github.com/ldc-developers/ldc/commit/db8797e1ced40d555baa3007e6a5f6d05e29b58d

July 27, 2022

On Wednesday, 27 July 2022 at 08:04:03 UTC, kinke wrote:

>

On Wednesday, 27 July 2022 at 03:50:50 UTC, Bruce Carneal wrote:

>

That said, I am curious: is this behavior intentional or accidental?

Intentional (based on the front-end type of (in)equality and identity expressions being a scalar bool, no special case for vectors): https://github.com/ldc-developers/ldc/commit/db8797e1ced40d555baa3007e6a5f6d05e29b58d

OK. You will be aware of all of these but for future reference here are six things the compiler could do when presented with a vector relOp:

  1. error out (the current GDC and DMD choice)
  2. produce a scalar boolean (the current LDC choice for eql/not-eql)
  3. produce a bit-per-lane reduction to a scalar (as provided by ballot intrinsics)
  4. produce a vector of one byte booleans
  5. produce a full lane width vector of "booleans" (with value zero or one)
  6. produce a full lane width vector of masks (all zeros or all ones)

As noted in the linked to material, 6) is popular. Fortunately 6)
is reliably and efficiently synthesized by LDC and GDC from a simple known-bounds for loop over a ternary.

July 27, 2022

On Wednesday, 27 July 2022 at 08:04:03 UTC, kinke wrote:

>

On Wednesday, 27 July 2022 at 03:50:50 UTC, Bruce Carneal wrote:

>

That said, I am curious: is this behavior intentional or accidental?

Intentional (based on the front-end type of (in)equality and identity expressions being a scalar bool, no special case for vectors): https://github.com/ldc-developers/ldc/commit/db8797e1ced40d555baa3007e6a5f6d05e29b58d

Just a random observation, why (1 << sizeInBits) - 1 and not just -1? I'd have thought the former would suffer from overflow issues (sizeInBits == 64).

July 27, 2022

On Wednesday, 27 July 2022 at 16:49:35 UTC, Iain Buclaw wrote:

>

Just a random observation, why (1 << sizeInBits) - 1 and not just -1? I'd have thought the former would suffer from overflow issues (sizeInBits == 64).

Heh, absolutely right: https://github.com/ldc-developers/ldc/commit/fc28d2db91e205843a37ef1fa80af1f5a5476dea