735 Commits

Author SHA1 Message Date
Luuk de Gram
200b2e4ee1
llvm: correctly lower c-abi for Wasm target
When lowering the return type for Wasm if the calling convention is `C`,
it now correctly lower it according to what clang does as specified in:
https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md

This makes use of the same logic as the Wasm backend, ensuring the
generated code does not diverge in function signatures.

When passing arguments accross the C-ABI for the Wasm target,
we want slightly different behavior than x86_64.
For instance: a struct with multiple fields must always be passed
by reference, even if its ABI size fits in a single integer.
However, we do pass larger integers such as 128bit by value,
which LLVM will correctly lower to use double arguments instead.
2022-07-25 06:34:00 +02:00
Andrew Kelley
546c75ca46 LLVM: notice the soft_float CPU feature
when deciding whether to lower to x86_fp80 instructions, or softfloat
instructions.

Closes #10847
Closes #12090
2022-07-24 17:10:08 -07:00
Meghan
dea437edfb
stage2: implement noinline fn 2022-07-24 11:56:33 +03:00
Veikka Tuominen
d75fa86d70 stage2: implement @setFloatMode 2022-07-23 15:40:12 +03:00
Veikka Tuominen
ff7ec4efb5 Sema: bad union field access safety 2022-07-23 15:40:11 +03:00
Andrew Kelley
f591936480
Merge pull request #12198 from Vexu/stage2
Sema: fix loading and storing of optional pointers represented as pointers
2022-07-22 20:47:40 -07:00
Veikka Tuominen
03b1fbe50d stage2: fix airIsErr when is_ptr == true 2022-07-22 21:07:55 +03:00
Andrew Kelley
f550c29c4e LLVM: fix lowering of structs with underaligned fields
When lowering a struct type to an LLVM struct type, keep track of
whether there are any underaligned fields. If so, then make it a packed
llvm struct. This works because we already insert manual padding bytes
regardless.

We could unconditionally use an LLVM packed struct; the reason we bother
checking for underaligned fields is that it is a conservative choice, in
case LLVM handles packed structs less optimally. A future improvement
could simplify this code by unconditionally using packed LLVM structs
and then make sure measure perf is unaffected.

closes #12190
2022-07-21 22:51:17 -07:00
Veikka Tuominen
d41dd499a9 stage2 llvm: fix handling of pointer fields in packed structs 2022-07-20 17:07:12 +03:00
Andrew Kelley
fe8c3ffeb1 LLVM: change commentary on isByRef
This branch originally started out as a potential workaround to
address #11450. It did not solve that problem, however, it did end
up fixing #11498!
2022-07-19 11:31:37 -07:00
Andrew Kelley
74fb65fb42 LLVM: lower all error unions as byref=true
Same reasoning as previous commit.
2022-07-19 11:26:19 -07:00
Andrew Kelley
bab570a225 LLVM: lower all structs as byref=true
Same reasoning as previous commit.
2022-07-19 11:26:18 -07:00
Andrew Kelley
65bc4d915d LLVM: lower optional types as byref=true
This is a possible workaround for
https://github.com/llvm/llvm-project/issues/56585

On my computer it makes stage3-release go from false positive
compilation errors on the behavior tests to "segmentation fault".
Is this forwards progress or backwards progress? I have no idea.

See #11450
2022-07-19 11:22:48 -07:00
Cody Tapscott
b93a38860d stage2: Change optional non-null field to i8
This is a workaround for https://github.com/llvm/llvm-project/issues/56585
which causes writes to i1 in memory to be optimized to an incorrect value.
Unfortunately, this does not save users from running into this bug with u1
in their own types.

However, this does seem to be enough to get the behavior tests working.
This resolves #11450 on my machine.
2022-07-19 13:33:41 -04:00
Andrew Kelley
9329b93b88 LLVM: disable the ABI size safety check
There are many more instances of this check being tripped that we need
to fix before we can enable this.
2022-07-14 23:26:32 -07:00
Andrew Kelley
040cb585e8 LLVM: fix ABI size of optional and error union types
Previously, the Zig ABI size and LLVM ABI size of these types disagreed
sometimes. This code also corrects the logging messages to not trigger
LLVM assertions.
2022-07-14 23:24:57 -07:00
Andrew Kelley
8c14d170b5 Revert "stage2 llvm: Use unpacked struct for unions and arrays"
This reverts commit 2eaef84ebe968224b0cf25206abf12ea1c5e0f5a.

