authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-13 12:44:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-13 12:44:30-04:00
log12ff91c1c99da11dcaab1e4a1adb6a6917ef4881
tree7653b6a83dc5cd5861173445cb30726248506be6
parent8a9289996ab8ed7da2f7e0c6df9fe2bd9a3e0b7b
signature Commit is signed but in an unrecognized format.

alignment of structs no longer depends on LLVM

fixes async function tests in optimized builds

7 files changed, 204 insertions(+), 59 deletions(-)

BRANCH_TODO+1
...@@ -1,3 +1,4 @@...@@ -1,3 +1,4 @@
1 * alignment of variables not being respected in async functions
1 * for loops need to spill the index. other payload captures probably also need to spill2 * for loops need to spill the index. other payload captures probably also need to spill
2 * compile error (instead of crashing) for trying to get @Frame of generic function3 * compile error (instead of crashing) for trying to get @Frame of generic function
3 * compile error (instead of crashing) for trying to async call and passing @Frame of wrong function4 * compile error (instead of crashing) for trying to async call and passing @Frame of wrong function
src/all_types.hpp+3
...@@ -1148,6 +1148,8 @@ struct ZigTypeOptional {...@@ -1148,6 +1148,8 @@ struct ZigTypeOptional {
1148struct ZigTypeErrorUnion {1148struct ZigTypeErrorUnion {
1149 ZigType *err_set_type;1149 ZigType *err_set_type;
1150 ZigType *payload_type;1150 ZigType *payload_type;
1151 size_t pad_bytes;
1152 LLVMTypeRef pad_llvm_type;
1151};1153};
11521154
1153struct ZigTypeErrorSet {1155struct ZigTypeErrorSet {
...@@ -3564,6 +3566,7 @@ struct IrInstructionAllocaGen {...@@ -3564,6 +3566,7 @@ struct IrInstructionAllocaGen {
35643566
3565 uint32_t align;3567 uint32_t align;
3566 const char *name_hint;3568 const char *name_hint;
3569 size_t field_index;
3567};3570};
35683571
3569struct IrInstructionEndExpr {3572struct IrInstructionEndExpr {
src/analyze.cpp+101-32
...@@ -630,6 +630,7 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa...@@ -630,6 +630,7 @@ ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payloa
630 size_t field2_offset = next_field_offset(0, entry->abi_align, field_sizes[0], field_aligns[1]);630 size_t field2_offset = next_field_offset(0, entry->abi_align, field_sizes[0], field_aligns[1]);
631 entry->abi_size = next_field_offset(field2_offset, entry->abi_align, field_sizes[1], entry->abi_align);631 entry->abi_size = next_field_offset(field2_offset, entry->abi_align, field_sizes[1], entry->abi_align);
632 entry->size_in_bits = entry->abi_size * 8;632 entry->size_in_bits = entry->abi_size * 8;
633 entry->data.error_union.pad_bytes = entry->abi_size - (field2_offset + field_sizes[1]);
633 }634 }
634635
635 g->type_table.put(type_id, entry);636 g->type_table.put(type_id, entry);
...@@ -1499,7 +1500,7 @@ bool type_is_invalid(ZigType *type_entry) {...@@ -1499,7 +1500,7 @@ bool type_is_invalid(ZigType *type_entry) {
1499}1500}
15001501
15011502
1502ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],1503static ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
1503 ZigType *field_types[], size_t field_count, unsigned min_abi_align)1504 ZigType *field_types[], size_t field_count, unsigned min_abi_align)
1504{1505{
1505 ZigType *struct_type = new_type_table_entry(ZigTypeIdStruct);1506 ZigType *struct_type = new_type_table_entry(ZigTypeIdStruct);
...@@ -1524,10 +1525,6 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na...@@ -1524,10 +1525,6 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na
1524 if (field->type_entry->abi_align > abi_align) {1525 if (field->type_entry->abi_align > abi_align) {
1525 abi_align = field->type_entry->abi_align;1526 abi_align = field->type_entry->abi_align;
1526 }1527 }
1527 field->gen_index = struct_type->data.structure.gen_field_count;
1528 struct_type->data.structure.gen_field_count += 1;
1529 } else {
1530 field->gen_index = SIZE_MAX;
1531 }1528 }
15321529
1533 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);1530 auto prev_entry = struct_type->data.structure.fields_by_name.put_unique(field->name, field);
...@@ -1537,14 +1534,16 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na...@@ -1537,14 +1534,16 @@ ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_na
1537 size_t next_offset = 0;1534 size_t next_offset = 0;
1538 for (size_t i = 0; i < field_count; i += 1) {1535 for (size_t i = 0; i < field_count; i += 1) {
1539 TypeStructField *field = &struct_type->data.structure.fields[i];1536 TypeStructField *field = &struct_type->data.structure.fields[i];
1540 if (field->gen_index == SIZE_MAX)1537 if (!type_has_bits(field->type_entry))
1541 continue;1538 continue;
1539
1542 field->offset = next_offset;1540 field->offset = next_offset;
1541
1542 // find the next non-zero-byte field for offset calculations
1543 size_t next_src_field_index = i + 1;1543 size_t next_src_field_index = i + 1;
1544 for (; next_src_field_index < field_count; next_src_field_index += 1) {1544 for (; next_src_field_index < field_count; next_src_field_index += 1) {
1545 if (struct_type->data.structure.fields[next_src_field_index].gen_index != SIZE_MAX) {1545 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
1546 break;1546 break;
1547 }
1548 }1547 }
1549 size_t next_abi_align = (next_src_field_index == field_count) ?1548 size_t next_abi_align = (next_src_field_index == field_count) ?
1550 abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;1549 abi_align : struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
...@@ -5304,6 +5303,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -5304,6 +5303,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
53045303
5305 for (size_t alloca_i = 0; alloca_i < fn->alloca_gen_list.length; alloca_i += 1) {5304 for (size_t alloca_i = 0; alloca_i < fn->alloca_gen_list.length; alloca_i += 1) {
5306 IrInstructionAllocaGen *instruction = fn->alloca_gen_list.at(alloca_i);5305 IrInstructionAllocaGen *instruction = fn->alloca_gen_list.at(alloca_i);
5306 instruction->field_index = SIZE_MAX;
5307 ZigType *ptr_type = instruction->base.value.type;5307 ZigType *ptr_type = instruction->base.value.type;
5308 assert(ptr_type->id == ZigTypeIdPointer);5308 assert(ptr_type->id == ZigTypeIdPointer);
5309 ZigType *child_type = ptr_type->data.pointer.child_type;5309 ZigType *child_type = ptr_type->data.pointer.child_type;
...@@ -5327,6 +5327,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {...@@ -5327,6 +5327,7 @@ static Error resolve_coro_frame(CodeGen *g, ZigType *frame_type) {
5327 } else {5327 } else {
5328 name = buf_ptr(buf_sprintf("%s.%" ZIG_PRI_usize, instruction->name_hint, alloca_i));5328 name = buf_ptr(buf_sprintf("%s.%" ZIG_PRI_usize, instruction->name_hint, alloca_i));
5329 }5329 }
5330 instruction->field_index = field_types.length;
5330 field_names.append(name);5331 field_names.append(name);
5331 field_types.append(child_type);5332 field_types.append(child_type);
5332 }5333 }
...@@ -5949,6 +5950,15 @@ ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {...@@ -5949,6 +5950,15 @@ ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits) {
5949 entry->llvm_type = LLVMIntType(size_in_bits);5950 entry->llvm_type = LLVMIntType(size_in_bits);
5950 entry->abi_size = LLVMABISizeOfType(g->target_data_ref, entry->llvm_type);5951 entry->abi_size = LLVMABISizeOfType(g->target_data_ref, entry->llvm_type);
5951 entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, entry->llvm_type);5952 entry->abi_align = LLVMABIAlignmentOfType(g->target_data_ref, entry->llvm_type);
5953
5954 if (size_in_bits >= 128) {
5955 // Override the incorrect alignment reported by LLVM. Clang does this as well.
5956 // On x86_64 there are some instructions like CMPXCHG16B which require this.
5957 // On all targets, integers 128 bits and above have ABI alignment of 16.
5958 // See: https://github.com/ziglang/zig/issues/2987
5959 assert(entry->abi_align == 8); // if this trips we can remove the workaround
5960 entry->abi_align = 16;
5961 }
5952 }5962 }
59535963
5954 const char u_or_i = is_signed ? 'i' : 'u';5964 const char u_or_i = is_signed ? 'i' : 'u';
...@@ -6810,10 +6820,9 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -6810,10 +6820,9 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
6810 }6820 }
68116821
6812 size_t field_count = struct_type->data.structure.src_field_count;6822 size_t field_count = struct_type->data.structure.src_field_count;
6813 size_t gen_field_count = struct_type->data.structure.gen_field_count;6823 // Every field could potentially have a generated padding field after it.
6814 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(gen_field_count);6824 LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count * 2);
68156825
6816 size_t gen_field_index = 0;
6817 bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked);6826 bool packed = (struct_type->data.structure.layout == ContainerLayoutPacked);
6818 size_t packed_bits_offset = 0;6827 size_t packed_bits_offset = 0;
6819 size_t first_packed_bits_offset_misalign = SIZE_MAX;6828 size_t first_packed_bits_offset_misalign = SIZE_MAX;
...@@ -6821,20 +6830,36 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -6821,20 +6830,36 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
68216830
6822 // trigger all the recursive get_llvm_type calls6831 // trigger all the recursive get_llvm_type calls
6823 for (size_t i = 0; i < field_count; i += 1) {6832 for (size_t i = 0; i < field_count; i += 1) {
6824 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];6833 TypeStructField *field = &struct_type->data.structure.fields[i];
6825 ZigType *field_type = type_struct_field->type_entry;6834 ZigType *field_type = field->type_entry;
6826 if (!type_has_bits(field_type))6835 if (!type_has_bits(field_type))
6827 continue;6836 continue;
6828 (void)get_llvm_type(g, field_type);6837 (void)get_llvm_type(g, field_type);
6829 if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return;6838 if (struct_type->data.structure.resolve_status >= wanted_resolve_status) return;
6830 }6839 }
68316840
6832 for (size_t i = 0; i < field_count; i += 1) {6841 size_t gen_field_index = 0;
6833 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
6834 ZigType *field_type = type_struct_field->type_entry;
68356842
6843 // Calculate what LLVM thinks the ABI align of the struct will be. We do this to avoid
6844 // inserting padding bytes where LLVM would do it automatically.
6845 size_t llvm_struct_abi_align = 0;
6846 for (size_t i = 0; i < field_count; i += 1) {
6847 ZigType *field_type = struct_type->data.structure.fields[i].type_entry;
6836 if (!type_has_bits(field_type))6848 if (!type_has_bits(field_type))
6837 continue;6849 continue;
6850 LLVMTypeRef field_llvm_type = get_llvm_type(g, field_type);
6851 size_t llvm_field_abi_align = LLVMABIAlignmentOfType(g->target_data_ref, field_llvm_type);
6852 llvm_struct_abi_align = max(llvm_struct_abi_align, llvm_field_abi_align);
6853 }
6854
6855 for (size_t i = 0; i < field_count; i += 1) {
6856 TypeStructField *field = &struct_type->data.structure.fields[i];
6857 ZigType *field_type = field->type_entry;
6858
6859 if (!type_has_bits(field_type)) {
6860 field->gen_index = SIZE_MAX;
6861 continue;
6862 }
68386863
6839 if (packed) {6864 if (packed) {
6840 size_t field_size_in_bits = type_size_bits(g, field_type);6865 size_t field_size_in_bits = type_size_bits(g, field_type);
...@@ -6871,11 +6896,44 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -6871,11 +6896,44 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
6871 llvm_type = get_llvm_type(g, field_type);6896 llvm_type = get_llvm_type(g, field_type);
6872 }6897 }
6873 element_types[gen_field_index] = llvm_type;6898 element_types[gen_field_index] = llvm_type;
68746899 field->gen_index = gen_field_index;
6875 gen_field_index += 1;6900 gen_field_index += 1;
6901
6902 // find the next non-zero-byte field for offset calculations
6903 size_t next_src_field_index = i + 1;
6904 for (; next_src_field_index < field_count; next_src_field_index += 1) {
6905 if (type_has_bits(struct_type->data.structure.fields[next_src_field_index].type_entry))
6906 break;
6907 }
6908 size_t next_abi_align = (next_src_field_index == field_count) ?
6909 struct_type->abi_align :
6910 struct_type->data.structure.fields[next_src_field_index].type_entry->abi_align;
6911 size_t llvm_next_abi_align = (next_src_field_index == field_count) ?
6912 llvm_struct_abi_align :
6913 LLVMABIAlignmentOfType(g->target_data_ref,
6914 get_llvm_type(g, struct_type->data.structure.fields[next_src_field_index].type_entry));
6915
6916 size_t next_offset = next_field_offset(field->offset, struct_type->abi_align,
6917 field_type->abi_size, next_abi_align);
6918 size_t llvm_next_offset = next_field_offset(field->offset, llvm_struct_abi_align,
6919 LLVMABISizeOfType(g->target_data_ref, llvm_type), llvm_next_abi_align);
6920
6921 assert(next_offset >= llvm_next_offset);
6922 if (next_offset > llvm_next_offset) {
6923 size_t pad_bytes = next_offset - (field->offset + field_type->abi_size);
6924 if (pad_bytes != 0) {
6925 LLVMTypeRef pad_llvm_type = LLVMArrayType(LLVMInt8Type(), pad_bytes);
6926 element_types[gen_field_index] = pad_llvm_type;
6927 gen_field_index += 1;
6928 }
6929 }
6876 }6930 }
6877 debug_field_count += 1;6931 debug_field_count += 1;
6878 }6932 }
6933 if (!packed) {
6934 struct_type->data.structure.gen_field_count = gen_field_index;
6935 }
6936
6879 if (first_packed_bits_offset_misalign != SIZE_MAX) {6937 if (first_packed_bits_offset_misalign != SIZE_MAX) {
6880 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;6938 size_t full_bit_count = packed_bits_offset - first_packed_bits_offset_misalign;
6881 size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);6939 size_t full_abi_size = get_abi_size_bytes(full_bit_count, g->pointer_size_bytes);
...@@ -6884,19 +6942,20 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -6884,19 +6942,20 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
6884 }6942 }
68856943
6886 if (type_has_bits(struct_type)) {6944 if (type_has_bits(struct_type)) {
6887 LLVMStructSetBody(struct_type->llvm_type, element_types, (unsigned)gen_field_count, packed);6945 LLVMStructSetBody(struct_type->llvm_type, element_types,
6946 (unsigned)struct_type->data.structure.gen_field_count, packed);
6888 }6947 }
68896948
6890 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count);6949 ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(debug_field_count);
6891 size_t debug_field_index = 0;6950 size_t debug_field_index = 0;
6892 for (size_t i = 0; i < field_count; i += 1) {6951 for (size_t i = 0; i < field_count; i += 1) {
6893 TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];6952 TypeStructField *field = &struct_type->data.structure.fields[i];
6894 size_t gen_field_index = type_struct_field->gen_index;6953 size_t gen_field_index = field->gen_index;
6895 if (gen_field_index == SIZE_MAX) {6954 if (gen_field_index == SIZE_MAX) {
6896 continue;6955 continue;
6897 }6956 }
68986957
6899 ZigType *field_type = type_struct_field->type_entry;6958 ZigType *field_type = field->type_entry;
69006959
6901 // if the field is a function, actually the debug info should be a pointer.6960 // if the field is a function, actually the debug info should be a pointer.
6902 ZigLLVMDIType *field_di_type;6961 ZigLLVMDIType *field_di_type;
...@@ -6914,13 +6973,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -6914,13 +6973,13 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
6914 uint64_t debug_align_in_bits;6973 uint64_t debug_align_in_bits;
6915 uint64_t debug_offset_in_bits;6974 uint64_t debug_offset_in_bits;
6916 if (packed) {6975 if (packed) {
6917 debug_size_in_bits = type_struct_field->type_entry->size_in_bits;6976 debug_size_in_bits = field->type_entry->size_in_bits;
6918 debug_align_in_bits = 8 * type_struct_field->type_entry->abi_align;6977 debug_align_in_bits = 8 * field->type_entry->abi_align;
6919 debug_offset_in_bits = 8 * type_struct_field->offset + type_struct_field->bit_offset_in_host;6978 debug_offset_in_bits = 8 * field->offset + field->bit_offset_in_host;
6920 } else {6979 } else {
6921 debug_size_in_bits = 8 * get_store_size_bytes(field_type->size_in_bits);6980 debug_size_in_bits = 8 * get_store_size_bytes(field_type->size_in_bits);
6922 debug_align_in_bits = 8 * field_type->abi_align;6981 debug_align_in_bits = 8 * field_type->abi_align;
6923 debug_offset_in_bits = 8 * type_struct_field->offset;6982 debug_offset_in_bits = 8 * field->offset;
6924 }6983 }
6925 unsigned line;6984 unsigned line;
6926 if (decl_node != nullptr) {6985 if (decl_node != nullptr) {
...@@ -6930,7 +6989,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS...@@ -6930,7 +6989,7 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS
6930 line = 0;6989 line = 0;
6931 }6990 }
6932 di_element_types[debug_field_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,6991 di_element_types[debug_field_index] = ZigLLVMCreateDebugMemberType(g->dbuilder,
6933 ZigLLVMTypeToScope(struct_type->llvm_di_type), buf_ptr(type_struct_field->name),6992 ZigLLVMTypeToScope(struct_type->llvm_di_type), buf_ptr(field->name),
6934 di_file, line,6993 di_file, line,
6935 debug_size_in_bits,6994 debug_size_in_bits,
6936 debug_align_in_bits,6995 debug_align_in_bits,
...@@ -7171,7 +7230,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta...@@ -7171,7 +7230,7 @@ static void resolve_llvm_types_union(CodeGen *g, ZigType *union_type, ResolveSta
7171 union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;7230 union_type->data.unionation.resolve_status = ResolveStatusLLVMFull;
7172}7231}
71737232
7174static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {7233static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type, ResolveStatus wanted_resolve_status) {
7175 if (type->llvm_di_type != nullptr) return;7234 if (type->llvm_di_type != nullptr) return;
71767235
7177 if (!type_has_bits(type)) {7236 if (!type_has_bits(type)) {
...@@ -7200,7 +7259,7 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {...@@ -7200,7 +7259,7 @@ static void resolve_llvm_types_pointer(CodeGen *g, ZigType *type) {
7200 uint64_t debug_align_in_bits = 8*type->abi_align;7259 uint64_t debug_align_in_bits = 8*type->abi_align;
7201 type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, elem_type->llvm_di_type,7260 type->llvm_di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, elem_type->llvm_di_type,
7202 debug_size_in_bits, debug_align_in_bits, buf_ptr(&type->name));7261 debug_size_in_bits, debug_align_in_bits, buf_ptr(&type->name));
7203 assertNoError(type_resolve(g, elem_type, ResolveStatusLLVMFull));7262 assertNoError(type_resolve(g, elem_type, wanted_resolve_status));
7204 } else {7263 } else {
7205 ZigType *host_int_type = get_int_type(g, false, type->data.pointer.host_int_bytes * 8);7264 ZigType *host_int_type = get_int_type(g, false, type->data.pointer.host_int_bytes * 8);
7206 LLVMTypeRef host_int_llvm_type = get_llvm_type(g, host_int_type);7265 LLVMTypeRef host_int_llvm_type = get_llvm_type(g, host_int_type);
...@@ -7326,10 +7385,17 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {...@@ -7326,10 +7385,17 @@ static void resolve_llvm_types_error_union(CodeGen *g, ZigType *type) {
7326 } else {7385 } else {
7327 LLVMTypeRef err_set_llvm_type = get_llvm_type(g, err_set_type);7386 LLVMTypeRef err_set_llvm_type = get_llvm_type(g, err_set_type);
7328 LLVMTypeRef payload_llvm_type = get_llvm_type(g, payload_type);7387 LLVMTypeRef payload_llvm_type = get_llvm_type(g, payload_type);
7329 LLVMTypeRef elem_types[2];7388 LLVMTypeRef elem_types[3];
7330 elem_types[err_union_err_index] = err_set_llvm_type;7389 elem_types[err_union_err_index] = err_set_llvm_type;
7331 elem_types[err_union_payload_index] = payload_llvm_type;7390 elem_types[err_union_payload_index] = payload_llvm_type;
7391
7332 type->llvm_type = LLVMStructType(elem_types, 2, false);7392 type->llvm_type = LLVMStructType(elem_types, 2, false);
7393 if (LLVMABISizeOfType(g->target_data_ref, type->llvm_type) != type->abi_size) {
7394 // we need to do our own padding
7395 type->data.error_union.pad_llvm_type = LLVMArrayType(LLVMInt8Type(), type->data.error_union.pad_bytes);
7396 elem_types[2] = type->data.error_union.pad_llvm_type;
7397 type->llvm_type = LLVMStructType(elem_types, 3, false);
7398 }
73337399
7334 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);7400 ZigLLVMDIScope *compile_unit_scope = ZigLLVMCompileUnitToScope(g->compile_unit);
7335 ZigLLVMDIFile *di_file = nullptr;7401 ZigLLVMDIFile *di_file = nullptr;
...@@ -7511,6 +7577,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {...@@ -7511,6 +7577,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) {
7511}7577}
75127578
7513void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {7579void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {
7580 Error err;
7514 if (fn->raw_di_type != nullptr) return;7581 if (fn->raw_di_type != nullptr) return;
75157582
7516 ZigType *fn_type = fn->type_entry;7583 ZigType *fn_type = fn->type_entry;
...@@ -7529,8 +7596,10 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {...@@ -7529,8 +7596,10 @@ void resolve_llvm_types_fn(CodeGen *g, ZigFn *fn) {
75297596
7530 ZigType *frame_type = get_coro_frame_type(g, fn);7597 ZigType *frame_type = get_coro_frame_type(g, fn);
7531 ZigType *ptr_type = get_pointer_to_type(g, frame_type, false);7598 ZigType *ptr_type = get_pointer_to_type(g, frame_type, false);
7532 gen_param_types.append(get_llvm_type(g, ptr_type));7599 if ((err = type_resolve(g, ptr_type, ResolveStatusLLVMFwdDecl)))
7533 param_di_types.append(get_llvm_di_type(g, ptr_type));7600 zig_unreachable();
7601 gen_param_types.append(ptr_type->llvm_type);
7602 param_di_types.append(ptr_type->llvm_di_type);
75347603
7535 // this parameter is used to pass the result pointer when await completes7604 // this parameter is used to pass the result pointer when await completes
7536 gen_param_types.append(get_llvm_type(g, g->builtin_types.entry_usize));7605 gen_param_types.append(get_llvm_type(g, g->builtin_types.entry_usize));
...@@ -7726,7 +7795,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r...@@ -7726,7 +7795,7 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
7726 case ZigTypeIdUnion:7795 case ZigTypeIdUnion:
7727 return resolve_llvm_types_union(g, type, wanted_resolve_status);7796 return resolve_llvm_types_union(g, type, wanted_resolve_status);
7728 case ZigTypeIdPointer:7797 case ZigTypeIdPointer:
7729 return resolve_llvm_types_pointer(g, type);7798 return resolve_llvm_types_pointer(g, type, wanted_resolve_status);
7730 case ZigTypeIdInt:7799 case ZigTypeIdInt:
7731 return resolve_llvm_types_integer(g, type);7800 return resolve_llvm_types_integer(g, type);
7732 case ZigTypeIdOptional:7801 case ZigTypeIdOptional:
src/analyze.hpp-2
...@@ -38,8 +38,6 @@ ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);...@@ -38,8 +38,6 @@ ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
38ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type);38ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type);
39ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);39ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
40ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);40ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);
41ZigType *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
42 ZigType *field_types[], size_t field_count, unsigned min_abi_align);
43ZigType *get_test_fn_type(CodeGen *g);41ZigType *get_test_fn_type(CodeGen *g);
44ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);42ZigType *get_any_frame_type(CodeGen *g, ZigType *result_type);
45bool handle_is_ptr(ZigType *type_entry);43bool handle_is_ptr(ZigType *type_entry);
src/codegen.cpp+36-22
...@@ -3765,29 +3765,17 @@ static void render_async_spills(CodeGen *g) {...@@ -3765,29 +3765,17 @@ static void render_async_spills(CodeGen *g) {
3765 gen_var_debug_decl(g, var);3765 gen_var_debug_decl(g, var);
3766 }3766 }
3767 }3767 }
3768 // label (grep this): [coro_frame_struct_layout]3768
3769 if (codegen_fn_has_err_ret_tracing_stack(g, g->cur_fn, true)) {3769 ZigType *frame_type = g->cur_fn->frame_type->data.frame.locals_struct;
3770 async_var_index += 2;3770
3771 }
3772 for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) {3771 for (size_t alloca_i = 0; alloca_i < g->cur_fn->alloca_gen_list.length; alloca_i += 1) {
3773 IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i);3772 IrInstructionAllocaGen *instruction = g->cur_fn->alloca_gen_list.at(alloca_i);
3774 ZigType *ptr_type = instruction->base.value.type;3773 if (instruction->field_index == SIZE_MAX)
3775 assert(ptr_type->id == ZigTypeIdPointer);
3776 ZigType *child_type = ptr_type->data.pointer.child_type;
3777 if (!type_has_bits(child_type))
3778 continue;
3779 if (instruction->base.ref_count == 0)
3780 continue;3774 continue;
3781 if (instruction->base.value.special != ConstValSpecialRuntime) {3775
3782 if (const_ptr_pointee(nullptr, g, &instruction->base.value, nullptr)->special !=3776 size_t gen_index = frame_type->data.structure.fields[instruction->field_index].gen_index;
3783 ConstValSpecialRuntime)3777 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index,
3784 {
3785 continue;
3786 }
3787 }
3788 instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, async_var_index,
3789 instruction->name_hint);3778 instruction->name_hint);
3790 async_var_index += 1;
3791 }3779 }
3792}3780}
37933781
...@@ -6363,6 +6351,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -6363,6 +6351,9 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
6363 break;6351 break;
6364 }6352 }
63656353
6354 if ((err = type_resolve(g, type_entry, ResolveStatusLLVMFull)))
6355 zig_unreachable();
6356
6366 switch (type_entry->id) {6357 switch (type_entry->id) {
6367 case ZigTypeIdInt:6358 case ZigTypeIdInt:
6368 return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_bigint);6359 return bigint_to_llvm_const(get_llvm_type(g, type_entry), &const_val->data.x_bigint);
...@@ -6434,6 +6425,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -6434,6 +6425,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
6434 LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);6425 LLVMValueRef *fields = allocate<LLVMValueRef>(type_entry->data.structure.gen_field_count);
6435 size_t src_field_count = type_entry->data.structure.src_field_count;6426 size_t src_field_count = type_entry->data.structure.src_field_count;
6436 bool make_unnamed_struct = false;6427 bool make_unnamed_struct = false;
6428 assert(type_entry->data.structure.resolve_status == ResolveStatusLLVMFull);
6437 if (type_entry->data.structure.layout == ContainerLayoutPacked) {6429 if (type_entry->data.structure.layout == ContainerLayoutPacked) {
6438 size_t src_field_index = 0;6430 size_t src_field_index = 0;
6439 while (src_field_index < src_field_count) {6431 while (src_field_index < src_field_count) {
...@@ -6503,6 +6495,22 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -6503,6 +6495,22 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
6503 LLVMValueRef val = gen_const_val(g, field_val, "");6495 LLVMValueRef val = gen_const_val(g, field_val, "");
6504 fields[type_struct_field->gen_index] = val;6496 fields[type_struct_field->gen_index] = val;
6505 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);6497 make_unnamed_struct = make_unnamed_struct || is_llvm_value_unnamed_type(g, field_val->type, val);
6498
6499 size_t end_pad_gen_index = (i + 1 < src_field_count) ?
6500 type_entry->data.structure.fields[i + 1].gen_index :
6501 type_entry->data.structure.gen_field_count;
6502 size_t next_offset = (i + 1 < src_field_count) ?
6503 type_entry->data.structure.fields[i + 1].offset : type_entry->abi_size;
6504 if (end_pad_gen_index != SIZE_MAX) {
6505 for (size_t gen_i = type_struct_field->gen_index + 1; gen_i < end_pad_gen_index;
6506 gen_i += 1)
6507 {
6508 size_t pad_bytes = next_offset -
6509 (type_struct_field->offset + type_struct_field->type_entry->abi_size);
6510 LLVMTypeRef llvm_array_type = LLVMArrayType(LLVMInt8Type(), pad_bytes);
6511 fields[gen_i] = LLVMGetUndef(llvm_array_type);
6512 }
6513 }
6506 }6514 }
6507 }6515 }
6508 if (make_unnamed_struct) {6516 if (make_unnamed_struct) {
...@@ -6690,13 +6698,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -6690,13 +6698,18 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
6690 err_payload_value = gen_const_val(g, payload_val, "");6698 err_payload_value = gen_const_val(g, payload_val, "");
6691 make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_val->type, err_payload_value);6699 make_unnamed_struct = is_llvm_value_unnamed_type(g, payload_val->type, err_payload_value);
6692 }6700 }
6693 LLVMValueRef fields[2];6701 LLVMValueRef fields[3];
6694 fields[err_union_err_index] = err_tag_value;6702 fields[err_union_err_index] = err_tag_value;
6695 fields[err_union_payload_index] = err_payload_value;6703 fields[err_union_payload_index] = err_payload_value;
6704 size_t field_count = 2;
6705 if (type_entry->data.error_union.pad_llvm_type != nullptr) {
6706 fields[2] = LLVMGetUndef(type_entry->data.error_union.pad_llvm_type);
6707 field_count = 3;
6708 }
6696 if (make_unnamed_struct) {6709 if (make_unnamed_struct) {
6697 return LLVMConstStruct(fields, 2, false);6710 return LLVMConstStruct(fields, field_count, false);
6698 } else {6711 } else {
6699 return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, 2);6712 return LLVMConstNamedStruct(get_llvm_type(g, type_entry), fields, field_count);
6700 }6713 }
6701 }6714 }
6702 }6715 }
...@@ -7139,6 +7152,7 @@ static void do_code_gen(CodeGen *g) {...@@ -7139,6 +7152,7 @@ static void do_code_gen(CodeGen *g) {
7139 }7152 }
71407153
7141 if (is_async) {7154 if (is_async) {
7155 (void)get_llvm_type(g, fn_table_entry->frame_type);
7142 g->cur_resume_block_count = 0;7156 g->cur_resume_block_count = 0;
71437157
7144 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;7158 LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
std/event/channel.zig+1-3
...@@ -307,11 +307,9 @@ test "std.event.Channel" {...@@ -307,11 +307,9 @@ test "std.event.Channel" {
307 // https://github.com/ziglang/zig/issues/1908307 // https://github.com/ziglang/zig/issues/1908
308 if (builtin.single_threaded) return error.SkipZigTest;308 if (builtin.single_threaded) return error.SkipZigTest;
309309
310 const allocator = std.heap.direct_allocator;
311
312 var loop: Loop = undefined;310 var loop: Loop = undefined;
313 // TODO make a multi threaded test311 // TODO make a multi threaded test
314 try loop.initSingleThreaded(allocator);312 try loop.initSingleThreaded(std.heap.direct_allocator);
315 defer loop.deinit();313 defer loop.deinit();
316314
317 const channel = try Channel(i32).create(&loop, 0);315 const channel = try Channel(i32).create(&loop, 0);
test/stage1/behavior/align.zig+62
...@@ -228,3 +228,65 @@ test "alignment of extern() void" {...@@ -228,3 +228,65 @@ test "alignment of extern() void" {
228}228}
229229
230extern fn nothing() void {}230extern fn nothing() void {}
231
232test "return error union with 128-bit integer" {
233 expect(3 == try give());
234}
235fn give() anyerror!u128 {
236 return 3;
237}
238
239test "alignment of >= 128-bit integer type" {
240 expect(@alignOf(u128) == 16);
241 expect(@alignOf(u129) == 16);
242}
243
244test "alignment of struct with 128-bit field" {
245 expect(@alignOf(struct {
246 x: u128,
247 }) == 16);
248
249 comptime {
250 expect(@alignOf(struct {
251 x: u128,
252 }) == 16);
253 }
254}
255
256test "size of extern struct with 128-bit field" {
257 expect(@sizeOf(extern struct {
258 x: u128,
259 y: u8,
260 }) == 32);
261
262 comptime {
263 expect(@sizeOf(extern struct {
264 x: u128,
265 y: u8,
266 }) == 32);
267 }
268}
269
270const DefaultAligned = struct {
271 nevermind: u32,
272 badguy: i128,
273};
274
275test "read 128-bit field from default aligned struct in stack memory" {
276 var default_aligned = DefaultAligned{
277 .nevermind = 1,
278 .badguy = 12,
279 };
280 expect((@ptrToInt(&default_aligned.badguy) % 16) == 0);
281 expect(12 == default_aligned.badguy);
282}
283
284var default_aligned_global = DefaultAligned{
285 .nevermind = 1,
286 .badguy = 12,
287};
288
289test "read 128-bit field from default aligned struct in global memory" {
290 expect((@ptrToInt(&default_aligned_global.badguy) % 16) == 0);
291 expect(12 == default_aligned_global.badguy);
292}