| ... | @@ -15776,6 +15776,10 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -15776,6 +15776,10 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 15776 | return ir_const_undef(ira, &instruction->base, op1->value->type); | 15776 | return ir_const_undef(ira, &instruction->base, op1->value->type); |
| 15777 | } | 15777 | } |
| 15778 | | 15778 | |
| | 15779 | ZigType *elem_type = op1->value->type->data.pointer.child_type; |
| | 15780 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) |
| | 15781 | return ira->codegen->invalid_instruction; |
| | 15782 | |
| 15779 | // NOTE: this variable is meaningful iff op2_val is not null! | 15783 | // NOTE: this variable is meaningful iff op2_val is not null! |
| 15780 | uint64_t byte_offset; | 15784 | uint64_t byte_offset; |
| 15781 | if (op2_val != nullptr) { | 15785 | if (op2_val != nullptr) { |
| ... | @@ -15783,9 +15787,6 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -15783,9 +15787,6 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 15783 | if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) | 15787 | if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) |
| 15784 | return ira->codegen->invalid_instruction; | 15788 | return ira->codegen->invalid_instruction; |
| 15785 | | 15789 | |
| 15786 | ZigType *elem_type = op1->value->type->data.pointer.child_type; | | |
| 15787 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) | | |
| 15788 | return ira->codegen->invalid_instruction; | | |
| 15789 | byte_offset = type_size(ira->codegen, elem_type) * elem_offset; | 15790 | byte_offset = type_size(ira->codegen, elem_type) * elem_offset; |
| 15790 | } | 15791 | } |
| 15791 | | 15792 | |
| ... | @@ -15795,24 +15796,23 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -15795,24 +15796,23 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 15795 | } | 15796 | } |
| 15796 | | 15797 | |
| 15797 | ZigType *result_type = op1->value->type; | 15798 | ZigType *result_type = op1->value->type; |
| 15798 | // The resulting pointer may not be aligned anymore | 15799 | // Calculate the new alignment of the pointer |
| 15799 | if (op2_val != nullptr) { | 15800 | { |
| 15800 | uint32_t align_bytes; | 15801 | uint32_t align_bytes; |
| 15801 | if ((err = resolve_ptr_align(ira, op1->value->type, &align_bytes))) | 15802 | if ((err = resolve_ptr_align(ira, op1->value->type, &align_bytes))) |
| 15802 | return ira->codegen->invalid_instruction; | 15803 | return ira->codegen->invalid_instruction; |
| 15803 | | 15804 | |
| 15804 | if (byte_offset & (align_bytes - 1)) { | 15805 | // If the addend is not a comptime-known value we can still count on |
| 15805 | // The resulting pointer is aligned to the lcd between the | 15806 | // it being a multiple of the type size |
| 15806 | // offset (an arbitrary number) and the alignment factor (always | 15807 | uint32_t addend = op2_val ? byte_offset : type_size(ira->codegen, elem_type); |
| 15807 | // a power of two, non zero) | 15808 | |
| 15808 | uint32_t new_align = 1 << ctzll(byte_offset | align_bytes); | 15809 | // The resulting pointer is aligned to the lcd between the |
| 15809 | // Rough guard to prevent overflows | 15810 | // offset (an arbitrary number) and the alignment factor (always |
| 15810 | assert(new_align); | 15811 | // a power of two, non zero) |
| 15811 | result_type = adjust_ptr_align(ira->codegen, result_type, new_align); | 15812 | uint32_t new_align = 1 << ctzll(addend | align_bytes); |
| 15812 | } | 15813 | // Rough guard to prevent overflows |
| 15813 | } else { | 15814 | assert(new_align); |
| 15814 | // The addend is not a comptime-known value | 15815 | result_type = adjust_ptr_align(ira->codegen, result_type, new_align); |
| 15815 | result_type = adjust_ptr_align(ira->codegen, result_type, 1); | | |
| 15816 | } | 15816 | } |
| 15817 | | 15817 | |
| 15818 | if (op2_val != nullptr && op1_val != nullptr && | 15818 | if (op2_val != nullptr && op1_val != nullptr && |