Fix constant union stuff against tests

This commit is contained in:
gingerBill
2026-06-29 13:00:44 +01:00
parent 2f3174fe10
commit b9a9846b7c
2 changed files with 22 additions and 45 deletions

View File

@@ -117,33 +117,7 @@ gb_internal LLVMValueRef llvm_const_cast(lbModule *m, LLVMValueRef val, LLVMType
unsigned dst_n = LLVMCountStructElementTypes(dst);
if (src_n != dst_n) goto failure;
bool skip_cast = true;
for (unsigned i = 0; i < dst_n; i++) {
LLVMTypeKind dt = LLVMGetTypeKind(LLVMStructGetTypeAtIndex(dst, i));
LLVMTypeKind st = LLVMGetTypeKind(LLVMStructGetTypeAtIndex(src, i));
if (dt != st) {
skip_cast = false;
}
if (dt == LLVMIntegerTypeKind) {
continue;
}
if (dt != LLVMArrayTypeKind) {
skip_cast = false;
break;
}
LLVMValueRef field_val = llvm_const_extract_value(m, val, i);
if (field_val == nullptr) goto failure;
LLVMTypeRef dst_elem_ty = LLVMStructGetTypeAtIndex(dst, i);
LLVMTypeRef src_elem_ty = LLVMTypeOf(field_val);
if (lb_sizeof(dst_elem_ty) > lb_sizeof(src_elem_ty)) {
skip_cast = true;
continue;
}
}
if (skip_cast) {
if (LLVM_VERSION_MAJOR > 14) {
return val;
}
@@ -1075,7 +1049,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty
values[value_count++] = llvm_const_pad_to_size(m, cv.value, block_type);
#else
values[value_count++] = cv.value;
{
if (block_size != type_size_of(variant_type)) {
LLVMTypeRef padding_type = lb_type_padding_filler(m, block_size - type_size_of(variant_type), 1);
values[value_count++] = LLVMConstNull(padding_type);
}
@@ -1095,6 +1069,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty
}
res.value = LLVMConstStructInContext(m->ctx, values, value_count, true);
gb_printf_err("%s\n", LLVMPrintValueToString(res.value));
return res;
}

View File

@@ -1647,22 +1647,23 @@ gb_internal lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
LLVMTypeRef uvt = llvm_addr_type(p->module, u);
unsigned element_count = LLVMCountStructElementTypes(uvt);
if (LLVM_VERSION_MAJOR == 14 || bt->Union.variants.count == 1) {
// if (LLVM_VERSION_MAJOR == 14 || bt->Union.variants.count == 1) {
GB_ASSERT_MSG(element_count >= 2, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
} else {
GB_ASSERT_MSG(element_count >= 3, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
}
// } else {
// GB_ASSERT_MSG(element_count >= 3, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
// }
LLVMValueRef ptr = u.value;
ptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(uvt, 0), "");
lbValue tag_ptr = {};
if (LLVM_VERSION_MAJOR == 14 || bt->Union.variants.count == 1) {
// if (LLVM_VERSION_MAJOR == 14 || bt->Union.variants.count == 1) {
tag_ptr.value = LLVMBuildStructGEP2(p->builder, uvt, ptr, 1, "");
} else {
tag_ptr.value = LLVMBuildStructGEP2(p->builder, uvt, ptr, 2, "");
}
// } else {
// tag_ptr.value = LLVMBuildStructGEP2(p->builder, uvt, ptr, 2, "");
// }
tag_ptr.type = alloc_type_pointer(tag_type);
tag_ptr.value = LLVMBuildPointerCast(p->builder, tag_ptr.value, lb_type(p->module, tag_ptr.type), "");
return tag_ptr;
}
@@ -2412,8 +2413,9 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
i64 full_type_align = type_align_of(type);
GB_ASSERT(full_type_size % full_type_align == 0);
if (type->Struct.is_raw_union) {
bool requires_packing = type->Struct.is_packed;
if (type->Struct.is_raw_union) {
lbStructFieldRemapping field_remapping = {};
slice_init(&field_remapping, permanent_allocator(), 1);
@@ -2421,7 +2423,7 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
fields[0] = lb_type_padding_filler(m, full_type_size, full_type_align);
field_remapping[0] = 0;
LLVMTypeRef struct_type = LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false);
LLVMTypeRef struct_type = LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), requires_packing);
map_set(&m->struct_field_remapping, cast(void *)struct_type, field_remapping);
map_set(&m->struct_field_remapping, cast(void *)type, field_remapping);
return struct_type;
@@ -2441,7 +2443,6 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
}
i64 prev_offset = 0;
bool requires_packing = type->Struct.is_packed;
for (i32 field_index : struct_fields_index_by_increasing_offset(temporary_allocator(), type)) {
Entity *field = type->Struct.fields[field_index];
i64 offset = type->Struct.offsets[field_index];
@@ -2529,12 +2530,6 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
LLVMTypeRef tag_type = lb_type(m, union_tag_type(type));
array_add(&fields, block_type);
#if LLVM_VERSION_MAJOR > 14
{ // NOTE(bill): always add a zero-byte pad to make inline constant unions work
LLVMTypeRef padding_type = lb_type_padding_filler(m, 0, 1);
array_add(&fields, padding_type);
}
#endif
array_add(&fields, tag_type);
i64 used_size = lb_sizeof(block_type) + lb_sizeof(tag_type);
i64 padding = size - used_size;
@@ -2655,6 +2650,13 @@ gb_internal LLVMTypeRef lb_type(lbModule *m, Type *type) {
m->internal_type_level += 1;
llvm_type = lb_type_internal(m, type);
m->internal_type_level -= 1;
// {
// i64 tsz = type_size_of(type);
// i64 lsz = lb_sizeof(llvm_type);
// GB_ASSERT_MSG(tsz == lsz, "%s %lld vs %lld %s", type_to_string(type), cast(long long)tsz, cast(long long)lsz, LLVMPrintTypeToString(llvm_type));
// }
if (m->internal_type_level == 0) {
map_set(&m->types, type, llvm_type);
}