Commit Graph
129 Commits
Author SHA1 Message Date
xtex adba664355 test: add regression test for #36732 2026-10-03 15:21:28 +08:00
Ali Cheraghi 65b95b0af4 add unskip_spirv_tests.zig tool 2026-09-18 16:36:24 +03:30
Jacob Young a242b0be88 compiler_rt: change float abi so it can become compatible with cbe 2026-07-27 14:35:12 -04:00
Justus Klausecker 69a26976ed zig fmt
Converts usages of `@intFromEnum` and `@enumFromInt` to instead use the
new `@backingInt` and `@fromBackingInt` builtins.
2026-07-17 23:30:26 +02:00
Justus Klausecker cb4c344e19 compiler: add @backingInt and @fromBackingInt
This commit implements the `@backingInt` and `@fromBackingInt` builtins.
These builtins are meant to replace the now-deprecated `@intFromEnum` and
`@enumFromInt` builtins.

`@backingInt` works with all enums and with bitpacks with *explicit* backing
integer types only. It also works with tagged unions, returning the backing
integer of the active tag value.
An `undefined` enum or bitpack yields an `undefined` backing integer.
The builtin is lowered to `bit_cast`.

`@fromBackingInt` infers its result type, which may be any enum or a bitpack
with an *explicit* backing integer type. It takes a parameter of exactly
that backing integer type.
For enums, passing a backing integer that is either `undefined` or would
yield an invalid tag value results in safety-checked Illegal Behavior.
For bitpacks, passing an `undefined` backing integer yields an `undefined`
bitpack.
The builtin is lowered to `bit_cast` or `bit_cast_safe` (more details below).

`@bitCast` now also performs a safety check for invalid tag values if its
destination type is an `enum`.

This commit also introduces a new AIR instruction, `bit_cast_safe`.
Similarly to `int_cast_safe`, it includes a safety check for invalid enum
tag values. When `@enumFromInt` is eventually removed, `int_cast_safe` won't
need to perform this safety check anymore.

Legalize only implements `expand_bit_cast_safe`, and no additional insts
to scalarize `bit_cast_safe` with vector/array operands. That is because
it can just reuse the existing scalarizations for regular `bit_cast`.

The safety check mandated by `bit_cast_safe` is only desired if the result
type is a scalar enum tag value, so the scalarization process is exactly
equivalent. The only difference is that we have to perform a safety check
on the result of the scalarization.

This means that there's no reason for a backend to want scalarization of
regular `bit_cast`, but not of `bit_cast_safe` (or the other way round).
If a backend is having trouble with the `bit_cast_safe` safety check it
should just use `expand_bit_cast_safe` instead.

Also adds a `std.meta.BackingInt()` function to conveniently get the result
type of `@backingInt` and for use in the langref.
2026-07-17 09:43:53 +01:00
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
David Rubin f2d13f6d07 Sema: preserve union alignment to field on switch 2026-06-18 16:42:32 +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 c6d178f93d spirv: make codegen multi-threaded
The SPIR-V backend previously ran codegen single-threaded in the linker thread.
Now each codegen job creates an `Mir` like other self-hosted backends.

Other changes:
- Bring back `dedup_types.zig` and `prune_unused.zig` **ISel**s which were originaly
  removed because codegen was single-threaded at that time and therefor had no use
- Clean up `BinaryModule.zig`
- Remove `checkLogicalPtrOperation` from `elemPtrOneLayerOnly` in `Sema.zig`.
  Element access uses `OpAccessChain`, which works on all logical address spaces
  without `VariablePointers`. the check is only needed for pointer arithmetic.
2026-06-18 13:38:58 +02:00
Justus Klausecker e6be5cfe3e Sema: allow overwriting previous analysis results when using switch inst to store temporary information
Essentially `inst_map.putAssumeCapacityNoClobber` is always wrong here
because we *want* to clobber previous results when analyzing the same
switch expression multiple times.
2026-06-16 23:28:03 +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
Justus Klausecker 73b760e033 Sema: simplify switch capture logic
Previously all switch capture logic was in a single gigantic function and
had lots of weird rules around its args depending on each other which were
only encoded in doc comments and not actually enforced by the compiler.

That's odd since the 'happy path' of a switch capture is actually super
simple; it's literally just loading the switch operand inside of the scope
of the prong. Error sets introduce a little complexity since the type of
an error capture must be narrowed to the set of values that can possibly
be captured by their prong, but the real source of complexity here are
tagged union captures. First of, they support *two* captures - a payload
and a tag capture. The captured payload has to be set up correctly, and
payload captures are not guaranteed to have the same type so Sema has to
make sure that all possible payloads of a capture are compatible.

Instead of throwing all of this logic into one large function with lots of
special casing interspersed it is now split into three main paths:

- tagged unions (+ a potential tag capture)
- errors (including error set narrowing)
- everything else

