Commit e08b6149ab
Changed files (5)
test
src/Sema.zig
@@ -1415,10 +1415,6 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
const ptr = sema.resolveInst(bin_inst.rhs);
const addr_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);
- const ptr_ty = try Type.ptr(sema.arena, .{
- .pointee_type = pointee_ty,
- .@"addrspace" = addr_space,
- });
if (Air.refToIndex(ptr)) |ptr_inst| {
if (sema.air_instructions.items(.tag)[ptr_inst] == .constant) {
@@ -1438,6 +1434,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
try inferred_alloc.stored_inst_list.append(sema.arena, operand);
try sema.requireRuntimeBlock(block, src);
+ const ptr_ty = try Type.ptr(sema.arena, .{
+ .pointee_type = pointee_ty,
+ .@"align" = inferred_alloc.alignment,
+ .@"addrspace" = addr_space,
+ });
const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr);
return bitcasted_ptr;
},
@@ -1447,19 +1448,30 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
// The alloc will turn into a Decl.
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
- iac.data = try anon_decl.finish(
+ iac.data.decl = try anon_decl.finish(
try pointee_ty.copy(anon_decl.arena()),
Value.undef,
);
+ const ptr_ty = try Type.ptr(sema.arena, .{
+ .pointee_type = pointee_ty,
+ .@"align" = iac.data.alignment,
+ .@"addrspace" = addr_space,
+ });
return sema.addConstant(
ptr_ty,
try Value.Tag.decl_ref_mut.create(sema.arena, .{
- .decl = iac.data,
+ .decl = iac.data.decl,
.runtime_index = block.runtime_index,
}),
);
},
- .decl_ref_mut => return sema.addConstant(ptr_ty, ptr_val),
+ .decl_ref_mut => {
+ const ptr_ty = try Type.ptr(sema.arena, .{
+ .pointee_type = pointee_ty,
+ .@"addrspace" = addr_space,
+ });
+ return sema.addConstant(ptr_ty, ptr_val);
+ },
else => {},
}
}
@@ -1491,6 +1503,11 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
sema.air_instructions.len -= 1;
}
+ const ptr_ty = try Type.ptr(sema.arena, .{
+ .pointee_type = pointee_ty,
+ .@"addrspace" = addr_space,
+ });
+
var new_ptr = ptr;
while (true) {
@@ -2183,7 +2200,10 @@ fn zirAllocExtended(
} else {
return sema.addConstant(
inferred_alloc_ty,
- try Value.Tag.inferred_alloc_comptime.create(sema.arena, undefined),
+ try Value.Tag.inferred_alloc_comptime.create(sema.arena, .{
+ .decl = undefined,
+ .alignment = alignment,
+ }),
);
}
}
@@ -2208,7 +2228,7 @@ fn zirAllocExtended(
// to the block even though it is currently a `.constant`.
const result = try sema.addConstant(
inferred_alloc_ty,
- try Value.Tag.inferred_alloc.create(sema.arena, .{}),
+ try Value.Tag.inferred_alloc.create(sema.arena, .{ .alignment = alignment }),
);
try sema.requireFunctionBlock(block, src);
try block.instructions.append(sema.gpa, Air.refToIndex(result).?);
@@ -2302,7 +2322,7 @@ fn zirAllocInferred(
// to the block even though it is currently a `.constant`.
const result = try sema.addConstant(
inferred_alloc_ty,
- try Value.Tag.inferred_alloc.create(sema.arena, .{}),
+ try Value.Tag.inferred_alloc.create(sema.arena, .{ .alignment = 0 }),
);
try sema.requireFunctionBlock(block, src);
try block.instructions.append(sema.gpa, Air.refToIndex(result).?);
@@ -2331,12 +2351,13 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
switch (ptr_val.tag()) {
.inferred_alloc_comptime => {
const iac = ptr_val.castTag(.inferred_alloc_comptime).?;
- const decl = iac.data;
+ const decl = iac.data.decl;
try sema.mod.declareDeclDependency(sema.owner_decl, decl);
const final_elem_ty = try decl.ty.copy(sema.arena);
const final_ptr_ty = try Type.ptr(sema.arena, .{
.pointee_type = final_elem_ty,
+ .@"align" = iac.data.alignment,
.@"addrspace" = target_util.defaultAddressSpace(target, .local),
});
const final_ptr_ty_inst = try sema.addType(final_ptr_ty);
@@ -2365,6 +2386,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
// Change it to a normal alloc.
const final_ptr_ty = try Type.ptr(sema.arena, .{
.pointee_type = final_elem_ty,
+ .@"align" = inferred_alloc.data.alignment,
.@"addrspace" = target_util.defaultAddressSpace(target, .local),
});
sema.air_instructions.set(ptr_inst, .{
@@ -2681,10 +2703,11 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
}
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
- iac.data = try anon_decl.finish(
+ iac.data.decl = try anon_decl.finish(
try operand_ty.copy(anon_decl.arena()),
try operand_val.copy(anon_decl.arena()),
);
+ // TODO set the alignment on the decl
return;
} else {
return sema.failWithNeededComptime(block, src);
@@ -2698,6 +2721,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi
// Create a runtime bitcast instruction with exactly the type the pointer wants.
const ptr_ty = try Type.ptr(sema.arena, .{
.pointee_type = operand_ty,
+ .@"align" = inferred_alloc.data.alignment,
.@"addrspace" = target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
});
const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr);
src/value.zig
@@ -256,7 +256,6 @@ pub const Value = extern union {
.extern_fn,
.decl_ref,
- .inferred_alloc_comptime,
=> Payload.Decl,
.repeated,
@@ -291,6 +290,7 @@ pub const Value = extern union {
.float_128 => Payload.Float_128,
.@"error" => Payload.Error,
.inferred_alloc => Payload.InferredAlloc,
+ .inferred_alloc_comptime => Payload.InferredAllocComptime,
.@"struct" => Payload.Struct,
.@"union" => Payload.Union,
.bound_fn => Payload.BoundFn,
@@ -2889,6 +2889,19 @@ pub const Value = extern union {
/// the items are contiguous in memory and thus can be passed to
/// `Module.resolvePeerTypes`.
stored_inst_list: std.ArrayListUnmanaged(Air.Inst.Ref) = .{},
+ /// 0 means ABI-aligned.
+ alignment: u16,
+ },
+ };
+
+ pub const InferredAllocComptime = struct {
+ pub const base_tag = Tag.inferred_alloc_comptime;
+
+ base: Payload = .{ .tag = base_tag },
+ data: struct {
+ decl: *Module.Decl,
+ /// 0 means ABI-aligned.
+ alignment: u16,
},
};
test/behavior/align_llvm.zig
@@ -0,0 +1,19 @@
+const std = @import("std");
+const expect = std.testing.expect;
+const builtin = @import("builtin");
+const native_arch = builtin.target.cpu.arch;
+
+test "page aligned array on stack" {
+ // Large alignment value to make it hard to accidentally pass.
+ var array align(0x1000) = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
+ var number1: u8 align(16) = 42;
+ var number2: u8 align(16) = 43;
+
+ try expect(@ptrToInt(&array[0]) & 0xFFF == 0);
+ try expect(array[3] == 4);
+
+ try expect(@truncate(u4, @ptrToInt(&number1)) == 0);
+ try expect(@truncate(u4, @ptrToInt(&number2)) == 0);
+ try expect(number1 == 42);
+ try expect(number2 == 43);
+}
test/behavior/align_stage1.zig
@@ -223,18 +223,3 @@ test "align(N) on functions" {
fn overaligned_fn() align(0x1000) i32 {
return 42;
}
-
-test "page aligned array on stack" {
- // Large alignment value to make it hard to accidentally pass.
- var array align(0x1000) = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
- var number1: u8 align(16) = 42;
- var number2: u8 align(16) = 43;
-
- try expect(@ptrToInt(&array[0]) & 0xFFF == 0);
- try expect(array[3] == 4);
-
- try expect(@truncate(u4, @ptrToInt(&number1)) == 0);
- try expect(@truncate(u4, @ptrToInt(&number2)) == 0);
- try expect(number1 == 42);
- try expect(number2 == 43);
-}
test/behavior.zig
@@ -44,6 +44,7 @@ test {
if (builtin.object_format != .c) {
// Tests that pass for stage1 and stage2 but not the C backend.
+ _ = @import("behavior/align_llvm.zig");
_ = @import("behavior/array.zig");
_ = @import("behavior/atomics.zig");
_ = @import("behavior/basic_llvm.zig");