159 Commits
Author SHA1 Message Date
Andrew Kelley def373ed78 Merge pull request 'llvm: pass some behavior tests (30%) for spirv target' (#37300) from alichraghi/zig:llvm-spirv into master
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37300
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
2026-10-24 22:34:19 +02:00
Ali Cheraghi b60a4af44c llvm: fix blocking issues to get tests running 2026-10-23 09:18:03 +03:30
CMDRZero 64e4f9db8f Implement partially ordered operator precedence 2026-10-22 12:21:43 +02:00
Jacob Young 54a25d8256 Type: fix vector size mismatch vs clang
This operation used to be implied by the old incorrect alignment
calculation, but seems to apply even when the alignment is saturated.

Closes #37110
2026-10-08 01:15:20 +02:00
Brian Ferri 25cafe0b34 spirv: fix vector casts, packed field pointers and debug names of comptime-known values (#37040)
I'm writing a small numeric library whose kernels run on the CPU, on CUDA and on Vulkan through the self-hosted SPIR-V backend, and I was making them generic over the float type. `f64` needs its own `exp` and `log` on the GPU, so I wrote them as polynomial series, and the `f64` Vulkan module stopped validating. This fixes the three backend bugs underneath that, and a crash I ran into after merging master.

The series take floats apart with `@bitCast` on vectors. Between vectors of the same length this reaches the Vulkan/OpenGL fallback in `bitCast`, which stores the source into a function variable of the destination type:

```zig
export fn main() callconv(.{ .spirv_kernel = .{ .x = 1, .y = 1, .z = 1 } }) void {
    var x: @Vector(2, f32) = .{ 1, 2 };
    _ = &x;
    const bits: @Vector(2, i32) = @bitCast(x);
    _ = bits;
}
```

```
$ zig build-exe -fno-llvm -target spirv64-vulkan -mcpu vulkan_v1_2 bitcast.zig -femit-bin=bitcast.spv
$ spirv-val --target-env vulkan1.2 bitcast.spv
error: line 45: OpStore Pointer <id> '36[%36]'s type does not match Object <id> '29[%29]'s type.
```

An elementwise vector bitcast is now a scalar `bitCast` per lane, the way `buildConvert` and friends already unroll vectors. Going through the scalar path also normalizes lanes of strange integers: a single `OpBitcast` on the whole vector validates for `@Vector(n, u3)` to `@Vector(n, i3)`, but leaves lanes that don't compare equal to the negative values they should hold.

The series also convert between integer and float lanes. A vector of one lane, or of more than four without `vector16`, is an array in SPIR-V, and `airFloatFromInt` and `airIntFromFloat` emitted a single `OpConvert*` with that array as its result type:

```zig
export fn main() callconv(.{ .spirv_kernel = .{ .x = 1, .y = 1, .z = 1 } }) void {
    var x: @Vector(1, i32) = .{1};
    _ = &x;
    const y: @Vector(1, f32) = @floatFromInt(x);
    _ = y;
}
```

```
$ spirv-val --target-env vulkan1.2 convert.spv
error: line 40: Expected float scalar or vector type as Result Type: ConvertSToF
  %y = OpConvertSToF %_arr_f32_u32_1 %26
```

`@floatCast` and `@intCast` already go through `buildConvert`, which unrolls the vector; these two now do as well, with `buildConvert` picking the int/float conversion opcodes.

The coefficients sit in a comptime array that the series take as a comptime slice, and that alone fails to compile, although nothing reads the slice at runtime:

```zig
const weights = [_]f32{ 1, 2, 3 };

inline fn first(comptime w: []const f32) f32 {
    return w[0];
}

export fn main() callconv(.{ .spirv_kernel = .{ .x = 1, .y = 1, .z = 1 } }) void {
    var x: f32 = first(&weights);
    _ = &x;
}
```

```
$ zig build-exe -fno-llvm -target spirv64-vulkan -mcpu vulkan_v1_2 dbgvar.zig -femit-bin=dbgvar.spv
dbgvar.zig:7:8: error: TODO (SPIR-V): pointer to constant 'dbgvar.weights'
```

It appears `airDbgVar` lowers the operand only to attach an `OpName` to it, and a pointer to a non-extern constant is still a TODO. A comptime-known value has no runtime variable of its own to name, so `airDbgVar` now leaves interned operands alone. The same thing held back 58 of the behavior tests skipped on SPIR-V, and the test commit un-skips them.

After merging master, four of those tests crashed the compiler in `structFieldPtr`, which has `unreachable` for packed containers since ebb8683ef1 ([#36996](https://codeberg.org/ziglang/zig/pulls/36996)):

```zig
const Flags = packed struct { a: bool, b: bool };

export fn main() callconv(.{ .spirv_kernel = .{ .x = 1, .y = 1, .z = 1 } }) void {
    var flags: Flags = .{ .a = true, .b = false };
    const b = &flags.b;
    b.* = true;
}
```

```
thread 3961624 panic: reached unreachable code
src/codegen/spirv/CodeGen.zig:6906:27: 0x4767157 in structFieldPtr (main.zig)
            .@"packed" => unreachable,
```

My reading is that the `unreachable` holds for the pointer derivations it was written for, since `constantPtr` now turns packed pointers into pointers to their host integer first, but `airStructFieldPtr` and `airStructFieldPtrIndex` still pass packed structs through. A pointer to a packed field is a bit-pointer into the struct's own host integer, so it is the struct pointer: that is what the old code computed, and what the C backend now does with `.begin`. Packed unions get back the TODO error they had before. I may be missing a plan for packed field pointers here, and I'm happy to change it if so. The commit also un-skips three packed tests that crash on master the same way. I suppose nothing caught this because those tests are skipped on SPIR-V and the `spirv64-vulkan` behavior target is commented out in `test/tests.zig`.

I ran the behavior tests through `tools/unskip_spirv_tests.zig` and [zig-spirv-test-executor](https://github.com/Snektron/zig-spirv-test-executor) on a Radeon 680M, and the new and un-skipped tests on an RTX 4060 as well. Every fix has tests that fail on master and pass with it; the vector ones compare lane by lane, since `expectEqual` on vectors doesn't compile for SPIR-V yet. Running each behavior file whole, nothing that passes on master fails. Five more skips already pass on master without these changes, so I left them out, but I can add them. The new vector tests copy the aarch64, arm, sparc64 and riscv64 skips of the tests around them, which I couldn't check.

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/37040
Reviewed-by: Ali Cheraghi <alichraghi@noreply.codeberg.org>
2026-10-04 11:50:49 +02:00
Ali Cheraghi 65b95b0af4 add unskip_spirv_tests.zig tool 2026-09-18 16:36:24 +03:30
Ali Cheraghi 827c3d528c test: unskip 72 passing behavior tests for spirv backend 2026-07-05 14:47:00 +03:30
Ali Cheraghi bae68c8a45 test: unskip passing behavior tests for spirv backend 2026-06-28 18:25:43 +02:00
Ali Cheraghi 65e74dfbda @extern: add flat decoration 2026-06-18 13:38:58 +02:00
Ali Cheraghi 4653794852 spirv: implement switch with ranges and loop_switch_br switch_dispatch 2026-06-18 13:38:58 +02:00
Ali Cheraghi 9115f88386 test: skip failing/crashing behavior tests for spirv backend
tested with `-target spirv64-vulkan` and `-mcpu vulkan_v1_2+float16+variable_pointers+float64+int64`
2026-06-14 09:11:59 +02:00
Krzysztof Wolicki 9e80795623 all: update to use new std.lang.Type definitions 2026-05-27 10:03:51 +01:00
Matthew Lugg a3d2f2999f tests: add new tests
Some for bugs which have been fixed, some for language changes.
2026-03-10 11:28:36 +00:00
Pavel Verigo cc099afca5 sema: fix error_return_trace_index handling in zirCondBr 2025-12-07 07:20:59 +01:00
Jacob Young 2fdf0e29b3 aarch64: enable fixed behavior 2025-09-20 18:33:00 -07:00
Jacob Young b26e732bd0 aarch64: fix error union constants 2025-07-27 08:01:07 -04:00
Jacob Young 7894703ee7 aarch64: implement more optional/error union/union support 2025-07-26 21:39:50 -04:00
Jacob Young 69abc945e4 aarch64: implement some safety checks
Closes #24553
2025-07-26 17:31:04 -04:00
Jacob Young 5060ab99c9 aarch64: add new from scratch self-hosted backend 2025-07-22 19:43:47 -07:00
Andrew Kelley 7eae26d608 delete bad behavior test
behavior tests must not depend on std.io
2025-07-07 22:43:51 -07:00
Bingwu Zhang e8d6ecb9ce riscv64: skip failing tests 2025-06-28 06:47:09 +08:00
Ali Cheraghi 872f68c9cb rename spirv backend name
`stage2_spirv64` -> `stage2_spirv`
2025-06-16 13:22:19 +03:30
Pavel Verigo a429d04ba9 stage2-wasm: enable already working tests 2025-03-24 14:59:58 +01:00
Ali Cheraghi aec0f9b3e7 test: skip failing tests with spirv-vulkan 2025-02-24 19:39:42 +01:00
mlugg 5317d88414 Sema: fix @errorCast with error unions
Resolves: #20169
2025-02-05 21:17:40 +00:00
mlugg cac814cf58 Sema: fix comparison between error set and comptime-known error union
Resolves: #20613
2025-02-05 20:13:56 +00:00
mlugg 0fe3fd01dd std: update std.builtin.Type fields to follow naming conventions
The compiler actually doesn't need any functional changes for this: Sema
does reification based on the tag indices of `std.builtin.Type` already!
So, no zig1.wasm update is necessary.

This change is necessary to disallow name clashes between fields and
decls on a type, which is a prerequisite of #9938.
2024-08-28 08:39:59 +01:00
David Rubin 8da212c11b riscv: update tests and fix reuse bug 2024-07-26 04:19:58 -07:00
David Rubin b533e848a2 riscv: enable passing tests 2024-07-26 04:19:17 -07:00
David Rubin 7a02878f4e riscv: truncate airStructFieldVal result 2024-07-14 23:02:33 -07:00
David Rubin e60c581147 test: disable-enable riscv tests 2024-06-13 04:42:26 -07:00
David Rubin 4fd8900337 riscv: rewrite "binOp"
Reorganize how the binOp and genBinOp functions work.

I've spent quite a while here reading exactly through the spec and so many
tests are enabled because of several critical issues the old design had.

There are some regressions that will take a long time to figure out individually
so I will ignore them for now, and pray they get fixed by themselves. When
we're closer to 100% passing is when I will start diving into them one-by-one.
2024-06-13 02:24:39 -07:00
David Rubin a270c6f8c8 riscv: implement optional logic 2024-06-13 02:22:33 -07:00
David Rubin 083b7b483e riscv: zero registers when using register-wide operations
what was happening is that instructions like `lb` were only affecting the lower bytes of the register and leaving the top dirty. this would lead to situtations were `cmp_eq` for example was using `xor`, which was failing because of the left-over stuff in the top of the register.

with this commit, we now zero out or truncate depending on the context, to ensure instructions like xor will provide proper results.
2024-06-13 02:22:04 -07:00
David Rubin 05de6c279b riscv: std.fmt.format running
- implements `airSlice`, `airBitAnd`, `airBitOr`, `airShr`.

- got a basic design going for the `airErrorName` but for some reason it simply returns
empty bytes. will investigate further.

- only generating `.got.zig` entries when not compiling an object or shared library

- reduced the total amount of ops a mnemonic can have to 3, simplifying the logic
2024-06-13 02:20:47 -07:00
Robin Voetter b9d738a5cf spirv: disable tests that fail on pocl
Besides the Intel OpenCL CPU runtime, we can now run the
behavior tests using the Portable Computing Language. This
implementation is open-source, so it will be easier for us
to patch in updated versions of spirv-llvm-translator that
have bug fixes etc.
2024-06-10 20:32:34 +02:00
David Rubin 75372f12ef riscv: update behaviour tests again 2024-05-11 02:17:24 -07:00
David Rubin ffb63a05a3 riscv: finally fix bug + airAggregateInit
i just hadn't realized that I placed the `riscv_start` branch in the non-simplified
starts
2024-05-11 02:17:24 -07:00
David Rubin d9e0cafe64 riscv: add stage2_riscv to test matrix and bypass failing tests 2024-05-11 02:17:24 -07:00
Andrew Kelley e89d6fc503 fix wrong int alignment for i65..i127 on x86 arch 2024-05-08 19:37:30 -07:00
mlugg d0e74ffe52 compiler: rework comptime pointer representation and access
We've got a big one here! This commit reworks how we represent pointers
in the InternPool, and rewrites the logic for loading and storing from
them at comptime.

Firstly, the pointer representation. Previously, pointers were
represented in a highly structured manner: pointers to fields, array
elements, etc, were explicitly represented. This works well for simple
cases, but is quite difficult to handle in the cases of unusual
reinterpretations, pointer casts, offsets, etc. Therefore, pointers are
now represented in a more "flat" manner. For types without well-defined
layouts -- such as comptime-only types, automatic-layout aggregates, and
so on -- we still use this "hierarchical" structure. However, for types
with well-defined layouts, we use a byte offset associated with the
pointer. This allows the comptime pointer access logic to deal with
reinterpreted pointers far more gracefully, because the "base address"
of a pointer -- for instance a `field` -- is a single value which
pointer accesses cannot exceed since the parent has undefined layout.
This strategy is also more useful to most backends -- see the updated
logic in `codegen.zig` and `codegen/llvm.zig`. For backends which do
prefer a chain of field and elements accesses for lowering pointer
values, such as SPIR-V, there is a helpful function in `Value` which
creates a strategy to derive a pointer value using ideally only field
and element accesses. This is actually more correct than the previous
logic, since it correctly handles pointer casts which, after the dust
has settled, end up referring exactly to an aggregate field or array
element.

In terms of the pointer access code, it has been rewritten from the
ground up. The old logic had become rather a mess of special cases being
added whenever bugs were hit, and was still riddled with bugs. The new
logic was written to handle the "difficult" cases correctly, the most
notable of which is restructuring of a comptime-only array (for
instance, converting a `[3][2]comptime_int` to a `[2][3]comptime_int`.
Currently, the logic for loading and storing work somewhat differently,
but a future change will likely improve the loading logic to bring it
more in line with the store strategy. As far as I can tell, the rewrite
has fixed all bugs exposed by #19414.

As a part of this, the comptime bitcast logic has also been rewritten.
Previously, bitcasts simply worked by serializing the entire value into
an in-memory buffer, then deserializing it. This strategy has two key
weaknesses: pointers, and undefined values. Representations of these
values at comptime cannot be easily serialized/deserialized whilst
preserving data, which means many bitcasts would become runtime-known if
pointers were involved, or would turn `undefined` values into `0xAA`.
The new logic works by "flattening" the datastructure to be cast into a
sequence of bit-packed atomic values, and then "unflattening" it; using
serialization when necessary, but with special handling for `undefined`
values and for pointers which align in virtual memory. The resulting
code is definitely slower -- more on this later -- but it is correct.

The pointer access and bitcast logic required some helper functions and
types which are not generally useful elsewhere, so I opted to split them
into separate files `Sema/comptime_ptr_access.zig` and
`Sema/bitcast.zig`, with simple re-exports in `Sema.zig` for their small
public APIs.

Whilst working on this branch, I caught various unrelated bugs with
transitive Sema errors, and with the handling of `undefined` values.
These bugs have been fixed, and corresponding behavior test added.

In terms of performance, I do anticipate that this commit will regress
performance somewhat, because the new pointer access and bitcast logic
is necessarily more complex. I have not yet taken performance
measurements, but will do shortly, and post the results in this PR. If
the performance regression is severe, I will do work to to optimize the
new logic before merge.

Resolves: #19452
Resolves: #19460
2024-04-17 13:41:25 +01:00
Veikka Tuominen 60614b2a85 add tests for fixed stage1 bugs
Closes #10357
Closes #11236
Closes #11615
Closes #12055
2024-03-28 15:24:01 +02:00
HydroH 7aa42f47b7 allow @errorcast to cast error sets to error unions 2024-03-28 10:23:32 +00:00
Robin Voetter 2f9e37ade0 spirv: enable passing tests 2024-03-18 19:13:51 +01:00
Ali Chraghi 37b0aa600a spirv: make rusticl the primary testing implementation 2024-02-09 09:27:08 +03:30
Veikka Tuominen f782202910 Sema: do not emit @errorCast safety check when dest is adhoc inferred error set
Closes #17354
2024-01-29 13:48:45 +02:00
dweiller 8108c9f4d2 test/behavior: replace all 'comptime expect' with 'comptime assert' 2024-01-15 20:55:01 +11:00
Veikka Tuominen 804cee3b93 categorize behavior/bugs/<issueno>.zig tests 2024-01-06 16:49:41 -08:00
mlugg 9c16b2370d test: update behavior to silence 'var is never mutated' errors 2023-11-19 09:57:03 +00:00
Robin Voetter 4bf27da6a6 Revert "Revert "Merge pull request #17657 from Snektron/spirv-recursive-ptrs""
This reverts commit 9f0359d78f in an attempt to
make the tests pass again. The CI failure from that merge should be unrelated
to this commit.
2023-10-23 06:27:12 -04:00