d: Add SIMD intrinsics module and compiler built-ins.
commitb93ae1a01bbad59ee77b7c84f4743a730138ba87
authorIain Buclaw <ibuclaw@gdcproject.org>
Tue, 28 Jun 2022 17:22:34 +0000 (28 19:22 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Wed, 29 Jun 2022 00:28:20 +0000 (29 02:28 +0200)
treee34e03818aa63ee9df776904df1ae30436e4b682
parentfb29fdea9cc36f4abeb8566968b2c1bd9054c7af
d: Add SIMD intrinsics module and compiler built-ins.

Vectors in D are exposed by the use of the `__vector(T[N])' type, and
whilst most unary and binary operations work as you'd expect, there are
some operations that are not possible without doing the operation
unrolled, or calling some target-specific built-in, or with inline asm.

This introduces a new `gcc.simd' module that introduces the following.

 - Prefetching has been exposed by a convenient `prefetch' function in
   the library.

 - Loading and storing from an unaligned address have been exposed by
   `loadUnaligned' and `storeUnaligned' intrinsics.

 - Vector permutations have been exposed by `shuffle`, and
   `shufflevector' intrinsics.

 - Converting between two vectors with a different element type has been
   exposed by a `convertvector' intrinsic.

 - The ternary operator has been exposed with a `blendvector' intrinsic.

 - Comparison operators have been exposed by `equalMask',
   `notEqualMask', `greaterMask', and `greaterEqualMask' intrinsics.

 - Logic operators have been exposed by convenient `notMask',
   `andAndMask', and `orOrMask' functions in the library.

To be compatible with the LLVM D compiler's own SIMD intrinsic module,
there is also the addition of an `extractelement' and `insertelement'
convenience functions, and an alternative interface for calling the
`shufflevector' function.

The addition of these intrinsics lowers the boundary for users working
in SIMD to get the desired codegen they want out of the compiler.

Most of what is present here - apart from tests - is the adding of
machinery in the intrinsics suite of functions to do validation on
templated intrinsics.  Whilst these are still matched from the library
by their generic (untyped) signature, there is a still an assumption
that what has been instantiated and handed down to the code generator is
valid, because why would these definitions be found outside of the
in-tree D runtime library?  The majority of intrinsics are not
templates, so the test on the mangled signature string still guarantees
all types are as we expect them to be.  However there are still a small
handful of other templated intrinsics (core.bitop.{rol,ror},
core.math.toPrec, std.math.traits.isNaN, ...) that are currently
unchecked, so would benefit from being included into this built-in
checking function at some point in the future.

gcc/d/ChangeLog:

* intrinsics.cc: Include diagnostic.h, langhooks.h,
vec-perm-indices.h.
(maybe_set_intrinsic): Add cases for new simd intrinsics.
(warn_mismatched_return_type): New function.
(warn_mismatched_argument): New function.
(build_shuffle_mask_type): New function.
(maybe_warn_intrinsic_mismatch): New function.
(expand_intrinsic_vec_cond): New function.
(expand_intrinsic_vec_convert): New function.
(expand_intrinsic_vec_blend): New function.
(expand_intrinsic_vec_shuffle): New function.
(expand_intrinsic_vec_shufflevector): New function.
(expand_intrinsic_vec_load_unaligned): New function.
(expand_intrinsic_vec_store_unaligned): New function.
(maybe_expand_intrinsic): Check signature of intrinsic before handing
off to front-end lowering.  Add cases for new simd intrinsics.
* intrinsics.def (INTRINSIC_LOADUNALIGNED): Define intrinsic.
(INTRINSIC_STOREUNALIGNED): Define intrinsic.
(INTRINSIC_SHUFFLE): Define intrinsic.
(INTRINSIC_SHUFFLEVECTOR): Define intrinsic.
(INTRINSIC_CONVERTVECTOR): Define intrinsic.
(INTRINSIC_BLENDVECTOR): Define intrinsic.
(INTRINSIC_EQUALMASK): Define intrinsic.
(INTRINSIC_NOTEQUALMASK): Define intrinsic.
(INTRINSIC_GREATERMASK): Define intrinsic.
(INTRINSIC_GREATEREQUALMASK): Define intrinsic.

libphobos/ChangeLog:

* libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add gcc/simd.d.
* libdruntime/Makefile.in: Regenerate.
* libdruntime/gcc/simd.d: New file.

gcc/testsuite/ChangeLog:

* gdc.dg/Wbuiltin_declaration_mismatch.d: Rename to...
* gdc.dg/Wbuiltin_declaration_mismatch1.d: ...this.
* gdc.dg/Wbuiltin_declaration_mismatch2.d: New test.
* gdc.dg/torture/simd_blendvector.d: New test.
* gdc.dg/torture/simd_cond.d: New test.
* gdc.dg/torture/simd_convertvector.d: New test.
* gdc.dg/torture/simd_load.d: New test.
* gdc.dg/torture/simd_logical.d: New test.
* gdc.dg/torture/simd_shuffle.d: New test.
* gdc.dg/torture/simd_shufflevector.d: New test.
* gdc.dg/torture/simd_store.d: New test.
15 files changed:
gcc/d/intrinsics.cc
gcc/d/intrinsics.def
gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch1.d [moved from gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch.d with 100% similarity]
gcc/testsuite/gdc.dg/Wbuiltin_declaration_mismatch2.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/torture/simd_blendvector.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/torture/simd_cond.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/torture/simd_convertvector.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/torture/simd_load.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/torture/simd_logical.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/torture/simd_shuffle.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/torture/simd_shufflevector.d [new file with mode: 0644]
gcc/testsuite/gdc.dg/torture/simd_store.d [new file with mode: 0644]
libphobos/libdruntime/Makefile.am
libphobos/libdruntime/Makefile.in
libphobos/libdruntime/gcc/simd.d [new file with mode: 0644]