diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index a314791c9..be036f553 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -911,6 +911,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty bool is_local = cc.allow_local && m->curr_procedure != nullptr; + if (is_type_union(type) && is_type_union_constantable(type)) { Type *bt = base_type(type); GB_ASSERT(bt->kind == Type_Union); @@ -1001,16 +1002,16 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty LLVMValueRef values[4] = {}; unsigned value_count = 0; - #if LLVM_VERSION_MAJOR == 14 + #if LLVM_VERSION_MAJOR == 14 LLVMTypeRef block_type = lb_type_internal_union_block_type(m, bt); values[value_count++] = llvm_const_pad_to_size(m, cv.value, block_type); - #else + #else values[value_count++] = cv.value; - if (type_size_of(variant_type) != block_size) { + { LLVMTypeRef padding_type = lb_type_padding_filler(m, block_size - type_size_of(variant_type), 1); values[value_count++] = LLVMConstNull(padding_type); } - #endif + #endif Type *tag_type = union_tag_type(bt); LLVMTypeRef llvm_tag_type = lb_type(m, tag_type); @@ -1026,6 +1027,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty } res.value = LLVMConstStructInContext(m->ctx, values, value_count, true); + return res; } } @@ -2103,7 +2105,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, Ty } } if (is_constant) { - LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, tav.type, cc).value; + LLVMValueRef elem_value = lb_const_value(m, cv_type, tav.value, tav.type, cc).value; if (LLVMIsConstant(elem_value) && LLVMIsConstant(values[index])) { values[index] = llvm_const_insert_value(m, values[index], elem_value, idx_list, idx_list_len); } else if (is_local) { diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index d0249172c..45380e7b6 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2498,7 +2498,7 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false); } - auto fields = array_make(temporary_allocator(), 0, 3); + auto fields = array_make(temporary_allocator(), 0, 4); if (is_type_union_maybe_pointer(type)) { LLVMTypeRef variant = lb_type(m, type->Union.variants[0]); array_add(&fields, variant); @@ -2519,6 +2519,12 @@ 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; @@ -2528,7 +2534,7 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { } } - return LLVMStructTypeInContext(ctx, fields.data, cast(unsigned)fields.count, false); + return LLVMStructTypeInContext(ctx, fields.data, cast(unsigned)fields.count, /*packed*/true); } break;