Skip to content

Commit b77e601

Browse files
authored
Merge pull request #23834 from jacobly0/x86_64-rewrite
x86_64: finish rewriting scalar overflow and saturate operations
2 parents 74a3ae4 + a4eabd3 commit b77e601

35 files changed

+89520
-59476
lines changed

lib/std/debug/Dwarf.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ pub const ExceptionFrameHeader = struct {
402402
}
403403
}
404404

405-
if (len == 0) return bad();
405+
if (len == 0) return missing();
406406
fbr.pos = left * entry_size;
407407

408408
// Read past the pc_begin field of the entry
@@ -460,6 +460,8 @@ pub const ExceptionFrameHeader = struct {
460460
@sizeOf(usize),
461461
native_endian,
462462
);
463+
464+
if (pc < fde.pc_begin or pc >= fde.pc_begin + fde.pc_range) return missing();
463465
}
464466
};
465467

lib/std/debug/SelfInfo.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1633,7 +1633,7 @@ pub fn unwindFrameDwarf(
16331633
&cie,
16341634
&fde,
16351635
) catch |err| switch (err) {
1636-
error.InvalidDebugInfo => {
1636+
error.MissingDebugInfo => {
16371637
// `.eh_frame_hdr` appears to be incomplete, so go ahead and populate `cie_map`
16381638
// and `fde_list`, and fall back to the binary search logic below.
16391639
try di.scanCieFdeInfo(allocator, base_address);

lib/std/math.zig

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -774,18 +774,15 @@ pub fn Log2IntCeil(comptime T: type) type {
774774
/// Returns the smallest integer type that can hold both from and to.
775775
pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) type {
776776
assert(from <= to);
777-
if (from == 0 and to == 0) {
778-
return u0;
779-
}
780777
const signedness: std.builtin.Signedness = if (from < 0) .signed else .unsigned;
781-
const largest_positive_integer = @max(if (from < 0) (-from) - 1 else from, to); // two's complement
782-
const base = log2(largest_positive_integer);
783-
const upper = (1 << base) - 1;
784-
var magnitude_bits = if (upper >= largest_positive_integer) base else base + 1;
785-
if (signedness == .signed) {
786-
magnitude_bits += 1;
787-
}
788-
return std.meta.Int(signedness, magnitude_bits);
778+
return @Type(.{ .int = .{
779+
.signedness = signedness,
780+
.bits = @as(u16, @intFromBool(signedness == .signed)) +
781+
switch (if (from < 0) @max(@abs(from) - 1, to) else to) {
782+
0 => 0,
783+
else => |pos_max| 1 + log2(pos_max),
784+
},
785+
} });
789786
}
790787

791788
test IntFittingRange {
@@ -1267,6 +1264,19 @@ pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
12671264
return @as(Log2Int(T), @intCast(@typeInfo(T).int.bits - 1 - @clz(x)));
12681265
}
12691266

1267+
test log2_int {
1268+
try testing.expect(log2_int(u32, 1) == 0);
1269+
try testing.expect(log2_int(u32, 2) == 1);
1270+
try testing.expect(log2_int(u32, 3) == 1);
1271+
try testing.expect(log2_int(u32, 4) == 2);
1272+
try testing.expect(log2_int(u32, 5) == 2);
1273+
try testing.expect(log2_int(u32, 6) == 2);
1274+
try testing.expect(log2_int(u32, 7) == 2);
1275+
try testing.expect(log2_int(u32, 8) == 3);
1276+
try testing.expect(log2_int(u32, 9) == 3);
1277+
try testing.expect(log2_int(u32, 10) == 3);
1278+
}
1279+
12701280
/// Return the log base 2 of integer value x, rounding up to the
12711281
/// nearest integer.
12721282
pub fn log2_int_ceil(comptime T: type, x: T) Log2IntCeil(T) {

lib/std/math/big/int.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,12 +415,12 @@ pub const Mutable = struct {
415415
// in the case that scalar happens to be small in magnitude within its type, but it
416416
// is well worth being able to use the stack and not needing an allocator passed in.
417417
// Note that Mutable.init still sets len to calcLimbLen(scalar) in any case.
418-
const limb_len = comptime switch (@typeInfo(@TypeOf(scalar))) {
418+
const limbs_len = comptime switch (@typeInfo(@TypeOf(scalar))) {
419419
.comptime_int => calcLimbLen(scalar),
420420
.int => |info| calcTwosCompLimbCount(info.bits),
421421
else => @compileError("expected scalar to be an int"),
422422
};
423-
var limbs: [limb_len]Limb = undefined;
423+
var limbs: [limbs_len]Limb = undefined;
424424
const operand = init(&limbs, scalar).toConst();
425425
return add(r, a, operand);
426426
}
@@ -2454,12 +2454,12 @@ pub const Const = struct {
24542454
// in the case that scalar happens to be small in magnitude within its type, but it
24552455
// is well worth being able to use the stack and not needing an allocator passed in.
24562456
// Note that Mutable.init still sets len to calcLimbLen(scalar) in any case.
2457-
const limb_len = comptime switch (@typeInfo(@TypeOf(scalar))) {
2457+
const limbs_len = comptime switch (@typeInfo(@TypeOf(scalar))) {
24582458
.comptime_int => calcLimbLen(scalar),
24592459
.int => |info| calcTwosCompLimbCount(info.bits),
24602460
else => @compileError("expected scalar to be an int"),
24612461
};
2462-
var limbs: [limb_len]Limb = undefined;
2462+
var limbs: [limbs_len]Limb = undefined;
24632463
const rhs = Mutable.init(&limbs, scalar);
24642464
return order(lhs, rhs.toConst());
24652465
}

lib/std/math/big/int_test.zig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,8 +2295,6 @@ test "sat shift-left signed simple positive" {
22952295
}
22962296

22972297
test "sat shift-left signed multi positive" {
2298-
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
2299-
23002298
var x: SignedDoubleLimb = 1;
23012299
_ = &x;
23022300

@@ -2310,8 +2308,6 @@ test "sat shift-left signed multi positive" {
23102308
}
23112309

23122310
test "sat shift-left signed multi negative" {
2313-
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
2314-
23152311
var x: SignedDoubleLimb = -1;
23162312
_ = &x;
23172313

lib/std/math/log2.zig

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@ const expect = std.testing.expect;
1212
/// - log2(nan) = nan
1313
pub fn log2(x: anytype) @TypeOf(x) {
1414
const T = @TypeOf(x);
15-
switch (@typeInfo(T)) {
16-
.comptime_float => {
17-
return @as(comptime_float, @log2(x));
18-
},
19-
.float => return @log2(x),
15+
return switch (@typeInfo(T)) {
16+
.comptime_float, .float => @log2(x),
2017
.comptime_int => comptime {
18+
std.debug.assert(x > 0);
2119
var x_shifted = x;
2220
// First, calculate floorPowerOfTwo(x)
2321
var shift_amt = 1;
@@ -34,12 +32,15 @@ pub fn log2(x: anytype) @TypeOf(x) {
3432
}
3533
return result;
3634
},
37-
.int => |IntType| switch (IntType.signedness) {
38-
.signed => @compileError("log2 not implemented for signed integers"),
39-
.unsigned => return math.log2_int(T, x),
40-
},
35+
.int => |int_info| math.log2_int(switch (int_info.signedness) {
36+
.signed => @Type(.{ .int = .{
37+
.signedness = .unsigned,
38+
.bits = int_info.bits -| 1,
39+
} }),
40+
.unsigned => T,
41+
}, @intCast(x)),
4142
else => @compileError("log2 not implemented for " ++ @typeName(T)),
42-
}
43+
};
4344
}
4445

4546
test log2 {

lib/std/zig/Zir.zig

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2142,7 +2142,7 @@ pub const Inst = struct {
21422142
ref_start_index = static_len,
21432143
_,
21442144

2145-
pub const static_len = 97;
2145+
pub const static_len = 101;
21462146

21472147
pub fn toRef(i: Index) Inst.Ref {
21482148
return @enumFromInt(@intFromEnum(Index.ref_start_index) + @intFromEnum(i));
@@ -2225,6 +2225,7 @@ pub const Inst = struct {
22252225
single_const_pointer_to_comptime_int_type,
22262226
slice_const_u8_type,
22272227
slice_const_u8_sentinel_0_type,
2228+
vector_8_i8_type,
22282229
vector_16_i8_type,
22292230
vector_32_i8_type,
22302231
vector_1_u8_type,
@@ -2233,8 +2234,10 @@ pub const Inst = struct {
22332234
vector_8_u8_type,
22342235
vector_16_u8_type,
22352236
vector_32_u8_type,
2237+
vector_4_i16_type,
22362238
vector_8_i16_type,
22372239
vector_16_i16_type,
2240+
vector_4_u16_type,
22382241
vector_8_u16_type,
22392242
vector_16_u16_type,
22402243
vector_4_i32_type,
@@ -2245,6 +2248,7 @@ pub const Inst = struct {
22452248
vector_4_i64_type,
22462249
vector_2_u64_type,
22472250
vector_4_u64_type,
2251+
vector_2_u128_type,
22482252
vector_4_f16_type,
22492253
vector_8_f16_type,
22502254
vector_2_f32_type,

lib/zig.h

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,14 +1115,15 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t
11151115
\
11161116
static inline uint##w##_t zig_shls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
11171117
uint##w##_t res; \
1118-
if (rhs >= bits) return lhs != UINT##w##_C(0) ? zig_maxInt_u(w, bits) : lhs; \
1119-
return zig_shlo_u##w(&res, lhs, (uint8_t)rhs, bits) ? zig_maxInt_u(w, bits) : res; \
1118+
if (rhs < bits && !zig_shlo_u##w(&res, lhs, rhs, bits)) return res; \
1119+
return lhs == INT##w##_C(0) ? INT##w##_C(0) : zig_maxInt_u(w, bits); \
11201120
} \
11211121
\
1122-
static inline int##w##_t zig_shls_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
1122+
static inline int##w##_t zig_shls_i##w(int##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
11231123
int##w##_t res; \
1124-
if ((uint##w##_t)rhs < (uint##w##_t)bits && !zig_shlo_i##w(&res, lhs, (uint8_t)rhs, bits)) return res; \
1125-
return lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1124+
if (rhs < bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \
1125+
return lhs == INT##w##_C(0) ? INT##w##_C(0) : \
1126+
lhs < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
11261127
} \
11271128
\
11281129
static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
@@ -1851,15 +1852,23 @@ static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8
18511852

18521853
static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
18531854
zig_u128 res;
1854-
if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) >= INT32_C(0))
1855-
return zig_cmp_u128(lhs, zig_make_u128(0, 0)) != INT32_C(0) ? zig_maxInt_u(128, bits) : lhs;
1856-
return zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits) ? zig_maxInt_u(128, bits) : res;
1855+
if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
1856+
switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) {
1857+
case 0: return zig_make_u128(0, 0);
1858+
case 1: return zig_maxInt_u(128, bits);
1859+
default: zig_unreachable();
1860+
}
18571861
}
18581862

1859-
static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
1863+
static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) {
18601864
zig_i128 res;
1861-
if (zig_cmp_u128(zig_bitCast_u128(rhs), zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_i128(rhs), bits)) return res;
1862-
return zig_cmp_i128(lhs, zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
1865+
if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
1866+
switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) {
1867+
case -1: return zig_minInt_i(128, bits);
1868+
case 0: return zig_make_i128(0, 0);
1869+
case 1: return zig_maxInt_i(128, bits);
1870+
default: zig_unreachable();
1871+
}
18631872
}
18641873

18651874
static inline zig_u128 zig_adds_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {

src/Air.zig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,9 @@ pub const Inst = struct {
257257
/// it shifts out any bits that disagree with the resultant sign bit.
258258
/// Uses the `bin_op` field.
259259
shl_exact,
260-
/// Saturating integer shift left. `<<|`
260+
/// Saturating integer shift left. `<<|`. The result is the same type as the `lhs`.
261+
/// The `rhs` must have the same vector shape as the `lhs`, but with any unsigned
262+
/// integer as the scalar type.
261263
/// Uses the `bin_op` field.
262264
shl_sat,
263265
/// Bitwise XOR. `^`
@@ -995,6 +997,7 @@ pub const Inst = struct {
995997
single_const_pointer_to_comptime_int_type = @intFromEnum(InternPool.Index.single_const_pointer_to_comptime_int_type),
996998
slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
997999
slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
1000+
vector_8_i8_type = @intFromEnum(InternPool.Index.vector_8_i8_type),
9981001
vector_16_i8_type = @intFromEnum(InternPool.Index.vector_16_i8_type),
9991002
vector_32_i8_type = @intFromEnum(InternPool.Index.vector_32_i8_type),
10001003
vector_1_u8_type = @intFromEnum(InternPool.Index.vector_1_u8_type),
@@ -1003,8 +1006,10 @@ pub const Inst = struct {
10031006
vector_8_u8_type = @intFromEnum(InternPool.Index.vector_8_u8_type),
10041007
vector_16_u8_type = @intFromEnum(InternPool.Index.vector_16_u8_type),
10051008
vector_32_u8_type = @intFromEnum(InternPool.Index.vector_32_u8_type),
1009+
vector_4_i16_type = @intFromEnum(InternPool.Index.vector_4_i16_type),
10061010
vector_8_i16_type = @intFromEnum(InternPool.Index.vector_8_i16_type),
10071011
vector_16_i16_type = @intFromEnum(InternPool.Index.vector_16_i16_type),
1012+
vector_4_u16_type = @intFromEnum(InternPool.Index.vector_4_u16_type),
10081013
vector_8_u16_type = @intFromEnum(InternPool.Index.vector_8_u16_type),
10091014
vector_16_u16_type = @intFromEnum(InternPool.Index.vector_16_u16_type),
10101015
vector_4_i32_type = @intFromEnum(InternPool.Index.vector_4_i32_type),
@@ -1015,6 +1020,7 @@ pub const Inst = struct {
10151020
vector_4_i64_type = @intFromEnum(InternPool.Index.vector_4_i64_type),
10161021
vector_2_u64_type = @intFromEnum(InternPool.Index.vector_2_u64_type),
10171022
vector_4_u64_type = @intFromEnum(InternPool.Index.vector_4_u64_type),
1023+
vector_2_u128_type = @intFromEnum(InternPool.Index.vector_2_u128_type),
10181024
vector_4_f16_type = @intFromEnum(InternPool.Index.vector_4_f16_type),
10191025
vector_8_f16_type = @intFromEnum(InternPool.Index.vector_8_f16_type),
10201026
vector_2_f32_type = @intFromEnum(InternPool.Index.vector_2_f32_type),

src/InternPool.zig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4572,6 +4572,7 @@ pub const Index = enum(u32) {
45724572
slice_const_u8_type,
45734573
slice_const_u8_sentinel_0_type,
45744574

4575+
vector_8_i8_type,
45754576
vector_16_i8_type,
45764577
vector_32_i8_type,
45774578
vector_1_u8_type,
@@ -4580,8 +4581,10 @@ pub const Index = enum(u32) {
45804581
vector_8_u8_type,
45814582
vector_16_u8_type,
45824583
vector_32_u8_type,
4584+
vector_4_i16_type,
45834585
vector_8_i16_type,
45844586
vector_16_i16_type,
4587+
vector_4_u16_type,
45854588
vector_8_u16_type,
45864589
vector_16_u16_type,
45874590
vector_4_i32_type,
@@ -4592,6 +4595,7 @@ pub const Index = enum(u32) {
45924595
vector_4_i64_type,
45934596
vector_2_u64_type,
45944597
vector_4_u64_type,
4598+
vector_2_u128_type,
45954599
vector_4_f16_type,
45964600
vector_8_f16_type,
45974601
vector_2_f32_type,
@@ -5090,6 +5094,8 @@ pub const static_keys = [_]Key{
50905094
},
50915095
} },
50925096

5097+
// @Vector(8, i8)
5098+
.{ .vector_type = .{ .len = 8, .child = .i8_type } },
50935099
// @Vector(16, i8)
50945100
.{ .vector_type = .{ .len = 16, .child = .i8_type } },
50955101
// @Vector(32, i8)
@@ -5106,10 +5112,14 @@ pub const static_keys = [_]Key{
51065112
.{ .vector_type = .{ .len = 16, .child = .u8_type } },
51075113
// @Vector(32, u8)
51085114
.{ .vector_type = .{ .len = 32, .child = .u8_type } },
5115+
// @Vector(4, i16)
5116+
.{ .vector_type = .{ .len = 4, .child = .i16_type } },
51095117
// @Vector(8, i16)
51105118
.{ .vector_type = .{ .len = 8, .child = .i16_type } },
51115119
// @Vector(16, i16)
51125120
.{ .vector_type = .{ .len = 16, .child = .i16_type } },
5121+
// @Vector(4, u16)
5122+
.{ .vector_type = .{ .len = 4, .child = .u16_type } },
51135123
// @Vector(8, u16)
51145124
.{ .vector_type = .{ .len = 8, .child = .u16_type } },
51155125
// @Vector(16, u16)
@@ -5130,6 +5140,8 @@ pub const static_keys = [_]Key{
51305140
.{ .vector_type = .{ .len = 2, .child = .u64_type } },
51315141
// @Vector(8, u64)
51325142
.{ .vector_type = .{ .len = 4, .child = .u64_type } },
5143+
// @Vector(2, u128)
5144+
.{ .vector_type = .{ .len = 2, .child = .u128_type } },
51335145
// @Vector(4, f16)
51345146
.{ .vector_type = .{ .len = 4, .child = .f16_type } },
51355147
// @Vector(8, f16)
@@ -11777,6 +11789,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1177711789
.single_const_pointer_to_comptime_int_type,
1177811790
.slice_const_u8_type,
1177911791
.slice_const_u8_sentinel_0_type,
11792+
.vector_8_i8_type,
1178011793
.vector_16_i8_type,
1178111794
.vector_32_i8_type,
1178211795
.vector_1_u8_type,
@@ -11785,8 +11798,10 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1178511798
.vector_8_u8_type,
1178611799
.vector_16_u8_type,
1178711800
.vector_32_u8_type,
11801+
.vector_4_i16_type,
1178811802
.vector_8_i16_type,
1178911803
.vector_16_i16_type,
11804+
.vector_4_u16_type,
1179011805
.vector_8_u16_type,
1179111806
.vector_16_u16_type,
1179211807
.vector_4_i32_type,
@@ -11797,6 +11812,7 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1179711812
.vector_4_i64_type,
1179811813
.vector_2_u64_type,
1179911814
.vector_4_u64_type,
11815+
.vector_2_u128_type,
1180011816
.vector_4_f16_type,
1180111817
.vector_8_f16_type,
1180211818
.vector_2_f32_type,
@@ -12121,6 +12137,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1212112137
.slice_const_u8_sentinel_0_type,
1212212138
=> .pointer,
1212312139

12140+
.vector_8_i8_type,
1212412141
.vector_16_i8_type,
1212512142
.vector_32_i8_type,
1212612143
.vector_1_u8_type,
@@ -12129,8 +12146,10 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1212912146
.vector_8_u8_type,
1213012147
.vector_16_u8_type,
1213112148
.vector_32_u8_type,
12149+
.vector_4_i16_type,
1213212150
.vector_8_i16_type,
1213312151
.vector_16_i16_type,
12152+
.vector_4_u16_type,
1213412153
.vector_8_u16_type,
1213512154
.vector_16_u16_type,
1213612155
.vector_4_i32_type,
@@ -12141,6 +12160,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1214112160
.vector_4_i64_type,
1214212161
.vector_2_u64_type,
1214312162
.vector_4_u64_type,
12163+
.vector_2_u128_type,
1214412164
.vector_4_f16_type,
1214512165
.vector_8_f16_type,
1214612166
.vector_2_f32_type,

0 commit comments

Comments
 (0)