This should greatly simplify reasoning about this logic in the future if
there's a bug or a change to be made. There's also no more dependencies of
args on each other; instead everything is a bit more modular, dependencies
are now encoded either as control flow or in the type system. This has
additionally lead to the OPV path being able to reuse some more of the
capture logic.

This commit also fixes inline prongs not narrowing error sets.
2026-05-28 19:35:48 +02:00
Alex Rønne Petersen 67fa822300 test: disable switch on pointer type behavior test with LLVM
See: https://github.com/llvm/llvm-project/issues/176634

ref https://github.com/ziglang/zig/issues/23509
2026-04-25 21:54:48 +02:00
Pavel Verigo 07e3e50fd2 stage2-wasm: enabling bigint blocked tests + final fixes 2026-04-09 00:14:09 +02:00
Justus Klausecker c10089d060 test: enable 'switch arbitrary int size' behavior test for cbe
was disabled in b25d93e7d9
2026-03-18 16:57:40 +01:00
Justus Klausecker 0b857eebeb test: disable 'switch on large types' behavior tests for wasm backend
The self-hosted wasm backend doesn't properly support very large integers yet.
2026-03-18 15:49:14 +01:00
Justus Klausecker dbe787a984 Revert "test: disable switch behavior test switching on type >64bits for cbe"
This reverts commit e91654b1e7.
2026-03-18 15:49:14 +01:00
Justus Klausecker 047df44d71 cbe: fix switch statements on large types
`switch` statements on types >128bits are now lowered to conditionals.
This is necessary because Zig lowers integers with more than 128 bits to
bigints, which are not 'native' integers and thus cannot be used as case
values.
128-bit integers get special treatment because Zig will emit actual 128bit
ints if they are supported by the target. They still *may* be lowered to
bigints though, e.g. for 32-bit targets or MSVC. To solve this, this commit
adds a bunch of switch macros to `zig.h` which will either resolve to an
actual `switch` statement or to conditionals. The `if` statements this
approach can generate are not as optimal as they could be but I think this
is a good trade-off since the generated `switch` statements are still the
same as the ones generated for smaller integers. Also the macros result
in pretty readable code.
2026-03-18 15:47:18 +01:00
Justus Klausecker e91654b1e7 test: disable switch behavior test switching on type >64bits for cbe
workaround for #31467
2026-03-11 21:14:43 +01:00
Justus Klausecker 28886ca9ec Sema: implement switch for packed structs/unions
Since packed containers are now represented by `bitpack` and can't include
pointers anymore this has become a very easy change to make. This commit
largely just reuses the logic already in place for integers.

Also fixes a small bug where captures-by-ref of errors wouldn't cause a
compile error for regular switch statements. There was already an astgen
error in place for error handling switch statements (`switch_block_err_union`)
capturing their error by reference.
2026-03-11 21:04:04 +01:00
Matthew Lugg 09d0b1f87a behavior: misc fixes
They compile now! They don't *pass*, but they *compile*!
2026-03-10 10:26:11 +00:00
Justus Klausecker 044ba3e0b0 Sema: fix single-range switch prong capture (for real this time)
e2338edb47 didn't *quite* do it, the call sites of all switch prong related
functions now have to do their part too and be a little more precise about
what kind of prong they're currently analyzing.

Also removes some unused/unnecessary stuff.
2026-01-13 06:03:07 +01:00
Justus Klausecker e2338edb47 Sema: fix single-range switch prong capture
This kind of capture cannot always be comptime-known, assuming so caused
access of undefined memory during payload capture analysis!
2026-01-11 20:22:32 +01:00
Matthew Lugg 01546e68cd compiler: handle switch rewrite review feedback 2026-01-11 14:37:28 +00:00
Justus Klausecker 2e99c3042e test: add some more switch regression tests
switch evaluation order, switch lazy value resolution
2026-01-11 11:37:18 +00:00
Justus Klausecker b79bd31356 Sema: rework switch_block[_ref/_err_union] logic
This commit aims to simplify and de-duplicate the logic required for
semantically analyzing `switch` expressions.

The core logic has been moved to `analyzeSwitchBlock`, `resolveSwitchBlock`
and `finishSwitchBlock` and has been rewritten around the new iterator-based
API exposed by `Zir.UnwrappedSwitchBlock`.

All validation logic and switch prong item resolution have been moved to
`validateSwitchBlock`, which produces a `ValidatedSwitchBlock` containing
all the necessary information for further analysis.

`Zir.UnwrappedSwitchBlock`, `ValidatedSwitchBlock` and `SwitchOperand`
replace `SwitchProngAnalysis` while adding more flexibility, mainly for
better integration with `switch_block_err_union`.

`analyzeSwitchBlock` has an explicit code path for OPV types which lowers
them to either a `block`-`br` or a `loop`-`repeat` construct instead of a
switch. Backends expect `switch` to actually have an operand that exists
at runtime, so this is a bug fix and avoids further special cases in the
rest of the switch logic.
`resolveSwitchBlock` and `finishSwitchBr` exclusively deal with operands
which can have more than one value, at comptime and at runtime respectively.

