Merge pull request #18179 from jacobly0/x86_64

x86_64: pass more behavior tests
This commit is contained in:
Jacob Young 2023-12-04 18:37:39 -05:00 committed by GitHub
commit c357b902b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 611 additions and 343 deletions

View File

@ -9069,7 +9069,7 @@ fn handleExternLibName(
block: *Block,
src_loc: LazySrcLoc,
lib_name: []const u8,
) CompileError![:0]u8 {
) CompileError!void {
blk: {
const mod = sema.mod;
const comp = mod.comp;
@ -9117,7 +9117,6 @@ fn handleExternLibName(
});
};
}
return sema.gpa.dupeZ(u8, lib_name);
}
/// These are calling conventions that are confirmed to work with variadic functions.
@ -9422,15 +9421,13 @@ fn funcCommon(
assert(section != .generic);
assert(address_space != null);
assert(!is_generic);
if (opt_lib_name) |lib_name| try sema.handleExternLibName(block, .{
.node_offset_lib_name = src_node_offset,
}, lib_name);
const func_index = try ip.getExternFunc(gpa, .{
.ty = func_ty,
.decl = sema.owner_decl_index,
.lib_name = if (opt_lib_name) |lib_name| (try mod.intern_pool.getOrPutString(
gpa,
try sema.handleExternLibName(block, .{
.node_offset_lib_name = src_node_offset,
}, lib_name),
)).toOptional() else .none,
.lib_name = try mod.intern_pool.getOrPutStringOpt(gpa, opt_lib_name),
});
return finishFunc(
sema,
@ -24688,10 +24685,11 @@ fn zirVarExtended(
var extra_index: usize = extra.end;
const lib_name: ?[]const u8 = if (small.has_lib_name) blk: {
const lib_name = if (small.has_lib_name) lib_name: {
const lib_name = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
extra_index += 1;
break :blk lib_name;
try sema.handleExternLibName(block, ty_src, lib_name);
break :lib_name lib_name;
} else null;
// ZIR supports encoding this information but it is not used; the information
@ -24729,10 +24727,7 @@ fn zirVarExtended(
.ty = var_ty.toIntern(),
.init = init_val,
.decl = sema.owner_decl_index,
.lib_name = if (lib_name) |lname| (try mod.intern_pool.getOrPutString(
sema.gpa,
try sema.handleExternLibName(block, ty_src, lname),
)).toOptional() else .none,
.lib_name = try mod.intern_pool.getOrPutStringOpt(sema.gpa, lib_name),
.is_extern = small.is_extern,
.is_threadlocal = small.is_threadlocal,
} })));
@ -25177,12 +25172,13 @@ fn resolveExternOptions(
.needed_comptime_reason = "threadlocality of the extern symbol must be comptime-known",
});
const library_name = if (library_name_val.optionalValue(mod)) |payload| blk: {
const library_name = try payload.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
const library_name = if (library_name_val.optionalValue(mod)) |library_name_payload| library_name: {
const library_name = try library_name_payload.toAllocatedBytes(Type.slice_const_u8, sema.arena, mod);
if (library_name.len == 0) {
return sema.fail(block, library_src, "library name cannot be empty", .{});
}
break :blk try sema.handleExternLibName(block, library_src, library_name);
try sema.handleExternLibName(block, library_src, library_name);
break :library_name library_name;
} else null;
if (name.len == 0) {

File diff suppressed because it is too large Load Diff

View File

@ -389,7 +389,47 @@ pub fn generateSymbol(
},
},
.vector_type => |vector_type| {
switch (aggregate.storage) {
const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse
return error.Overflow;
if (Type.fromInterned(vector_type.child).bitSize(mod) == 1) {
const bytes = try code.addManyAsSlice(abi_size);
@memset(bytes, 0xaa);
var index: usize = 0;
const len = math.cast(usize, vector_type.len) orelse return error.Overflow;
while (index < len) : (index += 1) {
const bit_index = switch (endian) {
.big => len - 1 - index,
.little => index,
};
const byte = &bytes[bit_index / 8];
const mask = @as(u8, 1) << @truncate(bit_index);
if (switch (switch (aggregate.storage) {
.bytes => unreachable,
.elems => |elems| elems[index],
.repeated_elem => |elem| elem,
}) {
.bool_true => true,
.bool_false => false,
else => |elem| switch (mod.intern_pool.indexToKey(elem)) {
.undef => continue,
.int => |int| switch (int.storage) {
.u64 => |x| switch (x) {
0 => false,
1 => true,
else => unreachable,
},
.i64 => |x| switch (x) {
-1 => true,
0 => false,
else => unreachable,
},
else => unreachable,
},
else => unreachable,
},
}) byte.* |= mask else byte.* &= ~mask;
}
} else switch (aggregate.storage) {
.bytes => |bytes| try code.appendSlice(bytes),
.elems, .repeated_elem => {
var index: u64 = 0;
@ -398,7 +438,9 @@ pub fn generateSymbol(
.ty = Type.fromInterned(vector_type.child),
.val = Value.fromInterned(switch (aggregate.storage) {
.bytes => unreachable,
.elems => |elems| elems[@as(usize, @intCast(index))],
.elems => |elems| elems[
math.cast(usize, index) orelse return error.Overflow
],
.repeated_elem => |elem| elem,
}),
}, code, debug_output, reloc_info)) {
@ -409,11 +451,14 @@ pub fn generateSymbol(
},
}
const padding = math.cast(usize, typed_value.ty.abiSize(mod) -
(math.divCeil(u64, Type.fromInterned(vector_type.child).bitSize(mod) * vector_type.len, 8) catch |err| switch (err) {
const padding = abi_size - (math.cast(usize, math.divCeil(
u64,
Type.fromInterned(vector_type.child).bitSize(mod) * vector_type.len,
8,
) catch |err| switch (err) {
error.DivisionByZero => unreachable,
else => |e| return e,
})) orelse return error.Overflow;
}) orelse return error.Overflow);
if (padding > 0) try code.appendNTimes(0, padding);
},
.anon_struct_type => |tuple| {

View File

@ -316,6 +316,8 @@ pub fn deinit(self: *Coff) void {
}
self.import_tables.deinit(gpa);
self.lazy_syms.deinit(gpa);
for (self.decls.values()) |*metadata| {
metadata.deinit(gpa);
}

Binary file not shown.

View File

@ -97,7 +97,7 @@ const Writer = struct {
const tag = w.air.instructions.items(.tag)[@intFromEnum(inst)];
try s.writeByteNTimes(' ', w.indent);
try s.print("%{d}{c}= {s}(", .{
inst,
@intFromEnum(inst),
@as(u8, if (if (w.liveness) |liveness| liveness.isUnused(inst) else false) '!' else ' '),
@tagName(tag),
});
@ -388,7 +388,7 @@ const Writer = struct {
try s.writeAll("}");
for (liveness_block.deaths) |operand| {
try s.print(" %{d}!", .{operand});
try s.print(" %{d}!", .{@intFromEnum(operand)});
}
}
@ -715,7 +715,7 @@ const Writer = struct {
try s.writeByteNTimes(' ', w.indent);
for (liveness_condbr.else_deaths, 0..) |operand, i| {
if (i != 0) try s.writeAll(" ");
try s.print("%{d}!", .{operand});
try s.print("%{d}!", .{@intFromEnum(operand)});
}
try s.writeAll("\n");
}
@ -726,7 +726,7 @@ const Writer = struct {
try s.writeAll("}");
for (liveness_condbr.then_deaths) |operand| {
try s.print(" %{d}!", .{operand});
try s.print(" %{d}!", .{@intFromEnum(operand)});
}
}
@ -752,7 +752,7 @@ const Writer = struct {
try s.writeByteNTimes(' ', w.indent);
for (liveness_condbr.else_deaths, 0..) |operand, i| {
if (i != 0) try s.writeAll(" ");
try s.print("%{d}!", .{operand});
try s.print("%{d}!", .{@intFromEnum(operand)});
}
try s.writeAll("\n");
}
@ -763,7 +763,7 @@ const Writer = struct {
try s.writeAll("}");
for (liveness_condbr.then_deaths) |operand| {
try s.print(" %{d}!", .{operand});
try s.print(" %{d}!", .{@intFromEnum(operand)});
}
}
@ -787,7 +787,7 @@ const Writer = struct {
try s.writeByteNTimes(' ', w.indent);
for (liveness_condbr.then_deaths, 0..) |operand, i| {
if (i != 0) try s.writeAll(" ");
try s.print("%{d}!", .{operand});
try s.print("%{d}!", .{@intFromEnum(operand)});
}
try s.writeAll("\n");
}
@ -800,7 +800,7 @@ const Writer = struct {
try s.writeByteNTimes(' ', w.indent);
for (liveness_condbr.else_deaths, 0..) |operand, i| {
if (i != 0) try s.writeAll(" ");
try s.print("%{d}!", .{operand});
try s.print("%{d}!", .{@intFromEnum(operand)});
}
try s.writeAll("\n");
}
@ -852,7 +852,7 @@ const Writer = struct {
try s.writeByteNTimes(' ', w.indent);
for (deaths, 0..) |operand, i| {
if (i != 0) try s.writeAll(" ");
try s.print("%{d}!", .{operand});
try s.print("%{d}!", .{@intFromEnum(operand)});
}
try s.writeAll("\n");
}
@ -873,7 +873,7 @@ const Writer = struct {
try s.writeByteNTimes(' ', w.indent);
for (deaths, 0..) |operand, i| {
if (i != 0) try s.writeAll(" ");
try s.print("%{d}!", .{operand});
try s.print("%{d}!", .{@intFromEnum(operand)});
}
try s.writeAll("\n");
}
@ -957,7 +957,7 @@ const Writer = struct {
dies: bool,
) @TypeOf(s).Error!void {
_ = w;
try s.print("%{d}", .{inst});
try s.print("%{d}", .{@intFromEnum(inst)});
if (dies) try s.writeByte('!');
}

View File

@ -208,7 +208,6 @@ fn testAtomicStore() !void {
}
test "atomicrmw with floats" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
@ -316,7 +315,6 @@ test "atomicrmw with 128-bit ints" {
if (!supports_128_bit_atomics) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
// TODO "ld.lld: undefined symbol: __sync_lock_test_and_set_16" on -mcpu x86_64
if (builtin.cpu.arch == .x86_64 and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;

View File

@ -393,7 +393,6 @@ test "bitcast vector to integer and back" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;

View File

@ -9,8 +9,7 @@ fn ctz(x: anytype) usize {
test "fixed" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64 and
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .bmi)) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO

View File

@ -336,7 +336,6 @@ test "array coercion to undefined at runtime" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
@setRuntimeSafety(true);
@ -1477,7 +1476,7 @@ test "coerce between pointers of compatible differently-named floats" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
if (builtin.os.tag == .windows) {
if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
// https://github.com/ziglang/zig/issues/12396
return error.SkipZigTest;
}
@ -1724,7 +1723,6 @@ test "peer type resolution: array and vector with same child type" {
test "peer type resolution: array with smaller child type and vector with larger child type" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
@ -2312,11 +2310,11 @@ test "cast builtins can wrap result in error union and optional" {
test "@floatCast on vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -2333,7 +2331,6 @@ test "@floatCast on vector" {
test "@ptrFromInt on vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
@ -2358,7 +2355,6 @@ test "@ptrFromInt on vector" {
test "@intFromPtr on vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
@ -2383,11 +2379,11 @@ test "@intFromPtr on vector" {
test "@floatFromInt on vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -2404,7 +2400,6 @@ test "@floatFromInt on vector" {
test "@intFromFloat on vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
@ -2425,7 +2420,6 @@ test "@intFromFloat on vector" {
test "@intFromBool on vector" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO

View File

@ -28,7 +28,6 @@ test "undefined 128 bit int" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
@setRuntimeSafety(true);

View File

@ -78,12 +78,11 @@ fn testClz() !void {
}
test "@clz big ints" {
if (builtin.zig_backend == .stage2_x86_64 and
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .lzcnt)) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
try testClzBigInts();
try comptime testClzBigInts();
@ -1610,8 +1609,9 @@ test "vector comparison" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64 and
!comptime std.Target.x86.featureSetHas(builtin.cpu.features, .avx2)) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {

View File

@ -804,7 +804,6 @@ test "nested packed struct at non-zero offset" {
}
test "nested packed struct at non-zero offset 2" {
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO

View File

@ -49,7 +49,6 @@ test "vector wrap operators" {
test "vector bin compares with mem.eql" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
@ -222,7 +221,7 @@ test "array to vector with element type coercion" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@ -1234,7 +1233,6 @@ test "array of vectors is copied" {
test "byte vector initialized in inline function" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO