| author | |
| committer | |
| log | 7ea7842ed020d5b984d14b824663891aae7549bc |
| tree | 022a3f509450d0824988dc767601c821c9e147d0 |
| parent | 7fe13f4a86c04c25f95b237452b90e9ab3103d1f |
2 files changed, 29 insertions(+), 15 deletions(-)
src/ir.cpp+9-2| ... | @@ -15801,8 +15801,15 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -15801,8 +15801,15 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 15801 | if ((err = resolve_ptr_align(ira, op1->value->type, &align_bytes))) | 15801 | if ((err = resolve_ptr_align(ira, op1->value->type, &align_bytes))) |
| 15802 | return ira->codegen->invalid_instruction; | 15802 | return ira->codegen->invalid_instruction; |
| 15803 | 15803 | ||
| 15804 | if (byte_offset != 0 && byte_offset % align_bytes != 0) | 15804 | if (byte_offset & (align_bytes - 1)) { |
| 15805 | result_type = adjust_ptr_align(ira->codegen, result_type, 1); | 15805 | // The resulting pointer is aligned to the lcd between the |
| 15806 | // offset (an arbitrary number) and the alignment factor (always | ||
| 15807 | // a power of two, non zero) | ||
| 15808 | uint32_t new_align = 1 << ctzll(byte_offset | align_bytes); | ||
| 15809 | // Rough guard to prevent overflows | ||
| 15810 | assert(new_align); | ||
| 15811 | result_type = adjust_ptr_align(ira->codegen, result_type, new_align); | ||
| 15812 | } | ||
| 15806 | } else { | 15813 | } else { |
| 15807 | // The addend is not a comptime-known value | 15814 | // The addend is not a comptime-known value |
| 15808 | result_type = adjust_ptr_align(ira->codegen, result_type, 1); | 15815 | result_type = adjust_ptr_align(ira->codegen, result_type, 1); |
test/stage1/behavior/pointers.zig+20-13| ... | @@ -290,17 +290,24 @@ test "pointer to array at fixed address" { | ... | @@ -290,17 +290,24 @@ test "pointer to array at fixed address" { |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | test "pointer arithmetic affects the alignment" { | 292 | test "pointer arithmetic affects the alignment" { |
| 293 | var arr: [10]u8 align(2) = undefined; | 293 | { |
| 294 | var x: usize = 1; | 294 | var ptr: [*]align(8) u32 = undefined; |
| 295 | 295 | var x: usize = 1; | |
| 296 | const ptr = @as([*]u8, &arr); | 296 | |
| 297 | expect(@typeInfo(@TypeOf(ptr)).Pointer.alignment == 2); | 297 | expect(@typeInfo(@TypeOf(ptr)).Pointer.alignment == 8); |
| 298 | const ptr1 = ptr + 1; | 298 | const ptr1 = ptr + 1; // 1 * 4 = 4 -> lcd(4,8) = 4 |
| 299 | expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 1); | 299 | expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 4); |
| 300 | const ptr2 = ptr + 4; | 300 | const ptr2 = ptr + 4; // 4 * 4 = 16 -> lcd(16,8) = 8 |
| 301 | expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 2); | 301 | expect(@typeInfo(@TypeOf(ptr2)).Pointer.alignment == 8); |
| 302 | const ptr3 = ptr + 0; | 302 | const ptr3 = ptr + 0; // no-op |
| 303 | expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 2); | 303 | expect(@typeInfo(@TypeOf(ptr3)).Pointer.alignment == 8); |
| 304 | const ptr4 = ptr + x; | 304 | const ptr4 = ptr + x; // runtime-known addend |
| 305 | expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 1); | 305 | expect(@typeInfo(@TypeOf(ptr4)).Pointer.alignment == 1); |
| 306 | } | ||
| 307 | { | ||
| 308 | var ptr: [*]align(8) [3]u8 = undefined; | ||
| 309 | |||
| 310 | const ptr1 = ptr + 17; // 3 * 17 = 51 | ||
| 311 | expect(@typeInfo(@TypeOf(ptr1)).Pointer.alignment == 1); | ||
| 312 | } | ||
| 306 | } | 313 | } |