Merge pull request #5108 from Barinzaya/core-simd-indices-redadd-redmul

Alternate `reduce_add`/`reduce_mul` intrinsics
This commit is contained in:
gingerBill
2025-05-06 15:46:49 +01:00
committed by GitHub
5 changed files with 274 additions and 2 deletions
+4
View File
@@ -853,8 +853,12 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
}
break;
case BuiltinProc_simd_reduce_add_bisect:
case BuiltinProc_simd_reduce_mul_bisect:
case BuiltinProc_simd_reduce_add_ordered:
case BuiltinProc_simd_reduce_mul_ordered:
case BuiltinProc_simd_reduce_add_pairs:
case BuiltinProc_simd_reduce_mul_pairs:
case BuiltinProc_simd_reduce_min:
case BuiltinProc_simd_reduce_max:
{
+8
View File
@@ -170,8 +170,12 @@ BuiltinProc__simd_begin,
BuiltinProc_simd_extract,
BuiltinProc_simd_replace,
BuiltinProc_simd_reduce_add_bisect,
BuiltinProc_simd_reduce_mul_bisect,
BuiltinProc_simd_reduce_add_ordered,
BuiltinProc_simd_reduce_mul_ordered,
BuiltinProc_simd_reduce_add_pairs,
BuiltinProc_simd_reduce_mul_pairs,
BuiltinProc_simd_reduce_min,
BuiltinProc_simd_reduce_max,
BuiltinProc_simd_reduce_and,
@@ -518,8 +522,12 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("simd_extract"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_replace"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_add_bisect"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_mul_bisect"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_add_ordered"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_mul_ordered"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_add_pairs"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_mul_pairs"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_min"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_max"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("simd_reduce_and"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
+66
View File
@@ -1495,6 +1495,38 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
res.value = LLVMBuildInsertElement(p->builder, arg0.value, arg2.value, arg1.value, "");
return res;
case BuiltinProc_simd_reduce_add_bisect:
case BuiltinProc_simd_reduce_mul_bisect:
{
GB_ASSERT(arg0.type->kind == Type_SimdVector);
i64 num_elems = arg0.type->SimdVector.count;
LLVMValueRef *indices = gb_alloc_array(temporary_allocator(), LLVMValueRef, num_elems);
for (i64 i = 0; i < num_elems; i++) {
indices[i] = lb_const_int(m, t_uint, cast(u64)i).value;
}
switch (builtin_id) {
case BuiltinProc_simd_reduce_add_bisect: op_code = is_float ? LLVMFAdd : LLVMAdd; break;
case BuiltinProc_simd_reduce_mul_bisect: op_code = is_float ? LLVMFMul : LLVMMul; break;
}
LLVMValueRef remaining = arg0.value;
i64 num_remaining = num_elems;
while (num_remaining > 1) {
num_remaining /= 2;
LLVMValueRef left_indices = LLVMConstVector(&indices[0], cast(unsigned)num_remaining);
LLVMValueRef left_value = LLVMBuildShuffleVector(p->builder, remaining, remaining, left_indices, "");
LLVMValueRef right_indices = LLVMConstVector(&indices[num_remaining], cast(unsigned)num_remaining);
LLVMValueRef right_value = LLVMBuildShuffleVector(p->builder, remaining, remaining, right_indices, "");
remaining = LLVMBuildBinOp(p->builder, op_code, left_value, right_value, "");
}
res.value = LLVMBuildExtractElement(p->builder, remaining, indices[0], "");
return res;
}
case BuiltinProc_simd_reduce_add_ordered:
case BuiltinProc_simd_reduce_mul_ordered:
{
@@ -1527,6 +1559,40 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
res.value = lb_call_intrinsic(p, name, args, cast(unsigned)args_count, types, gb_count_of(types));
return res;
}
case BuiltinProc_simd_reduce_add_pairs:
case BuiltinProc_simd_reduce_mul_pairs:
{
GB_ASSERT(arg0.type->kind == Type_SimdVector);
i64 num_elems = arg0.type->SimdVector.count;
LLVMValueRef *indices = gb_alloc_array(temporary_allocator(), LLVMValueRef, num_elems);
for (i64 i = 0; i < num_elems/2; i++) {
indices[i] = lb_const_int(m, t_uint, cast(u64)(2*i)).value;
indices[i+num_elems/2] = lb_const_int(m, t_uint, cast(u64)(2*i+1)).value;
}
switch (builtin_id) {
case BuiltinProc_simd_reduce_add_pairs: op_code = is_float ? LLVMFAdd : LLVMAdd; break;
case BuiltinProc_simd_reduce_mul_pairs: op_code = is_float ? LLVMFMul : LLVMMul; break;
}
LLVMValueRef remaining = arg0.value;
i64 num_remaining = num_elems;
while (num_remaining > 1) {
num_remaining /= 2;
LLVMValueRef left_indices = LLVMConstVector(&indices[0], cast(unsigned)num_remaining);
LLVMValueRef left_value = LLVMBuildShuffleVector(p->builder, remaining, remaining, left_indices, "");
LLVMValueRef right_indices = LLVMConstVector(&indices[num_elems/2], cast(unsigned)num_remaining);
LLVMValueRef right_value = LLVMBuildShuffleVector(p->builder, remaining, remaining, right_indices, "");
remaining = LLVMBuildBinOp(p->builder, op_code, left_value, right_value, "");
}
res.value = LLVMBuildExtractElement(p->builder, remaining, indices[0], "");
return res;
}
case BuiltinProc_simd_reduce_min:
case BuiltinProc_simd_reduce_max:
case BuiltinProc_simd_reduce_and: