aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-09-24 10:08:25 +0100
committergingerBill <gingerBill@users.noreply.github.com>2025-09-24 10:08:25 +0100
commitbad495519b604081e34e69bbafd33c81f4d3fc1e (patch)
tree3a4dca074abb30f423f394ab9171c3001389c4f0
parent31f0aaa62f2799d7c5e38c10cabe034284ae8e5d (diff)
Improve const union attemps
-rw-r--r--src/llvm_backend_const.cpp26
-rw-r--r--src/llvm_backend_general.cpp22
2 files changed, 45 insertions, 3 deletions
diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp
index 781cc52b8..9069f3bdf 100644
--- a/src/llvm_backend_const.cpp
+++ b/src/llvm_backend_const.cpp
@@ -547,6 +547,9 @@ gb_internal LLVMValueRef lb_construct_const_union(lbModule *m, LLVMValueRef vari
return variant_value;
}
+ i64 block_size = bt->Union.variant_block_size;
+ i64 variant_size = type_size_of(variant_type);
+
LLVMTypeRef llvm_type = lb_type(m, union_type);
LLVMTypeRef llvm_variant_type = lb_type(m, variant_type);
@@ -564,7 +567,7 @@ gb_internal LLVMValueRef lb_construct_const_union(lbModule *m, LLVMValueRef vari
values[i++] = variant_value;
values[i++] = LLVMConstInt(tag_type, the_tag, false);
- i64 used_size = bt->Union.variant_block_size + lb_sizeof(tag_type);
+ i64 used_size = block_size + lb_sizeof(tag_type);
i64 padding = type_size_of(union_type) - used_size;
i64 align = type_align_of(union_type);
if (padding > 0) {
@@ -578,7 +581,7 @@ gb_internal LLVMValueRef lb_construct_const_union(lbModule *m, LLVMValueRef vari
LLVMTypeRef block_type = LLVMStructGetTypeAtIndex(llvm_type, 0);
LLVMTypeRef block_padding = nullptr;
- i64 block_padding_size = bt->Union.variant_block_size - type_size_of(variant_type);
+ i64 block_padding_size = block_size - variant_size;
if (block_padding_size > 0) {
block_padding = lb_type_padding_filler(m, block_padding_size, type_align_of(variant_type));
return nullptr;
@@ -586,7 +589,7 @@ gb_internal LLVMValueRef lb_construct_const_union(lbModule *m, LLVMValueRef vari
LLVMTypeRef tag_type = lb_type(m, union_tag_type(bt));
- i64 used_size = bt->Union.variant_block_size + lb_sizeof(tag_type);
+ i64 used_size = block_size + lb_sizeof(tag_type);
i64 padding = type_size_of(union_type) - used_size;
i64 align = type_align_of(union_type);
LLVMTypeRef padding_type = nullptr;
@@ -603,9 +606,26 @@ gb_internal LLVMValueRef lb_construct_const_union(lbModule *m, LLVMValueRef vari
if (lb_sizeof(llvm_variant_type) == 0) {
variant_value_wrapped = LLVMConstNull(block_type);
} else if (block_type != llvm_variant_type) {
+ if (block_size != variant_size) {
+ return nullptr;
+ }
+ if (LLVMGetTypeKind(block_type) == LLVMIntegerTypeKind) {
+ switch (LLVMGetTypeKind(llvm_variant_type)) {
+ case LLVMHalfTypeKind:
+ case LLVMFloatTypeKind:
+ case LLVMDoubleTypeKind:
+ variant_value_wrapped = LLVMConstBitCast(variant_value_wrapped, block_type);
+ goto assign_value_wrapped;
+ case LLVMPointerTypeKind:
+ variant_value_wrapped = LLVMConstPtrToInt(variant_value_wrapped, block_type);
+ goto assign_value_wrapped;
+ }
+ }
+
return nullptr;
}
+assign_value_wrapped:;
values[i++] = variant_value_wrapped;
if (block_padding_size > 0) {
diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp
index fc770102c..4c60d9f4c 100644
--- a/src/llvm_backend_general.cpp
+++ b/src/llvm_backend_general.cpp
@@ -1778,6 +1778,28 @@ gb_internal LLVMTypeRef lb_type_internal_union_block_type(lbModule *m, Type *typ
}
} end_rest_zero_except_one:;
+ // {
+ // LLVMTypeRef first_different = nullptr;
+ // for (isize i = 0; i < type->Union.variants.count; i++) {
+ // Type *t = type->Union.variants[i];
+ // if (type_size_of(t) == 0) {
+ // continue;
+ // }
+ // if (first_different == nullptr) {
+ // first_different = lb_type(m, base_type(t));
+ // } else {
+ // LLVMTypeRef llvm_t = lb_type(m, base_type(t));
+ // if (llvm_t != first_different) {
+ // goto end_rest_zero_except_one_llvm_like;
+ // }
+ // }
+ // }
+ // if (first_different != nullptr) {
+ // return first_different;
+ // }
+ // } end_rest_zero_except_one_llvm_like:;
+
+
return lb_type_padding_filler(m, block_size, align);
}