Prior to this commit, the logic for ABI size and ABI alignment for
integers was naive and incorrect. This results in wasted hardware as
well as undefined behavior in the LLVM backend when we memset an
incorrect number of bytes to 0xaa due to disagreeing with LLVM about the
ABI size of integers.
This commit introduces a "max int align" value which is different per
Target. This value is used to derive the ABI size and alignment of all
integers.
This commit makes an interesting change from stage1, which treats
128-bit integers as 16-bytes aligned for x86_64-linux. stage1 is
incorrect. The maximum integer alignment on this system is only 8 bytes.
This change breaks the behavior test called "128-bit cmpxchg" because on
that target, 128-bit cmpxchg does require a 16-bytes aligned pointer to
a 128 bit integer. However, this alignment property does not belong on
*all* 128 bit integers - only on the pointer type in the `@cmpxchg`
builtin function prototype. The user can then use an alignment override
annotation on a 128-bit integer variable or struct field to obtain such
a pointer.
With this improved iterator, type of test is now inferred from
the filename, enabling us to put all cases in one common parent
directory, and iterate over that, thus automating a lot of tasks.
This was a bit trickier than it should be due to symbol conflicts with
zig's compiler-rt implementation. We attempt to use weak linkage in
our compiler-rt, but this does not seem to be working in all cases. I
manually disabled export of the problematic compiler-rt math functions
in order to cross compile musl's libc.so for all targets as input to
`tools/gen_stubs.zig`.
Other than that, this update went fairly smoothly. Quite a few
additional symbols were added to the blacklist in `tools/gen_stubs.zig`
due to recent reorganization of zig's compiler-rt.
* outputs can have names and be referenced with template replacements
the same as inputs.
* fix print_air.zig not decoding correctly.
* LLVM backend: use a table for template names for simplicity
Instead of doing heterogeneous comparison at comptime. This makes the
following test pass (as it already does for stage1):
```zig
test {
const x: f64 = 12.34;
expect(x == 12.34);
}
```
There is already behavior test coverage for this, however, other bugs in
`std.fmt.parseFloat` are masking the failures.
From a language specification perspective, this makes sense because it
makes comptime comparisons with comptime_float work the same way they
work with runtime comparisons.
Maybe after we have incremental compilation metadata serialization
and non-LLVM backends, it will make sense to switch this back. For now,
however, this makes successive `zig build` commands much faster.
Just like for Struct in 8238d4b33585a715c58ab559cd001dd3ea1db55b, in the
case of ErrorUnion struct we need to return a compound literal "(T){...}"
instead of just "{}", which is invalid code when used in e.g. a "return"
expression.
* Sema: Correctly determine whether array_cat lhs and rhs are single ptrs
Many-pointers are also not single-pointers and wouldn't be considered
here. This commit makes the conditions use the appropriately-named
isSinglePointer instead.
* Sema: Correctly obtain ArrayInfo for many-pointer concatenation
Many-pointers at comptime have a known size like slices and can be used
in array concatenation. This fixes a stage1 regression.
* test: Add comptime manyptr concatenation test
Co-authored-by: sin-ack <sin-ack@users.noreply.github.com>
Instead, just return ChildProcess directly. This structure does not
require a stable address, so we can put it on the stack just fine. If
someone wants it on the heap they should do.
const proc = try allocator.create(ChildProcess);
proc.* = ChildProcess.init(args, allocator);
To correctly handle multiple backends crossed with multiple targets,
we need to push all elements in separate allocated arrays rather
than operate on raw iterators. Hence, introduce `getConfigForKeyAlloc`.
Provide default parsers for obvious config options such as
`CrossTarget` or `Backend` (or any enum for that matter).
Unroll iterator loops into multiple cases - we need to create
a Cartesian product for all possibilities specified in the
test manifest.
Before this change, struct {f80, f80} targeting i386-windows-msvc lowers
to
```llvm
%"std.testing.struct:78:61.6" = type { x86_fp80, [6 x i8], x86_fp80, [6 x i8] }
```
which has an incorrect ABI size of 40. After this change, the struct
lowers to
```llvm
%"std.testing.struct:78:61.6" = type { x86_fp80, [4 x i8], x86_fp80, [4 x i8] }
```
which has the correct ABI size of 32, and properly aligns the second
field to 16 bytes.
The other place that calculates field padding (lowering of constant
values in codegen.cpp) already correctly calls LLVMABISizeOfType
rather than LLVMStoreSizeOfType.
This fixes the compiler-rt tests for i386-windows in this branch.
These are only as accurate as f64 even for f128 comptime functions. This
is OK for now; improvements will come with the launch of self-hosted
(#89) and enhancements to compiler-rt implementations.