Skip to content

Commit 585e418

Browse files
committed
x86_64: increase passing test coverage on windows
Now that codegen has no references to linker state this is much easier. Closes #24153
1 parent aa73e01 commit 585e418

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+12364
-7958
lines changed

lib/compiler_rt/stack_probe.zig

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -127,23 +127,23 @@ fn win_probe_stack_only() void {
127127
},
128128
.x86_64 => {
129129
asm volatile (
130-
\\ push %%rcx
131-
\\ push %%rax
132-
\\ cmp $0x1000,%%rax
133-
\\ lea 24(%%rsp),%%rcx
130+
\\ pushq %%rcx
131+
\\ pushq %%rax
132+
\\ cmpq $0x1000,%%rax
133+
\\ leaq 24(%%rsp),%%rcx
134134
\\ jb 1f
135135
\\ 2:
136-
\\ sub $0x1000,%%rcx
137-
\\ test %%rcx,(%%rcx)
138-
\\ sub $0x1000,%%rax
139-
\\ cmp $0x1000,%%rax
136+
\\ subq $0x1000,%%rcx
137+
\\ testq %%rcx,(%%rcx)
138+
\\ subq $0x1000,%%rax
139+
\\ cmpq $0x1000,%%rax
140140
\\ ja 2b
141141
\\ 1:
142-
\\ sub %%rax,%%rcx
143-
\\ test %%rcx,(%%rcx)
144-
\\ pop %%rax
145-
\\ pop %%rcx
146-
\\ ret
142+
\\ subq %%rax,%%rcx
143+
\\ testq %%rcx,(%%rcx)
144+
\\ popq %%rax
145+
\\ popq %%rcx
146+
\\ retq
147147
);
148148
},
149149
.x86 => {
@@ -179,26 +179,26 @@ fn win_probe_stack_adjust_sp() void {
179179
switch (arch) {
180180
.x86_64 => {
181181
asm volatile (
182-
\\ push %%rcx
183-
\\ cmp $0x1000,%%rax
184-
\\ lea 16(%%rsp),%%rcx
182+
\\ pushq %%rcx
183+
\\ cmpq $0x1000,%%rax
184+
\\ leaq 16(%%rsp),%%rcx
185185
\\ jb 1f
186186
\\ 2:
187-
\\ sub $0x1000,%%rcx
188-
\\ test %%rcx,(%%rcx)
189-
\\ sub $0x1000,%%rax
190-
\\ cmp $0x1000,%%rax
187+
\\ subq $0x1000,%%rcx
188+
\\ testq %%rcx,(%%rcx)
189+
\\ subq $0x1000,%%rax
190+
\\ cmpq $0x1000,%%rax
191191
\\ ja 2b
192192
\\ 1:
193-
\\ sub %%rax,%%rcx
194-
\\ test %%rcx,(%%rcx)
193+
\\ subq %%rax,%%rcx
194+
\\ testq %%rcx,(%%rcx)
195195
\\
196-
\\ lea 8(%%rsp),%%rax
197-
\\ mov %%rcx,%%rsp
198-
\\ mov -8(%%rax),%%rcx
199-
\\ push (%%rax)
200-
\\ sub %%rsp,%%rax
201-
\\ ret
196+
\\ leaq 8(%%rsp),%%rax
197+
\\ movq %%rcx,%%rsp
198+
\\ movq -8(%%rax),%%rcx
199+
\\ pushq (%%rax)
200+
\\ subq %%rsp,%%rax
201+
\\ retq
202202
);
203203
},
204204
.x86 => {

lib/std/math/float.zig

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -220,42 +220,61 @@ pub inline fn floatEpsAt(comptime T: type, x: T) T {
220220
}
221221
}
222222

223-
/// Returns the value inf for floating point type T.
224-
pub inline fn inf(comptime T: type) T {
225-
return reconstructFloat(T, floatExponentMax(T) + 1, mantissaOne(T));
223+
/// Returns the inf value for a floating point `Type`.
224+
pub inline fn inf(comptime Type: type) Type {
225+
const RuntimeType = switch (Type) {
226+
else => Type,
227+
comptime_float => f128, // any float type will do
228+
};
229+
return reconstructFloat(RuntimeType, floatExponentMax(RuntimeType) + 1, mantissaOne(RuntimeType));
226230
}
227231

228-
/// Returns the canonical quiet NaN representation for floating point type T.
229-
pub inline fn nan(comptime T: type) T {
232+
/// Returns the canonical quiet NaN representation for a floating point `Type`.
233+
pub inline fn nan(comptime Type: type) Type {
234+
const RuntimeType = switch (Type) {
235+
else => Type,
236+
comptime_float => f128, // any float type will do
237+
};
230238
return reconstructFloat(
231-
T,
232-
floatExponentMax(T) + 1,
233-
mantissaOne(T) | 1 << (floatFractionalBits(T) - 1),
239+
RuntimeType,
240+
floatExponentMax(RuntimeType) + 1,
241+
mantissaOne(RuntimeType) | 1 << (floatFractionalBits(RuntimeType) - 1),
234242
);
235243
}
236244

237-
/// Returns a signalling NaN representation for floating point type T.
245+
/// Returns a signalling NaN representation for a floating point `Type`.
238246
///
239247
/// TODO: LLVM is known to miscompile on some architectures to quiet NaN -
240248
/// this is tracked by https://github.com/ziglang/zig/issues/14366
241-
pub inline fn snan(comptime T: type) T {
249+
pub inline fn snan(comptime Type: type) Type {
250+
const RuntimeType = switch (Type) {
251+
else => Type,
252+
comptime_float => f128, // any float type will do
253+
};
242254
return reconstructFloat(
243-
T,
244-
floatExponentMax(T) + 1,
245-
mantissaOne(T) | 1 << (floatFractionalBits(T) - 2),
255+
RuntimeType,
256+
floatExponentMax(RuntimeType) + 1,
257+
mantissaOne(RuntimeType) | 1 << (floatFractionalBits(RuntimeType) - 2),
246258
);
247259
}
248260

249-
test "float bits" {
250-
inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| {
251-
// (1 +) for the sign bit, since it is separate from the other bits
252-
const size = 1 + floatExponentBits(T) + floatMantissaBits(T);
253-
try expect(@bitSizeOf(T) == size);
261+
fn floatBits(comptime Type: type) !void {
262+
// (1 +) for the sign bit, since it is separate from the other bits
263+
const size = 1 + floatExponentBits(Type) + floatMantissaBits(Type);
264+
try expect(@bitSizeOf(Type) == size);
265+
try expect(floatFractionalBits(Type) <= floatMantissaBits(Type));
254266

255-
// for machine epsilon, assert expmin <= -prec <= expmax
256-
try expect(floatExponentMin(T) <= -floatFractionalBits(T));
257-
try expect(-floatFractionalBits(T) <= floatExponentMax(T));
258-
}
267+
// for machine epsilon, assert expmin <= -prec <= expmax
268+
try expect(floatExponentMin(Type) <= -floatFractionalBits(Type));
269+
try expect(-floatFractionalBits(Type) <= floatExponentMax(Type));
270+
}
271+
test floatBits {
272+
try floatBits(f16);
273+
try floatBits(f32);
274+
try floatBits(f64);
275+
try floatBits(f80);
276+
try floatBits(f128);
277+
try floatBits(c_longdouble);
259278
}
260279

261280
test inf {

lib/std/math/signbit.zig

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,47 @@ const expect = std.testing.expect;
44

55
/// Returns whether x is negative or negative 0.
66
pub fn signbit(x: anytype) bool {
7-
const T = @TypeOf(x);
8-
const TBits = std.meta.Int(.unsigned, @typeInfo(T).float.bits);
9-
return @as(TBits, @bitCast(x)) >> (@bitSizeOf(T) - 1) != 0;
7+
return switch (@typeInfo(@TypeOf(x))) {
8+
.int, .comptime_int => x,
9+
.float => |float| @as(@Type(.{ .int = .{
10+
.signedness = .signed,
11+
.bits = float.bits,
12+
} }), @bitCast(x)),
13+
.comptime_float => @as(i128, @bitCast(@as(f128, x))), // any float type will do
14+
else => @compileError("std.math.signbit does not support " ++ @typeName(@TypeOf(x))),
15+
} < 0;
1016
}
1117

1218
test signbit {
13-
inline for ([_]type{ f16, f32, f64, f80, f128 }) |T| {
14-
try expect(!signbit(@as(T, 0.0)));
15-
try expect(!signbit(@as(T, 1.0)));
16-
try expect(signbit(@as(T, -2.0)));
17-
try expect(signbit(@as(T, -0.0)));
18-
try expect(!signbit(math.inf(T)));
19-
try expect(signbit(-math.inf(T)));
20-
try expect(!signbit(math.nan(T)));
21-
try expect(signbit(-math.nan(T)));
22-
}
19+
try testInts(i0);
20+
try testInts(u0);
21+
try testInts(i1);
22+
try testInts(u1);
23+
try testInts(i2);
24+
try testInts(u2);
25+
26+
try testFloats(f16);
27+
try testFloats(f32);
28+
try testFloats(f64);
29+
try testFloats(f80);
30+
try testFloats(f128);
31+
try testFloats(c_longdouble);
32+
try testFloats(comptime_float);
33+
}
34+
35+
fn testInts(comptime Type: type) !void {
36+
try expect((std.math.minInt(Type) < 0) == signbit(@as(Type, std.math.minInt(Type))));
37+
try expect(!signbit(@as(Type, 0)));
38+
try expect(!signbit(@as(Type, std.math.maxInt(Type))));
39+
}
40+
41+
fn testFloats(comptime Type: type) !void {
42+
try expect(!signbit(@as(Type, 0.0)));
43+
try expect(!signbit(@as(Type, 1.0)));
44+
try expect(signbit(@as(Type, -2.0)));
45+
try expect(signbit(@as(Type, -0.0)));
46+
try expect(!signbit(math.inf(Type)));
47+
try expect(signbit(-math.inf(Type)));
48+
try expect(!signbit(math.nan(Type)));
49+
try expect(signbit(-math.nan(Type)));
2350
}

lib/std/posix.zig

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7571,7 +7571,10 @@ const lfs64_abi = native_os == .linux and builtin.link_libc and (builtin.abi.isG
75717571
/// If this happens the fix is to add the error code to the corresponding
75727572
/// switch expression, possibly introduce a new error in the error set, and
75737573
/// send a patch to Zig.
7574-
pub const unexpected_error_tracing = builtin.zig_backend == .stage2_llvm and builtin.mode == .Debug;
7574+
pub const unexpected_error_tracing = builtin.mode == .Debug and switch (builtin.zig_backend) {
7575+
.stage2_llvm, .stage2_x86_64 => true,
7576+
else => false,
7577+
};
75757578

75767579
pub const UnexpectedError = error{
75777580
/// The Operating System returned an undocumented error code.

lib/std/start.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ fn _start() callconv(.naked) noreturn {
485485
}
486486

487487
fn WinStartup() callconv(.withStackAlign(.c, 1)) noreturn {
488+
// Switch from the x87 fpu state set by windows to the state expected by the gnu abi.
489+
if (builtin.abi == .gnu) asm volatile ("fninit");
490+
488491
if (!builtin.single_threaded and !builtin.link_libc) {
489492
_ = @import("os/windows/tls.zig");
490493
}
@@ -495,6 +498,9 @@ fn WinStartup() callconv(.withStackAlign(.c, 1)) noreturn {
495498
}
496499

497500
fn wWinMainCRTStartup() callconv(.withStackAlign(.c, 1)) noreturn {
501+
// Switch from the x87 fpu state set by windows to the state expected by the gnu abi.
502+
if (builtin.abi == .gnu) asm volatile ("fninit");
503+
498504
if (!builtin.single_threaded and !builtin.link_libc) {
499505
_ = @import("os/windows/tls.zig");
500506
}

src/Air/Legalize.zig

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,10 @@ pub const Feature = enum {
122122

123123
/// Legalize (shift lhs, (splat rhs)) -> (shift lhs, rhs)
124124
unsplat_shift_rhs,
125-
/// Legalize reduce of a one element vector to a bitcast
125+
/// Legalize reduce of a one element vector to a bitcast.
126126
reduce_one_elem_to_bitcast,
127+
/// Legalize splat to a one element vector to a bitcast.
128+
splat_one_elem_to_bitcast,
127129

128130
/// Replace `intcast_safe` with an explicit safety check which `call`s the panic function on failure.
129131
/// Not compatible with `scalarize_intcast_safe`.
@@ -628,7 +630,17 @@ fn legalizeBody(l: *Legalize, body_start: usize, body_len: usize) Error!void {
628630
else => {},
629631
}
630632
},
631-
.splat => {},
633+
.splat => if (l.features.has(.splat_one_elem_to_bitcast)) {
634+
const ty_op = l.air_instructions.items(.data)[@intFromEnum(inst)].ty_op;
635+
switch (ty_op.ty.toType().vectorLen(zcu)) {
636+
0 => unreachable,
637+
1 => continue :inst l.replaceInst(inst, .bitcast, .{ .ty_op = .{
638+
.ty = ty_op.ty,
639+
.operand = ty_op.operand,
640+
} }),
641+
else => {},
642+
}
643+
},
632644
.shuffle_one => if (l.features.has(.scalarize_shuffle_one)) continue :inst try l.scalarize(inst, .shuffle_one),
633645
.shuffle_two => if (l.features.has(.scalarize_shuffle_two)) continue :inst try l.scalarize(inst, .shuffle_two),
634646
.select => if (l.features.has(.scalarize_select)) continue :inst try l.scalarize(inst, .select),

src/arch/riscv64/CodeGen.zig

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5962,10 +5962,14 @@ fn airBr(func: *Func, inst: Air.Inst.Index) !void {
59625962
if (first_br) break :result src_mcv;
59635963

59645964
try func.getValue(block_tracking.short, br.block_inst);
5965-
// .long = .none to avoid merging operand and block result stack frames.
5966-
const current_tracking: InstTracking = .{ .long = .none, .short = src_mcv };
5967-
try current_tracking.materializeUnsafe(func, br.block_inst, block_tracking.*);
5968-
for (current_tracking.getRegs()) |src_reg| func.register_manager.freeReg(src_reg);
5965+
try InstTracking.materializeUnsafe(
5966+
// .long = .none to avoid merging operand and block result stack frames.
5967+
.{ .long = .none, .short = src_mcv },
5968+
func,
5969+
br.block_inst,
5970+
block_tracking.*,
5971+
);
5972+
try func.freeValue(src_mcv);
59695973
break :result block_tracking.short;
59705974
}
59715975

@@ -8192,8 +8196,11 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
81928196
const lf = func.bin_file;
81938197
const src_loc = func.src_loc;
81948198

8195-
const result = if (val.isUndef(pt.zcu))
8196-
try lf.lowerUav(pt, val.toIntern(), .none, src_loc)
8199+
const result: codegen.GenResult = if (val.isUndef(pt.zcu))
8200+
switch (try lf.lowerUav(pt, val.toIntern(), .none, src_loc)) {
8201+
.sym_index => |sym_index| .{ .mcv = .{ .load_symbol = sym_index } },
8202+
.fail => |em| .{ .fail = em },
8203+
}
81978204
else
81988205
try codegen.genTypedValue(lf, pt, src_loc, val, func.target);
81998206
const mcv: MCValue = switch (result) {

0 commit comments

Comments
 (0)