Skip to content

Commit

Permalink
cbe: fix introduced bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobly0 committed Mar 30, 2024
1 parent 2691a36 commit cb5deb5
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 44 deletions.
7 changes: 5 additions & 2 deletions src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -36125,7 +36125,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
// alignment is greater.
var size: u64 = 0;
var padding: u32 = 0;
if (tag_align.compare(.gte, max_align)) {
if (tag_align.order(max_align).compare(.gte)) {
// {Tag, Payload}
size += tag_size;
size = max_align.forward(size);
Expand All @@ -36136,7 +36136,10 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
} else {
// {Payload, Tag}
size += max_size;
size = tag_align.forward(size);
size = switch (mod.getTarget().ofmt) {
.c => max_align,
else => tag_align,
}.forward(size);
size += tag_size;
const prev_size = size;
size = max_align.forward(size);
Expand Down
35 changes: 22 additions & 13 deletions src/codegen/c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5032,15 +5032,18 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const result = result: {
const writer = f.object.writer();
const inst_ty = f.typeOfIndex(inst);
const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
const local = try f.allocLocal(inst, inst_ty);
const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
const inst_local = try f.allocLocalValue(.{
.ctype = try f.ctypeFromType(inst_ty, .complete),
.alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),
});
if (f.wantSafety()) {
try f.writeCValue(writer, local, .Other);
try f.writeCValue(writer, inst_local, .Other);
try writer.writeAll(" = ");
try f.writeCValue(writer, .{ .undef = inst_ty }, .Other);
try writer.writeAll(";\n");
}
break :local local;
break :local inst_local;
} else .none;

const locals_begin = @as(LocalIndex, @intCast(f.locals.items.len));
Expand All @@ -5063,9 +5066,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
if (is_reg) {
const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(zcu);
try writer.writeAll("register ");
const local_value = try f.allocLocal(inst, output_ty);
try f.allocs.put(gpa, local_value.new_local, false);
try f.object.dg.renderTypeAndName(writer, output_ty, local_value, .{}, .none, .complete);
const output_local = try f.allocLocalValue(.{
.ctype = try f.ctypeFromType(output_ty, .complete),
.alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),
});
try f.allocs.put(gpa, output_local.new_local, false);
try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete);
try writer.writeAll(" __asm(\"");
try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
try writer.writeAll("\")");
Expand Down Expand Up @@ -5095,9 +5101,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
if (asmInputNeedsLocal(f, constraint, input_val)) {
const input_ty = f.typeOf(input);
if (is_reg) try writer.writeAll("register ");
const local_value = try f.allocLocal(inst, input_ty);
try f.allocs.put(gpa, local_value.new_local, false);
try f.object.dg.renderTypeAndName(writer, input_ty, local_value, Const, .none, .complete);
const input_local = try f.allocLocalValue(.{
.ctype = try f.ctypeFromType(input_ty, .complete),
.alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),
});
try f.allocs.put(gpa, input_local.new_local, false);
try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete);
if (is_reg) {
try writer.writeAll(" __asm(\"");
try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
Expand Down Expand Up @@ -5190,7 +5199,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
try f.writeCValue(writer, .{ .local = locals_index }, .Other);
locals_index += 1;
} else if (output == .none) {
try f.writeCValue(writer, local, .FunctionArgument);
try f.writeCValue(writer, inst_local, .FunctionArgument);
} else {
try f.writeCValueDeref(writer, try f.resolveInst(output));
}
Expand Down Expand Up @@ -5246,7 +5255,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
const is_reg = constraint[1] == '{';
if (is_reg) {
try f.writeCValueDeref(writer, if (output == .none)
.{ .local_ref = local.new_local }
.{ .local_ref = inst_local.new_local }
else
try f.resolveInst(output));
try writer.writeAll(" = ");
Expand All @@ -5256,7 +5265,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
}
}

break :result if (f.liveness.isUnused(inst)) .none else local;
break :result if (f.liveness.isUnused(inst)) .none else inst_local;
};

