Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIMD Extract MSbs/LSbs Intrinsics #4466

Merged
merged 2 commits into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions base/intrinsics/intrinsics.odin
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,9 @@ simd_reduce_xor :: proc(a: #simd[N]T) -> T where type_is_integer(T) || t
simd_reduce_any :: proc(a: #simd[N]T) -> T where type_is_boolean(T) ---
simd_reduce_all :: proc(a: #simd[N]T) -> T where type_is_boolean(T) ---

simd_extract_lsbs :: proc(a: #simd[N]T) -> bit_set[0..<N] where type_is_integer(T) || type_is_boolean(T) ---
simd_extract_msbs :: proc(a: #simd[N]T) -> bit_set[0..<N] where type_is_integer(T) || type_is_boolean(T) ---


simd_gather :: proc(ptr: #simd[N]rawptr, val: #simd[N]T, mask: #simd[N]U) -> #simd[N]T where type_is_integer(U) || type_is_boolean(U) ---
simd_scatter :: proc(ptr: #simd[N]rawptr, val: #simd[N]T, mask: #simd[N]U) where type_is_integer(U) || type_is_boolean(U) ---
Expand Down
3 changes: 3 additions & 0 deletions core/simd/simd.odin
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ reduce_xor :: intrinsics.simd_reduce_xor
reduce_any :: intrinsics.simd_reduce_any
reduce_all :: intrinsics.simd_reduce_all

extract_lsbs :: intrinsics.simd_extract_lsbs
extract_msbs :: intrinsics.simd_extract_msbs

// swizzle :: proc(a: #simd[N]T, indices: ..int) -> #simd[len(indices)]T
swizzle :: builtin.swizzle

Expand Down
33 changes: 33 additions & 0 deletions src/check_builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,39 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
return true;
}

case BuiltinProc_simd_extract_lsbs:
case BuiltinProc_simd_extract_msbs:
{
Operand x = {};
check_expr(c, &x, ce->args[0]); if (x.mode == Addressing_Invalid) return false;

if (!is_type_simd_vector(x.type)) {
gbString xs = type_to_string(x.type);
error(x.expr, "'%.*s' expected a simd vector type, got '%s'", LIT(builtin_name), xs);
gb_string_free(xs);
return false;
}

Type *elem = base_array_type(x.type);
if (!is_type_integer_like(elem)) {
gbString xs = type_to_string(x.type);
error(x.expr, "'%.*s' expected a #simd type with integer or boolean elements, got '%s'", LIT(builtin_name), xs);
gb_string_free(xs);
return false;
}

i64 num_elems = get_array_type_count(x.type);

Type *result_type = alloc_type_bit_set();
result_type->BitSet.elem = t_int;
result_type->BitSet.lower = 0;
result_type->BitSet.upper = num_elems - 1;

operand->mode = Addressing_Value;
operand->type = result_type;
return true;
}


case BuiltinProc_simd_shuffle:
{
Expand Down
6 changes: 6 additions & 0 deletions src/checker_builtin_procs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ BuiltinProc__simd_begin,
BuiltinProc_simd_reduce_any,
BuiltinProc_simd_reduce_all,

BuiltinProc_simd_extract_lsbs,
BuiltinProc_simd_extract_msbs,

BuiltinProc_simd_shuffle,
BuiltinProc_simd_select,

Expand Down Expand Up @@ -523,6 +526,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("simd_reduce_any"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_all"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},

{STR_LIT("simd_extract_lsbs"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_extract_msbs"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},


{STR_LIT("simd_shuffle"), 2, true, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_select"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
Expand Down
28 changes: 28 additions & 0 deletions src/llvm_backend_proc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,34 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
return res;
}

case BuiltinProc_simd_extract_lsbs:
case BuiltinProc_simd_extract_msbs:
{
Type *vt = arg0.type;
GB_ASSERT(vt->kind == Type_SimdVector);

i64 elem_bits = 8*type_size_of(elem);
i64 num_elems = get_array_type_count(vt);

LLVMValueRef broadcast_value = arg0.value;
if (builtin_id == BuiltinProc_simd_extract_msbs) {
LLVMTypeRef word_type = lb_type(m, elem);
LLVMValueRef shift_value = llvm_splat_int(num_elems, word_type, elem_bits - 1);
broadcast_value = LLVMBuildAShr(p->builder, broadcast_value, shift_value, "");
}

LLVMTypeRef bitvec_type = LLVMVectorType(LLVMInt1TypeInContext(m->ctx), (unsigned)num_elems);
LLVMValueRef bitvec_value = LLVMBuildTrunc(p->builder, broadcast_value, bitvec_type, "");

LLVMTypeRef mask_type = LLVMIntTypeInContext(m->ctx, (unsigned)num_elems);
LLVMValueRef mask_value = LLVMBuildBitCast(p->builder, bitvec_value, mask_type, "");

LLVMTypeRef result_type = lb_type(m, res.type);
res.value = LLVMBuildZExtOrBitCast(p->builder, mask_value, result_type, "");

return res;
}


case BuiltinProc_simd_shuffle:
{
Expand Down