| ... | @@ -8404,7 +8404,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -8404,7 +8404,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 8404 | if (!ir_emit_global_runtime_side_effect(ira, source_instr)) | 8404 | if (!ir_emit_global_runtime_side_effect(ira, source_instr)) |
| 8405 | return ira->codegen->invalid_instruction; | 8405 | return ira->codegen->invalid_instruction; |
| 8406 | uint64_t child_type_size = type_size(ira->codegen, | 8406 | uint64_t child_type_size = type_size(ira->codegen, |
| 8407 | wanted_type->data.structure.fields[0].type_entry->data.pointer.child_type); | 8407 | wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type); |
| 8408 | if (actual_type->data.array.len % child_type_size == 0) { | 8408 | if (actual_type->data.array.len % child_type_size == 0) { |
| 8409 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBytesToSlice, true); | 8409 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpBytesToSlice, true); |
| 8410 | } else { | 8410 | } else { |
| ... | @@ -10870,6 +10870,15 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -10870,6 +10870,15 @@ static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstruct |
| 10870 | var_ptr_instruction->is_volatile); | 10870 | var_ptr_instruction->is_volatile); |
| 10871 | } | 10871 | } |
| 10872 | | 10872 | |
| | 10873 | static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, uint32_t new_align) { |
| | 10874 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| | 10875 | return get_pointer_to_type_extra(g, |
| | 10876 | ptr_type->data.pointer.child_type, |
| | 10877 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| | 10878 | new_align, |
| | 10879 | ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count); |
| | 10880 | } |
| | 10881 | |
| 10873 | static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { | 10882 | static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { |
| 10874 | IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other; | 10883 | IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->other; |
| 10875 | if (type_is_invalid(array_ptr->value.type)) | 10884 | if (type_is_invalid(array_ptr->value.type)) |
| ... | @@ -10888,6 +10897,9 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -10888,6 +10897,9 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 10888 | assert(ptr_type->id == TypeTableEntryIdPointer); | 10897 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 10889 | | 10898 | |
| 10890 | TypeTableEntry *array_type = ptr_type->data.pointer.child_type; | 10899 | TypeTableEntry *array_type = ptr_type->data.pointer.child_type; |
| | 10900 | |
| | 10901 | // At first return_type will be the pointer type we want to return, except with an optimistic alignment. |
| | 10902 | // We will adjust return_type's alignment before returning it. |
| 10891 | TypeTableEntry *return_type; | 10903 | TypeTableEntry *return_type; |
| 10892 | | 10904 | |
| 10893 | if (type_is_invalid(array_type)) { | 10905 | if (type_is_invalid(array_type)) { |
| ... | @@ -10918,7 +10930,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -10918,7 +10930,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 10918 | } else if (array_type->id == TypeTableEntryIdPointer) { | 10930 | } else if (array_type->id == TypeTableEntryIdPointer) { |
| 10919 | return_type = array_type; | 10931 | return_type = array_type; |
| 10920 | } else if (is_slice(array_type)) { | 10932 | } else if (is_slice(array_type)) { |
| 10921 | return_type = array_type->data.structure.fields[0].type_entry; | 10933 | return_type = array_type->data.structure.fields[slice_ptr_index].type_entry; |
| 10922 | } else if (array_type->id == TypeTableEntryIdArgTuple) { | 10934 | } else if (array_type->id == TypeTableEntryIdArgTuple) { |
| 10923 | ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); | 10935 | ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); |
| 10924 | if (!ptr_val) | 10936 | if (!ptr_val) |
| ... | @@ -10961,6 +10973,10 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -10961,6 +10973,10 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 10961 | return ira->codegen->builtin_types.entry_invalid; | 10973 | return ira->codegen->builtin_types.entry_invalid; |
| 10962 | | 10974 | |
| 10963 | bool safety_check_on = elem_ptr_instruction->safety_check_on; | 10975 | bool safety_check_on = elem_ptr_instruction->safety_check_on; |
| | 10976 | ensure_complete_type(ira->codegen, return_type->data.pointer.child_type); |
| | 10977 | uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); |
| | 10978 | uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); |
| | 10979 | uint64_t ptr_align = return_type->data.pointer.alignment; |
| 10964 | if (instr_is_comptime(casted_elem_index)) { | 10980 | if (instr_is_comptime(casted_elem_index)) { |
| 10965 | uint64_t index = bigint_as_unsigned(&casted_elem_index->value.data.x_bigint); | 10981 | uint64_t index = bigint_as_unsigned(&casted_elem_index->value.data.x_bigint); |
| 10966 | if (array_type->id == TypeTableEntryIdArray) { | 10982 | if (array_type->id == TypeTableEntryIdArray) { |
| ... | @@ -10974,6 +10990,26 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -10974,6 +10990,26 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 10974 | safety_check_on = false; | 10990 | safety_check_on = false; |
| 10975 | } | 10991 | } |
| 10976 | | 10992 | |
| | 10993 | { |
| | 10994 | // figure out the largest alignment possible |
| | 10995 | uint64_t chosen_align = abi_align; |
| | 10996 | if (ptr_align >= abi_align) { |
| | 10997 | while (ptr_align > abi_align) { |
| | 10998 | if ((index * elem_size) % ptr_align == 0) { |
| | 10999 | chosen_align = ptr_align; |
| | 11000 | break; |
| | 11001 | } |
| | 11002 | ptr_align >>= 1; |
| | 11003 | } |
| | 11004 | } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { |
| | 11005 | chosen_align = ptr_align; |
| | 11006 | } else { |
| | 11007 | // can't get here because guaranteed elem_size >= abi_align |
| | 11008 | zig_unreachable(); |
| | 11009 | } |
| | 11010 | return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); |
| | 11011 | } |
| | 11012 | |
| 10977 | ConstExprValue *array_ptr_val; | 11013 | ConstExprValue *array_ptr_val; |
| 10978 | if (array_ptr->value.special != ConstValSpecialRuntime && | 11014 | if (array_ptr->value.special != ConstValSpecialRuntime && |
| 10979 | (array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) && | 11015 | (array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) && |
| ... | @@ -11085,6 +11121,18 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -11085,6 +11121,18 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 11085 | } | 11121 | } |
| 11086 | } | 11122 | } |
| 11087 | | 11123 | |
| | 11124 | } else { |
| | 11125 | // runtime known element index |
| | 11126 | if (ptr_align < abi_align) { |
| | 11127 | if (elem_size >= ptr_align && elem_size % ptr_align == 0) { |
| | 11128 | return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); |
| | 11129 | } else { |
| | 11130 | // can't get here because guaranteed elem_size >= abi_align |
| | 11131 | zig_unreachable(); |
| | 11132 | } |
| | 11133 | } else { |
| | 11134 | return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); |
| | 11135 | } |
| 11088 | } | 11136 | } |
| 11089 | | 11137 | |
| 11090 | ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr, | 11138 | ir_build_elem_ptr_from(&ira->new_irb, &elem_ptr_instruction->base, array_ptr, |
| ... | @@ -14520,11 +14568,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 | ... | @@ -14520,11 +14568,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 |
| 14520 | uint32_t old_align_bytes; | 14568 | uint32_t old_align_bytes; |
| 14521 | | 14569 | |
| 14522 | if (target_type->id == TypeTableEntryIdPointer) { | 14570 | if (target_type->id == TypeTableEntryIdPointer) { |
| 14523 | result_type = get_pointer_to_type_extra(ira->codegen, | 14571 | result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); |
| 14524 | target_type->data.pointer.child_type, | | |
| 14525 | target_type->data.pointer.is_const, target_type->data.pointer.is_volatile, | | |
| 14526 | align_bytes, | | |
| 14527 | target_type->data.pointer.bit_offset, target_type->data.pointer.unaligned_bit_count); | | |
| 14528 | } else if (target_type->id == TypeTableEntryIdFn) { | 14572 | } else if (target_type->id == TypeTableEntryIdFn) { |
| 14529 | FnTypeId fn_type_id = target_type->data.fn.fn_type_id; | 14573 | FnTypeId fn_type_id = target_type->data.fn.fn_type_id; |
| 14530 | old_align_bytes = fn_type_id.alignment; | 14574 | old_align_bytes = fn_type_id.alignment; |
| ... | @@ -14535,11 +14579,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 | ... | @@ -14535,11 +14579,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 |
| 14535 | { | 14579 | { |
| 14536 | TypeTableEntry *ptr_type = target_type->data.maybe.child_type; | 14580 | TypeTableEntry *ptr_type = target_type->data.maybe.child_type; |
| 14537 | old_align_bytes = ptr_type->data.pointer.alignment; | 14581 | old_align_bytes = ptr_type->data.pointer.alignment; |
| 14538 | TypeTableEntry *better_ptr_type = get_pointer_to_type_extra(ira->codegen, | 14582 | TypeTableEntry *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); |
| 14539 | ptr_type->data.pointer.child_type, | | |
| 14540 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, | | |
| 14541 | align_bytes, | | |
| 14542 | ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count); | | |
| 14543 | | 14583 | |
| 14544 | result_type = get_maybe_type(ira->codegen, better_ptr_type); | 14584 | result_type = get_maybe_type(ira->codegen, better_ptr_type); |
| 14545 | } else if (target_type->id == TypeTableEntryIdMaybe && | 14585 | } else if (target_type->id == TypeTableEntryIdMaybe && |
| ... | @@ -14553,11 +14593,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 | ... | @@ -14553,11 +14593,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3 |
| 14553 | } else if (is_slice(target_type)) { | 14593 | } else if (is_slice(target_type)) { |
| 14554 | TypeTableEntry *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; | 14594 | TypeTableEntry *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; |
| 14555 | old_align_bytes = slice_ptr_type->data.pointer.alignment; | 14595 | old_align_bytes = slice_ptr_type->data.pointer.alignment; |
| 14556 | TypeTableEntry *result_ptr_type = get_pointer_to_type_extra(ira->codegen, | 14596 | TypeTableEntry *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); |
| 14557 | slice_ptr_type->data.pointer.child_type, | | |
| 14558 | slice_ptr_type->data.pointer.is_const, slice_ptr_type->data.pointer.is_volatile, | | |
| 14559 | align_bytes, | | |
| 14560 | slice_ptr_type->data.pointer.bit_offset, slice_ptr_type->data.pointer.unaligned_bit_count); | | |
| 14561 | result_type = get_slice_type(ira->codegen, result_ptr_type); | 14597 | result_type = get_slice_type(ira->codegen, result_ptr_type); |
| 14562 | } else { | 14598 | } else { |
| 14563 | ir_add_error(ira, target, | 14599 | ir_add_error(ira, target, |