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.
Empty enums are uninstantiable, so their backing integer should be too.
This avoids a bunch of weird special cases during semantic analysis.
If you were previously using `enum {}`, your code should continue to work
fine.
If you were previously using `enum(uN) {}` (where `uN` is any integer type),
you'll probably want to use `enum(uN) { _ }` instead.
composite integers (wider than usize) are represented in as `[N]u32` arrays.
however, no operations were implemented before.
following operations are implemented:
- bitwise (and, or, xor, not)
- comparison (eq/neq)
- add/sub/mul/shl/shr
- `@abs`, `@intCast`
this removes 36 SPIR-V behavior test skips.
also fixed `derivePtr` to use `OpAccessChain` instead of `OpBitcast`
for array pointer casts (e.g. `*[100]u8` to `*u8`) in logical addressing
mode, where pointer bitcasts are not valid.
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.
Once the switch condition is been shifted up so the minimum value is 0,
it makes sense to treat its type as the unsigned version of its original
type.
Fixes#35651
Unions with no fields are now "uninstantiable" types, which work like
`noreturn` in that values of this type cannot exist. Enums with no
fields are different because they are currently considered `extern`
types, though https://github.com/ziglang/zig/issues/19855 will change
this in the future.
'comptime_int' is no longer considered a valid backing type for an enum.
In other words, 'enum(comptime_int)' is a compile error. This change is
accepted to simplify the language.
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.
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.
- 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
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.