diff options
| author | gingerBill <bill@gingerbill.org> | 2022-05-26 14:51:50 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-05-26 14:51:50 +0100 |
| commit | f308f37ba112ca361715e470d513749236da026d (patch) | |
| tree | 1dd9053ed9b29b018b04ee244dd07422db1be39f /src | |
| parent | c2610cb75ed81d687a4e6962283f498e94773706 (diff) | |
Remove need for `simd.splat`
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.cpp | 8 | ||||
| -rw-r--r-- | src/llvm_backend_const.cpp | 26 | ||||
| -rw-r--r-- | src/llvm_backend_expr.cpp | 72 |
3 files changed, 74 insertions, 32 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp index fcd7818bc..2a3b5bf02 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -2713,6 +2713,14 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) { return check_is_castable_to(c, &x, elem_dst); } + if (is_type_simd_vector(dst)) { + Type *elem = base_array_type(dst); + if (check_is_castable_to(c, operand, elem)) { + return true; + } + } + + return false; } diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 3a3067dbc..bd76400de 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -495,9 +495,9 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc res.value = data; return res; } else if (is_type_array(type) && - value.kind != ExactValue_Invalid && - value.kind != ExactValue_String && - value.kind != ExactValue_Compound) { + value.kind != ExactValue_Invalid && + value.kind != ExactValue_String && + value.kind != ExactValue_Compound) { i64 count = type->Array.count; Type *elem = type->Array.elem; @@ -513,8 +513,8 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc res.value = llvm_const_array(lb_type(m, elem), elems, cast(unsigned)count); return res; } else if (is_type_matrix(type) && - value.kind != ExactValue_Invalid && - value.kind != ExactValue_Compound) { + value.kind != ExactValue_Invalid && + value.kind != ExactValue_Compound) { i64 row = type->Matrix.row_count; i64 column = type->Matrix.column_count; GB_ASSERT(row == column); @@ -537,6 +537,22 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc res.value = LLVMConstArray(lb_type(m, elem), elems, cast(unsigned)total_elem_count); return res; + } else if (is_type_simd_vector(type) && + value.kind != ExactValue_Invalid && + value.kind != ExactValue_Compound) { + i64 count = type->SimdVector.count; + Type *elem = type->SimdVector.elem; + + lbValue single_elem = lb_const_value(m, elem, value, allow_local); + single_elem.value = llvm_const_cast(single_elem.value, lb_type(m, elem)); + + LLVMValueRef *elems = gb_alloc_array(permanent_allocator(), LLVMValueRef, count); + for (i64 i = 0; i < count; i++) { + elems[i] = single_elem.value; + } + + res.value = LLVMConstVector(elems, cast(unsigned)count); + return res; } switch (value.kind) { diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 426becc1c..10c337650 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1820,41 +1820,59 @@ lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { return res; } - if (is_type_simd_vector(src) && is_type_simd_vector(dst)) { - Type *src_elem = core_array_type(src); - Type *dst_elem = core_array_type(dst); + if (is_type_simd_vector(dst)) { + Type *et = base_array_type(dst); + if (is_type_simd_vector(src)) { + Type *src_elem = core_array_type(src); + Type *dst_elem = core_array_type(dst); - GB_ASSERT(src->SimdVector.count == dst->SimdVector.count); + GB_ASSERT(src->SimdVector.count == dst->SimdVector.count); - lbValue res = {}; - res.type = t; - if (are_types_identical(src_elem, dst_elem)) { - res.value = value.value; - } else if (is_type_float(src_elem) && is_type_integer(dst_elem)) { - if (is_type_unsigned(dst_elem)) { - res.value = LLVMBuildFPToUI(p->builder, value.value, lb_type(m, t), ""); - } else { - res.value = LLVMBuildFPToSI(p->builder, value.value, lb_type(m, t), ""); - } - } else if (is_type_integer(src_elem) && is_type_float(dst_elem)) { - if (is_type_unsigned(src_elem)) { - res.value = LLVMBuildUIToFP(p->builder, value.value, lb_type(m, t), ""); + lbValue res = {}; + res.type = t; + if (are_types_identical(src_elem, dst_elem)) { + res.value = value.value; + } else if (is_type_float(src_elem) && is_type_integer(dst_elem)) { + if (is_type_unsigned(dst_elem)) { + res.value = LLVMBuildFPToUI(p->builder, value.value, lb_type(m, t), ""); + } else { + res.value = LLVMBuildFPToSI(p->builder, value.value, lb_type(m, t), ""); + } + } else if (is_type_integer(src_elem) && is_type_float(dst_elem)) { + if (is_type_unsigned(src_elem)) { + res.value = LLVMBuildUIToFP(p->builder, value.value, lb_type(m, t), ""); + } else { + res.value = LLVMBuildSIToFP(p->builder, value.value, lb_type(m, t), ""); + } + } else if ((is_type_integer(src_elem) || is_type_boolean(src_elem)) && is_type_integer(dst_elem)) { + res.value = LLVMBuildIntCast2(p->builder, value.value, lb_type(m, t), !is_type_unsigned(src_elem), ""); + } else if (is_type_float(src_elem) && is_type_float(dst_elem)) { + res.value = LLVMBuildFPCast(p->builder, value.value, lb_type(m, t), ""); + } else if (is_type_integer(src_elem) && is_type_boolean(dst_elem)) { + LLVMValueRef i1vector = LLVMBuildICmp(p->builder, LLVMIntNE, value.value, LLVMConstNull(LLVMTypeOf(value.value)), ""); + res.value = LLVMBuildIntCast2(p->builder, i1vector, lb_type(m, t), !is_type_unsigned(src_elem), ""); } else { - res.value = LLVMBuildSIToFP(p->builder, value.value, lb_type(m, t), ""); + GB_PANIC("Unhandled simd vector conversion: %s -> %s", type_to_string(src), type_to_string(dst)); } - } else if ((is_type_integer(src_elem) || is_type_boolean(src_elem)) && is_type_integer(dst_elem)) { - res.value = LLVMBuildIntCast2(p->builder, value.value, lb_type(m, t), !is_type_unsigned(src_elem), ""); - } else if (is_type_float(src_elem) && is_type_float(dst_elem)) { - res.value = LLVMBuildFPCast(p->builder, value.value, lb_type(m, t), ""); - } else if (is_type_integer(src_elem) && is_type_boolean(dst_elem)) { - LLVMValueRef i1vector = LLVMBuildICmp(p->builder, LLVMIntNE, value.value, LLVMConstNull(LLVMTypeOf(value.value)), ""); - res.value = LLVMBuildIntCast2(p->builder, i1vector, lb_type(m, t), !is_type_unsigned(src_elem), ""); + return res; } else { - GB_PANIC("Unhandled simd vector conversion: %s -> %s", type_to_string(src), type_to_string(dst)); + i64 count = get_array_type_count(dst); + LLVMTypeRef vt = lb_type(m, t); + LLVMTypeRef llvm_u32 = lb_type(m, t_u32); + LLVMValueRef elem = lb_emit_conv(p, value, et).value; + LLVMValueRef vector = LLVMConstNull(vt); + for (i64 i = 0; i < count; i++) { + LLVMValueRef idx = LLVMConstInt(llvm_u32, i, false); + vector = LLVMBuildInsertElement(p->builder, vector, elem, idx, ""); + } + lbValue res = {}; + res.type = t; + res.value = vector; + return res; } - return res; } + // Pointer <-> uintptr if (is_type_pointer(src) && is_type_uintptr(dst)) { lbValue res = {}; |