aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_general.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm_backend_general.cpp')
-rw-r--r--src/llvm_backend_general.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp
index e3d30ccff..5b43a11ab 100644
--- a/src/llvm_backend_general.cpp
+++ b/src/llvm_backend_general.cpp
@@ -852,6 +852,12 @@ bool lb_is_type_proc_recursive(Type *t) {
void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
GB_ASSERT(value.value != nullptr);
Type *a = type_deref(ptr.type);
+
+ if (LLVMIsNull(value.value)) {
+ LLVMTypeRef src_t = LLVMGetElementType(LLVMTypeOf(ptr.value));
+ LLVMBuildStore(p->builder, LLVMConstNull(src_t), ptr.value);
+ return;
+ }
if (is_type_boolean(a)) {
// NOTE(bill): There are multiple sized booleans, thus force a conversion (if necessarily)
value = lb_emit_conv(p, value, a);
@@ -861,6 +867,20 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
GB_ASSERT_MSG(are_types_identical(ca, core_type(value.type)), "%s != %s", type_to_string(a), type_to_string(value.type));
}
+ enum {MAX_STORE_SIZE = 64};
+
+ if (LLVMIsALoadInst(value.value) && lb_sizeof(LLVMTypeOf(value.value)) > MAX_STORE_SIZE) {
+ LLVMValueRef dst_ptr = ptr.value;
+ LLVMValueRef src_ptr = LLVMGetOperand(value.value, 0);
+ src_ptr = LLVMBuildPointerCast(p->builder, src_ptr, LLVMTypeOf(dst_ptr), "");
+
+ LLVMBuildMemMove(p->builder,
+ dst_ptr, 1,
+ src_ptr, 1,
+ LLVMConstInt(LLVMInt64TypeInContext(p->module->ctx), lb_sizeof(LLVMTypeOf(value.value)), false));
+ return;
+ }
+
if (lb_is_type_proc_recursive(a)) {
// NOTE(bill, 2020-11-11): Because of certain LLVM rules, a procedure value may be
// stored as regular pointer with no procedure information