Sema: Improve comptime arithmetic undef handling
This commit expands on the foundations laid by https://github.com/ziglang/zig/pull/23177 and moves even more `Sema`-only functionality from `Value` to `Sema.arith`. Specifically all shift and bitwise operations, `@truncate`, `@bitReverse` and `@byteSwap` have been moved and adapted to the new rules around `undefined`. Especially the comptime shift operations have been basically rewritten, fixing many open issues in the process. New rules applied to operators: * `<<`, `@shlExact`, `@shlWithOverflow`, `>>`, `@shrExact`: compile error if any operand is undef * `<<|`, `~`, `^`, `@truncate`, `@bitReverse`, `@byteSwap`: return undef if any operand is undef * `&`, `|`: Return undef if both operands are undef, turn undef into actual `0xAA` bytes otherwise Additionally this commit canonicalizes the representation of aggregates with all-undefined members in the `InternPool` by disallowing them and enforcing the usage of a single typed `undef` value instead. This reduces the amount of edge cases and fixes a bunch of bugs related to partially undefined vecs. List of operations directly affected by this patch: * `<<`, `<<|`, `@shlExact`, `@shlWithOverflow` * `>>`, `@shrExact` * `&`, `|`, `~`, `^` and their atomic rmw + reduce pendants * `@truncate`, `@bitReverse`, `@byteSwap`
This commit is contained in:
@@ -154,12 +154,6 @@ test "Saturating Shift Left where lhs is of a computed type" {
|
||||
try expect(value.exponent == 0);
|
||||
}
|
||||
|
||||
comptime {
|
||||
var image: [1]u8 = undefined;
|
||||
_ = ℑ
|
||||
_ = @shlExact(@as(u16, image[0]), 8);
|
||||
}
|
||||
|
||||
test "Saturating Shift Left" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
@@ -202,3 +196,10 @@ test "Saturating Shift Left" {
|
||||
try expectEqual(170141183460469231731687303715884105727, S.shlSat(@as(i128, 0x2fe6bc5448c55ce18252e2c9d4477750), 0x31));
|
||||
try expectEqual(0, S.shlSat(@as(i128, 0), 127));
|
||||
}
|
||||
|
||||
test "shift by partially undef vector" {
|
||||
comptime {
|
||||
const a: @Vector(1, u8) = .{undefined};
|
||||
_ = a >> @splat(4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,9 @@ export fn d(rhs: @Vector(3, i32)) void {
|
||||
//
|
||||
// :2:25: error: shift by negative amount '-1'
|
||||
// :7:12: error: shift by negative amount '-2'
|
||||
// :11:47: error: shift by negative amount '-3' at index '0'
|
||||
// :16:27: error: shift by negative amount '-4' at index '1'
|
||||
// :11:47: error: shift by negative amount '-3'
|
||||
// :11:47: note: when computing vector element at index '0'
|
||||
// :16:27: error: shift by negative amount '-4'
|
||||
// :16:27: note: when computing vector element at index '1'
|
||||
// :20:25: error: shift by signed type 'i32'
|
||||
// :24:40: error: shift by signed type '@Vector(3, i32)'
|
||||
|
||||
10
test/cases/compile_errors/shift_by_larger_than_usize.zig
Normal file
10
test/cases/compile_errors/shift_by_larger_than_usize.zig
Normal file
@@ -0,0 +1,10 @@
|
||||
export fn f() usize {
|
||||
const a = comptime 0 <<| (1 << @bitSizeOf(usize));
|
||||
return a;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2,llvm
|
||||
// target=x86_64-linux
|
||||
//
|
||||
// :2:30: error: this implementation only supports comptime shift amounts of up to 2^64 - 1 bits
|
||||
@@ -7,4 +7,4 @@ comptime {
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:15: error: operation caused overflow
|
||||
// :2:25: error: overflow of integer type 'u8' with value '340'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user