Here is a motivating example:

```zig
const E = union(enum) {
    A: [9]u8,
    B: u64,
};
```

```llvm
%test2.E = type { { i64, [1 x i8] }, i1, [6 x i8] }
```

```
error(codegen): when lowering test2.E, Zig ABI size = 16 but LLVM ABI size = 24
```
2022-07-14 22:26:11 -07:00
Andrew Kelley
9c136be78f LLVM: add padding to optional types when lowering
If the LLVM ABI size does not agree with the Zig ABI size.
2022-07-14 22:26:11 -07:00
Andrew Kelley
070e3ea37d LLVM: insert debug logging when LLVM ABI size is wrong 2022-07-14 22:26:11 -07:00
Andrew Kelley
35e7011124 LLVM: implement signext/zeroext attributes
For calling convention ABI purposes, integer attributes and return
values need to have an LLVM attribute signext or zeroext added
sometimes. This commit implements that logic.

It also implements a proof-of-concept of moving the F16T type from
being a compiler_rt hack to being how the compiler lowers f16 in
functions that need to match certain calling conventions.

Closes #12054
2022-07-13 11:14:46 -07:00
Andrew Kelley
8324a93f2e LLVM: always add some clobbers for some architectures
For some targets, Clang unconditionally adds some clobbers to all inline assembly.
While this is probably not strictly necessary, if we don't follow Clang's lead
here then we may risk tripping LLVM bugs since anything not used by Clang tends
to be buggy and regress often.
2022-07-12 18:38:11 -07:00
Andrew Kelley
0d164f9a25 LLVM: broaden aarch64-windows f16 debug variable workaround
LLVM does not properly handle debug info for f16 on the aarch64-windows
target, causing "fatal error: unknown codeview register H1". The
previous workaround checked only for f16 but was still vulnerable if a
type was a byval struct or tuple which had an f16 field in it.

