Skip to content

Commit 6d7d21a

Browse files
committed
x86_64: fix crashes compiling the compiler and tests
1 parent 9091729 commit 6d7d21a

File tree

8 files changed

+443
-388
lines changed

8 files changed

+443
-388
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: 387 additions & 328 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,
@@ -3316,6 +3321,7 @@ fn buildOutputType(
33163321
.allocator = gpa,
33173322
.n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
33183323
.track_ids = true,
3324+
.stack_size = thread_stack_size,
33193325
});
33203326
defer thread_pool.deinit();
33213327

@@ -5020,6 +5026,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
50205026
.allocator = gpa,
50215027
.n_jobs = @min(@max(n_jobs orelse std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
50225028
.track_ids = true,
5029+
.stack_size = thread_stack_size,
50235030
});
50245031
defer thread_pool.deinit();
50255032

@@ -5456,6 +5463,7 @@ fn jitCmd(
54565463
.allocator = gpa,
54575464
.n_jobs = @min(@max(std.Thread.getCpuCount() catch 1, 1), std.math.maxInt(Zcu.PerThread.IdBacking)),
54585465
.track_ids = true,
5466+
.stack_size = thread_stack_size,
54595467
});
54605468
defer thread_pool.deinit();
54615469

src/register_manager.zig

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

66-
fn excludeRegister(reg: Register, register_class: RegisterBitSet) bool {
67-
const index = indexOfRegIntoTracked(reg) orelse return true;
68-
return !register_class.isSet(index);
69-
}
70-
7166
fn markRegIndexAllocated(self: *Self, tracked_index: TrackedIndex) void {
7267
self.allocated_registers.set(tracked_index);
7368
}
@@ -239,28 +234,20 @@ pub fn RegisterManager(
239234
) ?[count]Register {
240235
comptime assert(count > 0 and count <= tracked_registers.len);
241236

242-
var free_and_not_locked_registers = self.free_registers;
243-
free_and_not_locked_registers.setIntersection(register_class);
244-
245-
var unlocked_registers = self.locked_registers;
246-
unlocked_registers.toggleAll();
247-
248-
free_and_not_locked_registers.setIntersection(unlocked_registers);
249-
250-
if (free_and_not_locked_registers.count() < count) return null;
237+
var free_and_unlocked_registers = self.locked_registers;
238+
free_and_unlocked_registers.toggleAll();
239+
free_and_unlocked_registers.setIntersection(self.free_registers);
240+
free_and_unlocked_registers.setIntersection(register_class);
251241

252242
var regs: [count]Register = undefined;
253243
var i: usize = 0;
254-
for (tracked_registers) |reg| {
255-
if (i >= count) break;
256-
if (excludeRegister(reg, register_class)) continue;
257-
if (self.isRegLocked(reg)) continue;
258-
if (!self.isRegFree(reg)) continue;
259-
260-
regs[i] = reg;
244+
var it = free_and_unlocked_registers.iterator(.{});
245+
while (it.next()) |reg_index| {
246+
regs[i] = regAtTrackedIndex(@intCast(reg_index));
261247
i += 1;
248+
if (i >= count) break;
262249
}
263-
assert(i == count);
250+
if (i < count) return null;
264251

265252
for (regs, insts) |reg, inst| {
266253
log.debug("tryAllocReg {} for inst {?}", .{ reg, inst });
@@ -295,46 +282,27 @@ pub fn RegisterManager(
295282
) AllocateRegistersError![count]Register {
296283
comptime assert(count > 0 and count <= tracked_registers.len);
297284

298-
var locked_registers = self.locked_registers;
299-
locked_registers.setIntersection(register_class);
300-
301-
if (count > register_class.count() - locked_registers.count()) return error.OutOfRegisters;
302-
303285
const result = self.tryAllocRegs(count, insts, register_class) orelse blk: {
286+
var unlocked_registers = self.locked_registers;
287+
unlocked_registers.toggleAll();
288+
unlocked_registers.setIntersection(register_class);
289+
304290
// We'll take over the first count registers. Spill
305291
// the instructions that were previously there to a
306292
// stack allocations.
307293
var regs: [count]Register = undefined;
308294
var i: usize = 0;
309-
for (tracked_registers) |reg| {
310-
if (i >= count) break;
311-
if (excludeRegister(reg, register_class)) break;
312-
if (self.isRegLocked(reg)) continue;
313-
314-
log.debug("allocReg {} for inst {?}", .{ reg, insts[i] });
315-
regs[i] = reg;
316-
self.markRegAllocated(reg);
317-
const index = indexOfRegIntoTracked(reg).?; // indexOfReg() on a callee-preserved reg should never return null
318-
if (insts[i]) |inst| {
319-
// Track the register
320-
if (self.isRegFree(reg)) {
321-
self.markRegUsed(reg);
322-
} else {
323-
const spilled_inst = self.registers[index];
324-
try self.getFunction().spillInstruction(reg, spilled_inst);
325-
}
326-
self.registers[index] = inst;
327-
} else {
328-
// Don't track the register
329-
if (!self.isRegFree(reg)) {
330-
const spilled_inst = self.registers[index];
331-
try self.getFunction().spillInstruction(reg, spilled_inst);
332-
self.freeReg(reg);
333-
}
334-
}
335-
295+
var it = unlocked_registers.iterator(.{});
296+
while (it.next()) |reg_index| {
297+
const tracked_index: TrackedIndex = @intCast(reg_index);
298+
if (!self.isRegIndexFree(tracked_index) and
299+
self.registers[tracked_index].unwrap() == .target) continue;
300+
try self.getRegIndex(tracked_index, insts[i]);
301+
regs[i] = regAtTrackedIndex(tracked_index);
336302
i += 1;
303+
if (i >= count) break;
337304
}
305+
if (i < count) return error.OutOfRegisters;
338306

339307
break :blk regs;
340308
};
@@ -356,7 +324,7 @@ pub fn RegisterManager(
356324
/// Spills the register if it is currently allocated. If a
357325
/// corresponding instruction is passed, will also track this
358326
/// register.
359-
fn getRegIndex(
327+
pub fn getRegIndex(
360328
self: *Self,
361329
tracked_index: TrackedIndex,
362330
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)