Skip to content

Commit 8c8dfb3

Browse files
committed
x86_64: fix crashes compiling the compiler and tests
1 parent c3d3344 commit 8c8dfb3

File tree

8 files changed

+445
-389
lines changed

8 files changed

+445
-389
lines changed

lib/std/Thread.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,11 @@ pub const SpawnConfig = struct {
372372
// https://github.com/ziglang/zig/issues/157
373373

374374
/// Size in bytes of the Thread's stack
375-
stack_size: usize = 16 * 1024 * 1024,
375+
stack_size: usize = default_stack_size,
376376
/// The allocator to be used to allocate memory for the to-be-spawned thread
377377
allocator: ?std.mem.Allocator = null,
378+
379+
pub const default_stack_size = 16 * 1024 * 1024;
378380
};
379381

380382
pub const SpawnError = error{

lib/std/Thread/Pool.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub const Options = struct {
2727
allocator: std.mem.Allocator,
2828
n_jobs: ?usize = null,
2929
track_ids: bool = false,
30+
stack_size: usize = std.Thread.SpawnConfig.default_stack_size,
3031
};
3132

3233
pub fn init(pool: *Pool, options: Options) !void {
@@ -54,7 +55,10 @@ pub fn init(pool: *Pool, options: Options) !void {
5455
errdefer pool.join(spawned);
5556

5657
for (pool.threads) |*thread| {
57-
thread.* = try std.Thread.spawn(.{}, worker, .{pool});
58+
thread.* = try std.Thread.spawn(.{
59+
.stack_size = options.stack_size,
60+
.allocator = allocator,
61+
}, worker, .{pool});
5862
spawned += 1;
5963
}
6064
}

lib/std/crypto/aes/aesni.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const mem = std.mem;
44
const debug = std.debug;
55

66
const has_vaes = builtin.cpu.arch == .x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .vaes);
7-
const has_avx512f = builtin.cpu.arch == .x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f);
7+
const has_avx512f = builtin.cpu.arch == .x86_64 and builtin.zig_backend != .stage2_x86_64 and std.Target.x86.featureSetHas(builtin.cpu.features, .avx512f);
88

99
/// A single AES block.
1010
pub const Block = struct {

src/arch/x86_64/CodeGen.zig

Lines changed: 389 additions & 329 deletions
Large diffs are not rendered by default.

src/arch/x86_64/abi.zig

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,12 @@ pub fn getCAbiSseReturnRegs(cc: std.builtin.CallingConvention.Tag) []const Regis
540540
}
541541

542542
pub fn getCAbiLinkerScratchReg(cc: std.builtin.CallingConvention.Tag) Register {
543-
const int_return_regs = getCAbiIntReturnRegs(cc);
544-
return int_return_regs[int_return_regs.len - 1];
543+
return switch (cc) {
544+
.auto => zigcc.int_return_regs[zigcc.int_return_regs.len - 1],
545+
.x86_64_sysv => SysV.c_abi_int_return_regs[0],
546+
.x86_64_win => Win64.c_abi_int_return_regs[0],
547+
else => unreachable,
548+
};
545549
}
546550

547551
const gp_regs = [_]Register{

src/main.zig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ test {
3939
_ = Package;
4040
}
4141

42+
const thread_stack_size = switch (builtin.zig_backend) {
43+
else => std.Thread.SpawnConfig.default_stack_size,
44+
.stage2_x86_64 => 32 << 20,
45+
};
46+
4247
pub const std_options: std.Options = .{
4348
.wasiCwd = wasi_cwd,
4449
.logFn = log,
@@ -3320,6 +3325,7 @@ fn buildOutputType(
33203325
.allocator = gpa,
33213326
.n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
33223327
.track_ids = true,
3328+
.stack_size = thread_stack_size,
33233329
});
33243330
defer thread_pool.deinit();
33253331

@@ -5024,6 +5030,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
50245030
.allocator = gpa,
50255031
.n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
50265032
.track_ids = true,
5033+
.stack_size = thread_stack_size,
50275034
});
50285035
defer thread_pool.deinit();
50295036

