diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 8967a4e03..de7cadaf3 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -130,7 +130,7 @@ gb_internal lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, LLVMTypeRef vector_type = nullptr; if (op != Token_Not && lb_try_vector_cast(p->module, val, &vector_type)) { LLVMValueRef vp = LLVMBuildPointerCast(p->builder, val.value, LLVMPointerType(vector_type, 0), ""); - LLVMValueRef v = LLVMBuildLoad2(p->builder, vector_type, vp, ""); + LLVMValueRef v = OdinLLVMBuildLoad(p, vector_type, vp); LLVMValueRef opv = nullptr; switch (op) { @@ -324,8 +324,8 @@ gb_internal bool lb_try_direct_vector_arith(lbProcedure *p, TokenKind op, lbValu LLVMValueRef lhs_vp = LLVMBuildPointerCast(p->builder, lhs_ptr.value, LLVMPointerType(vector_type, 0), ""); LLVMValueRef rhs_vp = LLVMBuildPointerCast(p->builder, rhs_ptr.value, LLVMPointerType(vector_type, 0), ""); - LLVMValueRef x = LLVMBuildLoad2(p->builder, vector_type, lhs_vp, ""); - LLVMValueRef y = LLVMBuildLoad2(p->builder, vector_type, rhs_vp, ""); + LLVMValueRef x = OdinLLVMBuildLoad(p, vector_type, lhs_vp); + LLVMValueRef y = OdinLLVMBuildLoad(p, vector_type, rhs_vp); LLVMValueRef z = nullptr; if (is_type_float(integral_type)) { @@ -551,15 +551,14 @@ gb_internal LLVMValueRef lb_matrix_to_vector(lbProcedure *p, lbValue matrix) { Type *mt = base_type(matrix.type); GB_ASSERT(mt->kind == Type_Matrix); LLVMTypeRef elem_type = lb_type(p->module, mt->Matrix.elem); - + unsigned total_count = cast(unsigned)matrix_type_total_internal_elems(mt); LLVMTypeRef total_matrix_type = LLVMVectorType(elem_type, total_count); - + #if 1 LLVMValueRef ptr = lb_address_from_load_or_generate_local(p, matrix).value; LLVMValueRef matrix_vector_ptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(total_matrix_type, 0), ""); - LLVMValueRef matrix_vector = LLVMBuildLoad2(p->builder, total_matrix_type, matrix_vector_ptr, ""); - LLVMSetAlignment(matrix_vector, cast(unsigned)type_align_of(mt)); + LLVMValueRef matrix_vector = OdinLLVMBuildLoadAligned(p, total_matrix_type, matrix_vector_ptr, type_align_of(mt)); return matrix_vector; #else LLVMValueRef matrix_vector = LLVMBuildBitCast(p->builder, matrix.value, total_matrix_type, ""); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 43c9f738a..686724f6a 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -774,6 +774,36 @@ gb_internal bool lb_try_vector_cast(lbModule *m, lbValue ptr, LLVMTypeRef *vecto return false; } +gb_internal LLVMValueRef OdinLLVMBuildLoad(lbProcedure *p, LLVMTypeRef type, LLVMValueRef value) { + LLVMValueRef result = LLVMBuildLoad2(p->builder, type, value, ""); + + // If it is not an instruction it isn't a GEP, so we don't need to track alignment in the metadata, + // which is not possible anyway (only LLVM instructions can have metadata). + if (LLVMIsAInstruction(value)) { + u64 is_packed = lb_get_metadata_custom_u64(p->module, value, ODIN_METADATA_IS_PACKED); + if (is_packed != 0) { + LLVMSetAlignment(result, 1); + } + } + + return result; +} + +gb_internal LLVMValueRef OdinLLVMBuildLoadAligned(lbProcedure *p, LLVMTypeRef type, LLVMValueRef value, i64 alignment) { + LLVMValueRef result = LLVMBuildLoad2(p->builder, type, value, ""); + + LLVMSetAlignment(result, cast(unsigned)alignment); + + if (LLVMIsAInstruction(value)) { + u64 is_packed = lb_get_metadata_custom_u64(p->module, value, ODIN_METADATA_IS_PACKED); + if (is_packed != 0) { + LLVMSetAlignment(result, 1); + } + } + + return result; +} + gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { if (addr.addr.value == nullptr) { return; @@ -1119,7 +1149,7 @@ gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue value) { Type *vt = base_type(value.type); GB_ASSERT(vt->kind == Type_MultiPointer); Type *t = vt->MultiPointer.elem; - LLVMValueRef v = LLVMBuildLoad2(p->builder, lb_type(p->module, t), value.value, ""); + LLVMValueRef v = OdinLLVMBuildLoad(p, lb_type(p->module, t), value.value); return lbValue{v, t}; } else if (is_type_soa_pointer(value.type)) { lbValue ptr = lb_emit_struct_ev(p, value, 0); @@ -1130,16 +1160,7 @@ gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue value) { GB_ASSERT_MSG(is_type_pointer(value.type), "%s", type_to_string(value.type)); Type *t = type_deref(value.type); - LLVMValueRef v = LLVMBuildLoad2(p->builder, lb_type(p->module, t), value.value, ""); - - // If it is not an instruction it isn't a GEP, so we don't need to track alignment in the metadata, - // which is not possible anyway (only LLVM instructions can have metadata). - if (LLVMIsAInstruction(value.value)) { - u64 is_packed = lb_get_metadata_custom_u64(p->module, value.value, ODIN_METADATA_IS_PACKED); - if (is_packed != 0) { - LLVMSetAlignment(v, 1); - } - } + LLVMValueRef v = OdinLLVMBuildLoad(p, lb_type(p->module, t), value.value); return lbValue{v, t}; } @@ -1413,7 +1434,7 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) { LLVMTypeRef vector_type = nullptr; if (lb_try_vector_cast(p->module, addr.addr, &vector_type)) { LLVMValueRef vp = LLVMBuildPointerCast(p->builder, addr.addr.value, LLVMPointerType(vector_type, 0), ""); - LLVMValueRef v = LLVMBuildLoad2(p->builder, vector_type, vp, ""); + LLVMValueRef v = OdinLLVMBuildLoad(p, vector_type, vp); LLVMValueRef scalars[4] = {}; for (u8 i = 0; i < addr.swizzle.count; i++) { scalars[i] = LLVMConstInt(lb_type(p->module, t_u32), addr.swizzle.indices[i], false); @@ -2710,7 +2731,7 @@ general_end:; if (LLVMIsALoadInst(val) && (src_size >= dst_size && src_align >= dst_align)) { LLVMValueRef val_ptr = LLVMGetOperand(val, 0); val_ptr = LLVMBuildPointerCast(p->builder, val_ptr, LLVMPointerType(dst_type, 0), ""); - LLVMValueRef loaded_val = LLVMBuildLoad2(p->builder, dst_type, val_ptr, ""); + LLVMValueRef loaded_val = OdinLLVMBuildLoad(p, dst_type, val_ptr); // LLVMSetAlignment(loaded_val, gb_min(src_align, dst_align)); @@ -2726,7 +2747,7 @@ general_end:; LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), ""); LLVMBuildStore(p->builder, val, nptr); - return LLVMBuildLoad2(p->builder, dst_type, ptr, ""); + return OdinLLVMBuildLoad(p, dst_type, ptr); } } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index d84599eb0..5aee5b639 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -2568,7 +2568,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu case BuiltinProc_atomic_load_explicit: { lbValue dst = lb_build_expr(p, ce->args[0]); - LLVMValueRef instr = LLVMBuildLoad2(p->builder, lb_type(p->module, type_deref(dst.type)), dst.value, ""); + LLVMValueRef instr = OdinLLVMBuildLoad(p, lb_type(p->module, type_deref(dst.type)), dst.value); switch (id) { case BuiltinProc_non_temporal_load: { @@ -2621,8 +2621,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu if (is_type_simd_vector(t)) { lbValue res = {}; res.type = t; - res.value = LLVMBuildLoad2(p->builder, lb_type(p->module, t), src.value, ""); - LLVMSetAlignment(res.value, 1); + res.value = OdinLLVMBuildLoadAligned(p, lb_type(p->module, t), src.value, 1); return res; } else { lbAddr dst = lb_add_local_generated(p, t, false); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index df3d4bc03..288e7206a 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -2001,7 +2001,7 @@ gb_internal void lb_build_return_stmt_internal(lbProcedure *p, lbValue res) { LLVMValueRef ptr = p->temp_callee_return_struct_memory; LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), ""); LLVMBuildStore(p->builder, ret_val, nptr); - ret_val = LLVMBuildLoad2(p->builder, ret_type, ptr, ""); + ret_val = OdinLLVMBuildLoad(p, ret_type, ptr); } else { ret_val = OdinLLVMBuildTransmute(p, ret_val, ret_type); } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index f63c42ab9..6367d0118 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -269,7 +269,7 @@ gb_internal lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) { if (lb_try_update_alignment(ptr, align)) { LLVMTypeRef result_type = lb_type(p->module, t); res.value = LLVMBuildPointerCast(p->builder, ptr.value, LLVMPointerType(result_type, 0), ""); - res.value = LLVMBuildLoad2(p->builder, result_type, res.value, ""); + res.value = OdinLLVMBuildLoad(p, result_type, res.value); return res; } lbAddr addr = lb_add_local_generated(p, t, false);