var bt = iterateBigTomb(f, inst);
Expand Down
77 changes: 48 additions & 29 deletions src/codegen/c/Type.zig
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,8 @@ pub const Info = union(enum) {
aggregate: Aggregate,
function: Function,

const Tag = @typeInfo(Info).Union.tag_type.?;

pub const Pointer = struct {
elem_ctype: CType,
@"const": bool = false,
Expand Down Expand Up @@ -761,7 +763,7 @@ pub const Info = union(enum) {
len: u64,
};

pub const Tag = enum { @"enum", @"struct", @"union" };
pub const AggregateTag = enum { @"enum", @"struct", @"union" };

pub const Field = struct {
name: String,
Expand Down Expand Up @@ -820,15 +822,15 @@ pub const Info = union(enum) {
};

pub const FwdDecl = struct {
tag: Tag,
tag: AggregateTag,
name: union(enum) {
anon: Field.Slice,
owner_decl: DeclIndex,
},
};

pub const Aggregate = struct {
tag: Tag,
tag: AggregateTag,
@"packed": bool = false,
name: union(enum) {
anon: struct {
Expand All @@ -853,9 +855,8 @@ pub const Info = union(enum) {
rhs_pool: *const Pool,
pool_adapter: anytype,
) bool {
const InfoTag = @typeInfo(Info).Union.tag_type.?;
const rhs_info = rhs_ctype.info(rhs_pool);
if (@as(InfoTag, lhs_info) != @as(InfoTag, rhs_info)) return false;
if (@as(Info.Tag, lhs_info) != @as(Info.Tag, rhs_info)) return false;
return switch (lhs_info) {
.basic => |lhs_basic_info| lhs_basic_info == rhs_info.basic,
.pointer => |lhs_pointer_info| lhs_pointer_info.@"const" == rhs_info.pointer.@"const" and
Expand Down Expand Up @@ -1012,7 +1013,7 @@ pub const Pool = struct {
pool: *Pool,
allocator: std.mem.Allocator,
fwd_decl_info: struct {
tag: Info.Tag,
tag: Info.AggregateTag,
name: union(enum) {
anon: []const Info.Field,
owner_decl: DeclIndex,
Expand Down Expand Up @@ -1070,7 +1071,7 @@ pub const Pool = struct {
pool: *Pool,
allocator: std.mem.Allocator,
aggregate_info: struct {
tag: Info.Tag,
tag: Info.AggregateTag,
@"packed": bool = false,
name: union(enum) {
anon: struct {
Expand Down Expand Up @@ -1175,7 +1176,7 @@ pub const Pool = struct {
pub fn fromFields(
pool: *Pool,
allocator: std.mem.Allocator,
tag: Info.Tag,
tag: Info.AggregateTag,
fields: []Info.Field,
kind: Kind,
) !CType {
Expand Down Expand Up @@ -1390,8 +1391,8 @@ pub const Pool = struct {
else => |ip_index| switch (ip.indexToKey(ip_index)) {
.int_type => |int_info| return pool.fromIntInfo(allocator, int_info, mod, kind),
.ptr_type => |ptr_info| switch (ptr_info.flags.size) {
.One, .Many, .C => return pool.getPointer(allocator, .{
.elem_ctype = elem_ctype: {
.One, .Many, .C => {
const elem_ctype = elem_ctype: {
if (ptr_info.packed_offset.host_size > 0 and
ptr_info.flags.vector_index == .none)
break :elem_ctype try pool.fromIntInfo(allocator, .{
Expand All @@ -1412,13 +1413,31 @@ pub const Pool = struct {
.abi = Type.fromInterned(ptr_info.child).abiAlignment(zcu),
}),
};
if (elem.alignas.abiOrder().compare(.gte))
break :elem_ctype elem.ctype;
break :elem_ctype try pool.getAligned(allocator, elem);
},
.@"const" = ptr_info.flags.is_const,
.@"volatile" = ptr_info.flags.is_volatile,
}),
break :elem_ctype if (elem.alignas.abiOrder().compare(.gte))
elem.ctype
else
try pool.getAligned(allocator, elem);
};
const elem_tag: Info.Tag = switch (elem_ctype.info(pool)) {
.aligned => |aligned_info| aligned_info.ctype.info(pool),
else => |elem_tag| elem_tag,
};
return pool.getPointer(allocator, .{
.elem_ctype = elem_ctype,
.@"const" = switch (elem_tag) {
.basic,
.pointer,
.aligned,
.array,
.vector,
.fwd_decl,
.aggregate,
=> ptr_info.flags.is_const,
.function => false,
},
.@"volatile" = ptr_info.flags.is_volatile,
});
},
.Slice => {
const target = &mod.resolved_target.result;
var fields = [_]Info.Field{
Expand Down Expand Up @@ -1589,7 +1608,7 @@ pub const Pool = struct {
loaded_struct.field_types.len * @typeInfo(Field).Struct.fields.len,
);
var hasher = Hasher.init;
var tag: Tag = .aggregate_struct;
var tag: Pool.Tag = .aggregate_struct;
var field_it = loaded_struct.iterateRuntimeOrder(ip);
while (field_it.next()) |field_index| {
const field_type = Type.fromInterned(
Expand Down Expand Up @@ -1729,7 +1748,7 @@ pub const Pool = struct {
loaded_union.field_types.len * @typeInfo(Field).Struct.fields.len,
);
var hasher = Hasher.init;
var tag: Tag = .aggregate_union;
var tag: Pool.Tag = .aggregate_union;
var payload_align: Alignment = .@"1";
for (0..loaded_union.field_types.len) |field_index| {
const field_type = Type.fromInterned(
Expand Down Expand Up @@ -2093,7 +2112,7 @@ pub const Pool = struct {
inline for (@typeInfo(Extra).Struct.fields) |field| {
const value = @field(extra, field.name);
hasher.update(switch (field.type) {
Tag, String, CType => unreachable,
Pool.Tag, String, CType => unreachable,
CType.Index => (CType{ .index = value }).hash(pool),
String.Index => (String{ .index = value }).slice(pool),
else => value,
Expand All @@ -2102,7 +2121,7 @@ pub const Pool = struct {
}
fn update(hasher: *Hasher, data: anytype) void {
switch (@TypeOf(data)) {
Tag => @compileError("pass tag to final"),
Pool.Tag => @compileError("pass tag to final"),
CType, CType.Index => @compileError("hash ctype.hash(pool) instead"),
String, String.Index => @compileError("hash string.slice(pool) instead"),
u32, DeclIndex, Aligned.Flags => hasher.impl.update(std.mem.asBytes(&data)),
Expand All @@ -2111,7 +2130,7 @@ pub const Pool = struct {
}
}

fn final(hasher: Hasher, tag: Tag) Map.Hash {
fn final(hasher: Hasher, tag: Pool.Tag) Map.Hash {
var impl = hasher.impl;
impl.update(std.mem.asBytes(&tag));
return @truncate(impl.final());
Expand All @@ -2122,11 +2141,11 @@ pub const Pool = struct {
pool: *Pool,
allocator: std.mem.Allocator,
hasher: Hasher,
tag: Tag,
tag: Pool.Tag,
data: u32,
) !CType {
try pool.ensureUnusedCapacity(allocator, 1);
const Key = struct { hash: Map.Hash, tag: Tag, data: u32 };
const Key = struct { hash: Map.Hash, tag: Pool.Tag, data: u32 };
const CTypeAdapter = struct {
pool: *const Pool,
pub fn hash(_: @This(), key: Key) Map.Hash {
Expand All @@ -2148,7 +2167,7 @@ pub const Pool = struct {
fn tagExtra(
pool: *Pool,
allocator: std.mem.Allocator,
tag: Tag,
tag: Pool.Tag,
comptime Extra: type,
extra: Extra,
) !CType {
Expand All @@ -2166,7 +2185,7 @@ pub const Pool = struct {
pool: *Pool,
allocator: std.mem.Allocator,
hasher: Hasher,
tag: Tag,
tag: Pool.Tag,
extra_index: ExtraIndex,
) !CType {
try pool.ensureUnusedCapacity(allocator, 1);
Expand All @@ -2176,10 +2195,10 @@ pub const Pool = struct {
fn tagTrailingExtraAssumeCapacity(
pool: *Pool,
hasher: Hasher,
tag: Tag,
tag: Pool.Tag,
extra_index: ExtraIndex,
) CType {
const Key = struct { hash: Map.Hash, tag: Tag, extra: []const u32 };
const Key = struct { hash: Map.Hash, tag: Pool.Tag, extra: []const u32 };
const CTypeAdapter = struct {
pool: *const Pool,
pub fn hash(_: @This(), key: Key) Map.Hash {
Expand Down Expand Up @@ -2239,7 +2258,7 @@ pub const Pool = struct {
}

const Item = struct {
tag: Tag,
tag: Pool.Tag,
data: u32,
};

Expand Down

0 comments on commit cb5deb5

Please sign in to comment.