@@ -5460,6 +5467,7 @@ fn jitCmd(
54605467
.allocator = gpa,
54615468
.n_jobs = @min(@max(std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
54625469
.track_ids = true,
5470+
.stack_size = thread_stack_size,
54635471
});
54645472
defer thread_pool.deinit();
54655473

src/register_manager.zig

Lines changed: 23 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,6 @@ pub fn RegisterManager(
5858
return @alignCast(@fieldParentPtr("register_manager", self));
5959
}
6060

61-
fn excludeRegister(reg: Register, register_class: RegisterBitSet) bool {
62-
const index = indexOfRegIntoTracked(reg) orelse return true;
63-
return !register_class.isSet(index);
64-
}
65-
6661
fn markRegIndexAllocated(self: *Self, tracked_index: TrackedIndex) void {
6762
self.allocated_registers.set(tracked_index);
6863
}
@@ -234,28 +229,20 @@ pub fn RegisterManager(
234229
) ?[count]Register {
235230
comptime assert(count > 0 and count <= tracked_registers.len);
236231

237-
var free_and_not_locked_registers = self.free_registers;
238-
free_and_not_locked_registers.setIntersection(register_class);
239-
240-
var unlocked_registers = self.locked_registers;
241-
unlocked_registers.toggleAll();
242-
243-
free_and_not_locked_registers.setIntersection(unlocked_registers);
244-
245-
if (free_and_not_locked_registers.count() < count) return null;
232+
var free_and_unlocked_registers = self.locked_registers;
233+
free_and_unlocked_registers.toggleAll();
234+
free_and_unlocked_registers.setIntersection(self.free_registers);
235+
free_and_unlocked_registers.setIntersection(register_class);
246236

247237
var regs: [count]Register = undefined;
248238
var i: usize = 0;
249-
for (tracked_registers) |reg| {
250-
if (i >= count) break;
251-
if (excludeRegister(reg, register_class)) continue;
252-
if (self.isRegLocked(reg)) continue;
253-
if (!self.isRegFree(reg)) continue;
254-
255-
regs[i] = reg;
239+
var it = free_and_unlocked_registers.iterator(.{});
240+
while (it.next()) |reg_index| {
241+
regs[i] = regAtTrackedIndex(@intCast(reg_index));
256242
i += 1;
243+
if (i >= count) break;
257244
}
258-
assert(i == count);
245+
if (i < count) return null;
259246

260247
for (regs, insts) |reg, inst| {
261248
log.debug("tryAllocReg {} for inst {?}", .{ reg, inst });
@@ -290,46 +277,27 @@ pub fn RegisterManager(
290277
) AllocationError![count]Register {
291278
comptime assert(count > 0 and count <= tracked_registers.len);
292279

293-
var locked_registers = self.locked_registers;
294-
locked_registers.setIntersection(register_class);
295-
296-
if (count > register_class.count() - locked_registers.count()) return error.OutOfRegisters;
297-
298280
const result = self.tryAllocRegs(count, insts, register_class) orelse blk: {
281+
var unlocked_registers = self.locked_registers;
282+
unlocked_registers.toggleAll();
283+
unlocked_registers.setIntersection(register_class);
284+
299285
// We'll take over the first count registers. Spill
300286
// the instructions that were previously there to a
301287
// stack allocations.
302288
var regs: [count]Register = undefined;
303289
var i: usize = 0;
304-
for (tracked_registers) |reg| {
305-
if (i >= count) break;
306-
if (excludeRegister(reg, register_class)) break;
307-
if (self.isRegLocked(reg)) continue;
308-
309-
log.debug("allocReg {} for inst {?}", .{ reg, insts[i] });
310-
regs[i] = reg;
311-
self.markRegAllocated(reg);
312-
const index = indexOfRegIntoTracked(reg).?; // indexOfReg() on a callee-preserved reg should never return null
313-
if (insts[i]) |inst| {
314-
// Track the register
315-
if (self.isRegFree(reg)) {
316-
self.markRegUsed(reg);
317-
} else {
318-
const spilled_inst = self.registers[index];
319-
try self.getFunction().spillInstruction(reg, spilled_inst);
320-
}
321-
self.registers[index] = inst;
322-
} else {
323-
// Don't track the register
324-
if (!self.isRegFree(reg)) {
325-
const spilled_inst = self.registers[index];
326-
try self.getFunction().spillInstruction(reg, spilled_inst);
327-
self.freeReg(reg);
328-
}
329-
}
330-
290+
var it = unlocked_registers.iterator(.{});
291+
while (it.next()) |reg_index| {
292+
const tracked_index: TrackedIndex = @intCast(reg_index);
293+
if (!self.isRegIndexFree(tracked_index) and
294+
self.registers[tracked_index].unwrap() == .target) continue;
295+
try self.getRegIndex(tracked_index, insts[i]);
296+
regs[i] = regAtTrackedIndex(tracked_index);
331297
i += 1;
298+
if (i >= count) break;
332299
}
300+
if (i < count) return error.OutOfRegisters;
333301

334302
break :blk regs;
335303
};
@@ -351,7 +319,7 @@ pub fn RegisterManager(
351319
/// Spills the register if it is currently allocated. If a
352320
/// corresponding instruction is passed, will also track this
353321
/// register.
354-
fn getRegIndex(
322+
pub fn getRegIndex(
355323
self: *Self,
356324
tracked_index: TrackedIndex,
357325
inst: ?Air.Inst.Index,

test/behavior/x86_64/math.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,16 @@ fn testBinary(comptime op: anytype) !void {
742742
0xb7935f5c2f3b1ae7a422c0a7c446884294b7d5370bada307d2fe5a4c4284a999,
743743
0x310e6e196ba4f143b8d285ca6addf7f3bb3344224aff221b27607a31e148be08,
744744
);
745+
try testType(
746+
u258,
747+
0x186d5ddaab8cb8cb04e5b41e36f812e039d008baf49f12894c39e29a07796d800,
748+
0x2072daba6ffad168826163eb136f6d28ca4360c8e7e5e41e29755e19e4753a4f5,
749+
);
750+
try testType(
751+
u495,
752+
0x6eaf4e252b3bf74b75bac59e0b43ca5326bad2a25b3fdb74a67ef132ac5e47d72eebc3316fb2351ee66c50dc5afb92a75cea9b0e35160652c7db39eeb158,
753+
0x49fbed744a92b549d8c05bb3512c617d24dd824f3f69bdf3923bc326a75674b85f5b828d2566fab9c86f571d12c2a63c9164feb0d191d27905533d09622a,
754+
);
745755
try testType(
746756
u512,
747757
0xe5b1fedca3c77db765e517aabd05ffc524a3a8aff1784bbf67c45b894447ede32b65b9940e78173c591e56e078932d465f235aece7ad47b7f229df7ba8f12295,

0 commit comments

Comments
 (0)