check packed load and set alignment on all loads, not just lb_emit_load

This commit is contained in:
Laytan Laats
2024-12-01 11:54:50 +11:00
committed by flysand7
parent 64fdf6e18f
commit 6e534c0e24
5 changed files with 45 additions and 26 deletions
+4 -5
View File
@@ -130,7 +130,7 @@ gb_internal lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x,
LLVMTypeRef vector_type = nullptr; LLVMTypeRef vector_type = nullptr;
if (op != Token_Not && lb_try_vector_cast(p->module, val, &vector_type)) { 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 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; LLVMValueRef opv = nullptr;
switch (op) { 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 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 rhs_vp = LLVMBuildPointerCast(p->builder, rhs_ptr.value, LLVMPointerType(vector_type, 0), "");
LLVMValueRef x = LLVMBuildLoad2(p->builder, vector_type, lhs_vp, ""); LLVMValueRef x = OdinLLVMBuildLoad(p, vector_type, lhs_vp);
LLVMValueRef y = LLVMBuildLoad2(p->builder, vector_type, rhs_vp, ""); LLVMValueRef y = OdinLLVMBuildLoad(p, vector_type, rhs_vp);
LLVMValueRef z = nullptr; LLVMValueRef z = nullptr;
if (is_type_float(integral_type)) { if (is_type_float(integral_type)) {
@@ -558,8 +558,7 @@ gb_internal LLVMValueRef lb_matrix_to_vector(lbProcedure *p, lbValue matrix) {
#if 1 #if 1
LLVMValueRef ptr = lb_address_from_load_or_generate_local(p, matrix).value; 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_ptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(total_matrix_type, 0), "");
LLVMValueRef matrix_vector = LLVMBuildLoad2(p->builder, total_matrix_type, matrix_vector_ptr, ""); LLVMValueRef matrix_vector = OdinLLVMBuildLoadAligned(p, total_matrix_type, matrix_vector_ptr, type_align_of(mt));
LLVMSetAlignment(matrix_vector, cast(unsigned)type_align_of(mt));
return matrix_vector; return matrix_vector;
#else #else
LLVMValueRef matrix_vector = LLVMBuildBitCast(p->builder, matrix.value, total_matrix_type, ""); LLVMValueRef matrix_vector = LLVMBuildBitCast(p->builder, matrix.value, total_matrix_type, "");
+35 -14
View File
@@ -774,6 +774,36 @@ gb_internal bool lb_try_vector_cast(lbModule *m, lbValue ptr, LLVMTypeRef *vecto
return false; 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) { gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
if (addr.addr.value == nullptr) { if (addr.addr.value == nullptr) {
return; return;
@@ -1119,7 +1149,7 @@ gb_internal lbValue lb_emit_load(lbProcedure *p, lbValue value) {
Type *vt = base_type(value.type); Type *vt = base_type(value.type);
GB_ASSERT(vt->kind == Type_MultiPointer); GB_ASSERT(vt->kind == Type_MultiPointer);
Type *t = vt->MultiPointer.elem; 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}; return lbValue{v, t};
} else if (is_type_soa_pointer(value.type)) { } else if (is_type_soa_pointer(value.type)) {
lbValue ptr = lb_emit_struct_ev(p, value, 0); 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)); GB_ASSERT_MSG(is_type_pointer(value.type), "%s", type_to_string(value.type));
Type *t = type_deref(value.type); Type *t = type_deref(value.type);
LLVMValueRef v = LLVMBuildLoad2(p->builder, lb_type(p->module, t), value.value, ""); LLVMValueRef v = OdinLLVMBuildLoad(p, 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);
}
}
return lbValue{v, t}; return lbValue{v, t};
} }
@@ -1413,7 +1434,7 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
LLVMTypeRef vector_type = nullptr; LLVMTypeRef vector_type = nullptr;
if (lb_try_vector_cast(p->module, addr.addr, &vector_type)) { if (lb_try_vector_cast(p->module, addr.addr, &vector_type)) {
LLVMValueRef vp = LLVMBuildPointerCast(p->builder, addr.addr.value, LLVMPointerType(vector_type, 0), ""); 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] = {}; LLVMValueRef scalars[4] = {};
for (u8 i = 0; i < addr.swizzle.count; i++) { for (u8 i = 0; i < addr.swizzle.count; i++) {
scalars[i] = LLVMConstInt(lb_type(p->module, t_u32), addr.swizzle.indices[i], false); 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)) { if (LLVMIsALoadInst(val) && (src_size >= dst_size && src_align >= dst_align)) {
LLVMValueRef val_ptr = LLVMGetOperand(val, 0); LLVMValueRef val_ptr = LLVMGetOperand(val, 0);
val_ptr = LLVMBuildPointerCast(p->builder, val_ptr, LLVMPointerType(dst_type, 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)); // 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), ""); LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), "");
LLVMBuildStore(p->builder, val, nptr); LLVMBuildStore(p->builder, val, nptr);
return LLVMBuildLoad2(p->builder, dst_type, ptr, ""); return OdinLLVMBuildLoad(p, dst_type, ptr);
} }
} }
+2 -3
View File
@@ -2568,7 +2568,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
case BuiltinProc_atomic_load_explicit: { case BuiltinProc_atomic_load_explicit: {
lbValue dst = lb_build_expr(p, ce->args[0]); 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) { switch (id) {
case BuiltinProc_non_temporal_load: 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)) { if (is_type_simd_vector(t)) {
lbValue res = {}; lbValue res = {};
res.type = t; res.type = t;
res.value = LLVMBuildLoad2(p->builder, lb_type(p->module, t), src.value, ""); res.value = OdinLLVMBuildLoadAligned(p, lb_type(p->module, t), src.value, 1);
LLVMSetAlignment(res.value, 1);
return res; return res;
} else { } else {
lbAddr dst = lb_add_local_generated(p, t, false); lbAddr dst = lb_add_local_generated(p, t, false);
+1 -1
View File
@@ -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 ptr = p->temp_callee_return_struct_memory;
LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), ""); LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), "");
LLVMBuildStore(p->builder, ret_val, nptr); LLVMBuildStore(p->builder, ret_val, nptr);
ret_val = LLVMBuildLoad2(p->builder, ret_type, ptr, ""); ret_val = OdinLLVMBuildLoad(p, ret_type, ptr);
} else { } else {
ret_val = OdinLLVMBuildTransmute(p, ret_val, ret_type); ret_val = OdinLLVMBuildTransmute(p, ret_val, ret_type);
} }
+1 -1
View File
@@ -269,7 +269,7 @@ gb_internal lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
if (lb_try_update_alignment(ptr, align)) { if (lb_try_update_alignment(ptr, align)) {
LLVMTypeRef result_type = lb_type(p->module, t); LLVMTypeRef result_type = lb_type(p->module, t);
res.value = LLVMBuildPointerCast(p->builder, ptr.value, LLVMPointerType(result_type, 0), ""); 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; return res;
} }
lbAddr addr = lb_add_local_generated(p, t, false); lbAddr addr = lb_add_local_generated(p, t, false);