This commit also reworks `RangeSet` to be an unmanaged container and adds
`Air.SwitchBr.BranchHints` to offload some complexity from Sema to there
and save a few bytes of memory in the process.

Additionally, some new features have been implemented:
- decl literals and everything else requiring a result type (`@enumFromInt`!)
  may now be used as switch prong items
- union tag captures are now allowed for all prongs, not just `inline` ones
- switch prongs may contain errors which are not in the error set being
  switched on, if these prongs contain `=> comptime unreachable`

and some bugs have been fixed:
- lots of issues with switching on OPV types are now fixed
- the rules around unreachable `else` prongs when switching on errors now
  apply to *any* switch on an error, not just to `switch_block_err_union`,
  and are applied properly based on the AST
- switching on `void` no longer requires an `else` prong unconditionally
- lazy values are properly resolved before any comparisons with prong items
- evaluation order between all kinds of switch statements is now the same,
  with or without label
2026-01-11 11:37:17 +00:00
Ali CheraghiandMatthew Lugg dec1163fbb all: replace all @Type usages
Co-authored-by: Matthew Lugg <mlugg@mlugg.co.uk>
2025-11-22 22:42:38 +00:00
Jacob Young 402c14f86a aarch64: implement optional comparisons 2025-10-30 09:31:30 +00:00
Justus Klausecker 0ecbd5a0e1 address comments 2025-08-07 13:58:49 +02:00
Justus Klausecker ba549a7d67 Add support for both '_' and 'else' prongs at the same time in switch statements
If both are used, 'else' handles named members and '_' handles
unnamed members. In this case the 'else' prong will be unrolled
to an explicit case containing all remaining named values.
2025-08-07 13:58:47 +02:00
Justus Klausecker 1d9b1c0212 Permit explicit tags with '_' switch prong
Mainly affects ZIR representation of switch_block[_ref]
and special prong (detection) logic for switch.
Adds a new SpecialProng tag 'absorbing_under' that allows
specifying additional explicit tags in a '_' prong which
are respected when checking that every value is handled
during semantic analysis but are not transformed into AIR
and instead 'absorbed' by the '_' branch.
2025-08-07 13:57:57 +02:00
Jacob Young c334956a54 aarch64: workaround some optional/union issues 2025-07-28 09:03:17 -07:00
Andrew Kelley da408bd6fc Merge pull request #24585 from jacobly0/aarch64
aarch64: more progress
2025-07-27 00:17:19 -07:00
Jacob Young 7894703ee7 aarch64: implement more optional/error union/union support 2025-07-26 21:39:50 -04:00
Jacob Young 7c349da49c aarch64: implement complex switch prongs 2025-07-26 16:08:40 -04:00
Jacob Young 68cfa736df x86_64: fix switch on mod result
Closes #24541
2025-07-26 06:24:03 -04:00
Jacob Young 5060ab99c9 aarch64: add new from scratch self-hosted backend 2025-07-22 19:43:47 -07:00
Ali Cheraghi 872f68c9cb rename spirv backend name
`stage2_spirv64` -> `stage2_spirv`
2025-06-16 13:22:19 +03:30
Jacob Young 37f763560b x86_64: fix switch dispatch bug
Also closes #23902
2025-06-06 23:42:15 -07:00
Jacob Young 1eb5d70d12 x86_64: fix switch on big ints 2025-04-09 20:14:12 -04:00
Ali Cheraghi aec0f9b3e7 test: skip failing tests with spirv-vulkan 2025-02-24 19:39:42 +01:00
Pavel Verigo b25d93e7d9 stage2-wasm: implement switch_dispatch + handle > 32 bit integers in switches
Updated solution is future proof for arbitary size integer handling for both strategies .br_table lowering if switch case is dense, .br_if base jump table if values are too sparse.
2025-02-22 18:34:00 -05:00
Robin Voetter 86b88ea7da spirv: skip range switch tests
This is not yet implemented
2024-10-13 01:58:11 +02:00
mlugg 03c363300f AstGen: do not allow unlabeled break to exit a labeled switch
`break`ing from something which isn't a loop should always be opt-in.
This was a bug in #21257.
2024-09-12 22:52:23 +01:00
mlugg b7a55cd6c3 AstGen: allow breaking from labeled switch
Also, don't use the special switch lowering for errors if the switch
is labeled; this isn't currently supported. Related: #20627.
2024-09-01 18:31:01 +01:00
David Rubin 8da212c11b riscv: update tests and fix reuse bug 2024-07-26 04:19:58 -07:00
David Rubin 1a7d89a84d riscv: clean up and unify encoding logic 2024-07-26 04:19:13 -07:00
David Rubin 8d30fc45c4 riscv: implement more operators
we can run `std.debug.print` now, with both run-time strings and integers!
2024-07-26 04:05:39 -07:00
David Rubin 7a02878f4e riscv: truncate airStructFieldVal result 2024-07-14 23:02:33 -07:00