Now I have filed an upstream issue (see
https://github.com/llvm/llvm-project/issues/56484) and broadened the
workaround to always skip debug values for this target.
2022-07-12 18:38:11 -07:00
Cody Tapscott
2eaef84ebe stage2 llvm: Use unpacked struct for unions and arrays
Our lowerings for various LLVM types assume that we can anticipate the
alignment/layout that LLVM will generate. Among other things, this
requires that we keep the alignment of our lowered LLVM types
synchronized with their expected alignment in Zig.

 - Arrays were using packed struct types, which is seems to be
   incorrect since array elements are supposed to be self-aligned.

 - Unions were using packed struct types for their payload, which causes
   layout divergence between what stage2 expects and what LLVM generates

Consider this lowered union type:
```llvm
%Value = type { <{ i64, [8 x i8] }>, i1, [7 x i8] } ; 24 bytes, align(1)
%ErrorUnion = type { %Value, i16 } ; 26 bytes, align(2)
```

Zig expects Value to be align(8) and, by extension, for ErrorUnion to be
size 32.
2022-07-12 21:34:20 -04:00
Cody Tapscott
2b5215436c stage2: Lower libcalls on Windows x86-64 correctly
This change is the Zig counterpart to https://reviews.llvm.org/D110413

Same as the prior commit, but for stage2
2022-07-10 20:52:29 -07:00
Andrew Kelley
6a3a0fe7ae Merge remote-tracking branch 'origin/master' into llvm14 2022-07-07 18:25:01 -07:00
Andrew Kelley
3a03872af7 LLVM: more robust implementation of C ABI for multiple_llvm_ints
The previous code here was potentially more optimal for some cases,
however, I never tested the perf, so it might not actually matter. This
code handles more cases. We can go back and re-evaluate that other
implementation if it seems worthwhile in the future.
2022-07-07 18:24:34 -07:00
Andrew Kelley
8d6011361f LLVM: handle byref combined with multiple_llvm_ints 2022-07-07 18:24:34 -07:00
Andrew Kelley
2ee864ca5e CLI: add support for -fno-builtin 2022-07-05 15:21:20 -07:00
Andrew Kelley
fbd6c88321 Merge remote-tracking branch 'origin/master' into llvm14 2022-07-04 17:22:36 -07:00
Andrew Kelley
ecb4293afe stage2: disable unit tests when building with stage1
They trip LLVM assertions and spirv is not needed to bootstrap. Not
important for these tests to pass with stage1.
2022-07-04 16:20:33 -07:00
Andrew Kelley
15bdba410a update build scripts to LLD and LLVM 14 libraries 2022-07-03 18:41:43 -07:00
Andrew Kelley
15f111a085 LLVM: update lowering of saturating shift-left
LLVM 14 makes it so that a RHS of saturating shift left produces a
poison value if the value is greater than the number of bits of the LHS.
Zig now emits code that will check if this is the case and select a
saturated LHS value in such case, matching Zig semantics.
2022-07-03 13:07:23 -07:00
Andrew Kelley
b1873f2074 LLVM: update inline asm to LLVM14 semantics
This is the equivalent of d19290e603833a197bc8bfc8315561ec77291225
applied to stage2 instead of stage1.
2022-07-03 11:37:31 -07:00
Andrew Kelley
3ab5912eee LLD: the driver functions now return "false" to mean "error" 2022-07-01 22:13:30 -07:00
Andrew Kelley
1fa4a58d2c stage1: update to LLVM 14 API 2022-07-01 19:19:13 -07:00
Andrew Kelley
c89dd15e1b Merge remote-tracking branch 'origin/master' into llvm14 2022-07-01 15:52:54 -07:00
Andrew Kelley
d3542be875 LLVM: be sure to never pass align(0) attribute
This can happen with pointers to zero-bit types.

This commit fixes an LLVM assertion being tripped.
2022-06-30 18:33:02 -07:00
Andrew Kelley
c030ec1884 LLVM: use unnamed struct llvm type for unions when necessary
The constant value lowering for unions was missing a check for whether
the payload was itself an unnamed struct. Lowerings of other types
already handle this case.

closes #11971
2022-06-30 18:33:02 -07:00
Andrew Kelley
1951051e3d
Merge pull request #11942 from Vexu/stage2-compile-errors
Move passing stage1 compile error tests to stage2
2022-06-30 18:39:46 -04:00
Andrew Kelley
77a334451f
Merge pull request #11967 from ziglang/runtime-float-negation
stage2: lower float negation explicitly + modify hash/eql logic for floats
2022-06-30 17:34:05 -04:00
Andrew Kelley
b3b96b5e28 LLVM: lower float negation with xor a constant
Rather than a compiler-rt call in the case that LLVM does not support
lowering the fneg instruction.
2022-06-30 11:48:37 -07:00
Veikka Tuominen
4f200eda9f stage2 llvm: ensure @tagName functions are unique 2022-06-30 21:47:25 +03:00
Andrew Kelley
6bc6e47b15 stage2: lower float negation explicitly
Rather than lowering float negation as `0.0 - x`.

 * Add AIR instruction for float negation.
 * Add compiler-rt functions for f128, f80 negation

closes #11853
2022-06-30 00:02:00 -07:00
Andrew Kelley
c248af3bdc LLVM: fix lowering of untagged union types
The LLVM backend was calculating the amount of padding solely based
on the payload size. However, in the case where there is no union
tag, this fails to take into account alignment.

Closes #11857
2022-06-30 02:43:05 -04:00
Andrew Kelley
3c1daf951c LLVM: fix invalid IR on @returnAddress of wasm/bpf
see #11946
2022-06-27 17:12:45 -07:00
Andrew Kelley
8d8a5f9733 LLVM: support calls to varargs functions
closes #11944
2022-06-27 16:02:41 -07:00
Veikka Tuominen
38a1222c87 std.crypto: fix invalid pass by value 2022-06-20 15:11:22 +03:00
Andrew Kelley
13f02c30e6 stage2: fix some inline asm incompatibilities with stage1 2022-06-12 14:46:05 -07:00
Veikka Tuominen
0333ff4476 stage2: make error{} the same size as anyerror
Having `error{}` be a zero bit type causes issues when it interracts
with empty inferred error sets which are the same size as `anyerror`.
2022-06-11 23:49:33 +03:00
Veikka Tuominen
0f820d0bdf stage2: improve debugging tools
llvm: dump failed module when -femit-llvm-ir set
print_air:
 * print fully qualified name
 * use Type.fmt and Value.fmtValue, fmtDebug is useless

TypedValue
 * handle anon structs and tuples
 * fix bugs
2022-06-11 11:02:56 +03:00