authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-08 21:02:05+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-08 21:02:05+01:00
log7ea7842ed020d5b984d14b824663891aae7549bc
tree022a3f509450d0824988dc767601c821c9e147d0
parent7fe13f4a86c04c25f95b237452b90e9ab3103d1f

Fix calculation of new alignment factor


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;
1580315803
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 value15814 // 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}
291291
292test "pointer arithmetic affects the alignment" {292test "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;
295295 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}