1645 Commits

Author SHA1 Message Date
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
Andrew Kelley
c1eb6c30e8
Merge pull request #11835 from ziglang/stage2-behavior
stage2: fix handling of aggregates with mixed comptime-only fields
2022-06-11 00:27:41 -04:00
Andrew Kelley
32c90cb553 stage2: fix handling of aggregates with mixed comptime-only fields 2022-06-09 19:23:36 -07:00
Andrew Kelley
bac132bc8f introduce std.debug.Trace
And use it to debug a LazySrcLoc in stage2 that is set to a bogus value.

The actual fix in this commit is:

```diff
-        try sema.emitBackwardBranch(&child_block, call_src);
+        try sema.emitBackwardBranch(block, call_src);
```
2022-06-09 15:37:16 -07:00
Andrew Kelley
3e30ba3f20 stage2: better codegen for byte-aligned packed struct fields
* Sema: handle overaligned packed struct field pointers
 * LLVM: handle byte-aligned packed struct field pointers
2022-06-07 21:05:40 -07:00
Veikka Tuominen
6de9eea7bc stage2 llvm: fix float/int conversion compiler-rt calls 2022-06-07 21:27:06 +03:00
Veikka Tuominen
fbd7e4506f stage2: implement asm with multiple outputs 2022-06-07 21:27:06 +03:00
Andrew Kelley
e9fc58eab7 LLVM: handle extern function name collisions
Zig allows multiple extern functions with the same name, and the
backends have to handle this possibility.

For LLVM, we keep a sparse map of collisions, and then resolve them in
flushModule(). This introduces some technical debt that will have to be
resolved when adding incremental compilation support to the LLVM
backend.
2022-06-07 00:47:10 -04:00
Andrew Kelley
d2f31d315e C backend: implement try instruction 2022-06-05 10:37:08 +02:00
Andrew Kelley
ef885a78d6 stage2: implement the new "try" ZIR/AIR instruction
Implements semantic analysis for the new try/try_inline ZIR
instruction. Adds the new try/try_ptr AIR instructions and implements
them for the LLVM backend.

Fixes not calling rvalue() for tryExpr in AstGen.

This is part of an effort to implement #11772.
2022-06-05 10:37:08 +02:00
Veikka Tuominen
8f45e81c84 stage2: ignore asm inputs named _
This is a hacky solution but the entire asm syntax is supposed to be
reworked anyways.
2022-06-03 15:10:37 +03:00
Andrew Kelley
de14fba247 LLVM: convert two ArrayLists into a MultiArrayList 2022-06-01 11:53:47 -07:00
Andrew Kelley
8c0f4e6f54 LLVM: add target-cpu and target-features fn attributes 2022-05-31 22:13:24 -07:00
Andrew Kelley
2f9533f639 LLVM: pass slices as ptr/len combo
LLVM optimization passes handle this better, and it allows Zig to
specify pointer parameter attributes such as readonly, nonnull, noalias,
and alignment.

closes #561
2022-05-31 18:25:57 -07:00
Andrew Kelley
356a865b87 stage2: introduce support for noalias
Not implemented yet is enhancements to coerceInMemory to account for
noalias parameters.

Related to #11498.
2022-05-31 17:38:42 -07:00
Andrew Kelley
ec919c3c9b LLVM: integrate param attrs with iterateParamTypes
This moves some logic from resolveLlvmFunction to updateFunc and takes
advantage of the iteration we already do that takes into account C ABI
lowering, making LLVM parameter attributes accurate for C ABI functions
as well as our own unspecified calling convention.

Related to #11498.
2022-05-31 15:32:15 -07:00
Andrew Kelley
43311e19f4 LLVM: add readonly, nonnull, align attributes to pointer params 2022-05-31 15:16:38 -07:00
Andrew Kelley
d410693dad LLVM: elide some loads when lowering
Generally, the load instruction may need to make a copy of an
isByRef=true value, such as in the case of the following code:

```zig
pub fn swap(comptime T: type, a: *T, b: *T) void {
    const tmp = a.*;
    a.* = b.*;
    b.* = tmp;
}
```

However, it only needs to do so if there are any instructions which can
possibly write to memory. When calling functions with isByRef=true
parameters, the AIR code that is generated looks like loads followed
directly by call.

This allows for a peephole optimization when lowering loads: if the load
instruction operates on an isByRef=true type and dies before any side effects
occur, then we can safely lower the load as a no-op that returns its
operand.

This is one out of three changes I intend to make to address #11498.
However I will put these changes in separate branches and merge them
separately so that we can have three independent points on the perf
charts.
2022-05-31 14:17:54 -04:00
Andrew Kelley
83beed09e1 LLVM: omit memset of 0xaa bytes in unsafe optimization modes
This is one out of three changes I intend to make to address #11498.
However I will put these changes in separate branches and merge them
separately so that we can have three independent points on the perf
charts.
2022-05-31 00:39:14 -07:00
Andrew Kelley
83f69af971 stage2: implement runtime array multiplication
Additionally:

 * Sema: fix array cat/mul not setting the sentinel value
   - This required an LLVM backend enhancement to the handling of the
     AIR instruction aggregate_init that likely needs to be
     propagated to the other backends.
 * Sema: report integer overflow of array concatenation in a proper
   compile error instead of crashing.
 * Sema: fix not using proper pointer address space for array cat/mul
2022-05-25 22:33:48 -07:00
Andrew Kelley
1f16b07d6f stage2: treat error{}!void as a zero-bit type 2022-05-24 17:53:04 -07:00
Andrew Kelley
c711c788f0 stage2: fixes for error unions, optionals, errors
* `?E` where E is an error set with only one field now lowers the same
   as `bool`.
 * Fix implementation of errUnionErrOffset and errUnionPayloadOffset to
   properly compute the offset of each field. Also name them the same
   as the corresponding LLVM functions and have the same function
   signature, to avoid confusion. This fixes a bug where wasm was
   passing the error union type instead of the payload type.
 * Fix C backend handling of optionals with zero-bit payload types.
 * C backend: separate out airOptionalPayload and airOptionalPayloadPtr
   which reduces branching and cleans up control flow.
 * Make Type.isNoReturn return true for error sets with no fields.
 * Make `?error{}` have only one possible value (null).
2022-05-24 15:34:52 -07:00
Andrew Kelley
cd59b8277d LLVM: rename two functions
llvmType -> lowerType
genTypedValue -> lowerValue
2022-05-24 15:34:52 -07:00
Andrew Kelley
02e9d9b43b stage2: make ?anyerror represented the same as anyerror
I was able to get the backend implementation working on LLVM and the C
backend, but I'm going to ask for some help on the other backends.
2022-05-24 15:34:52 -07:00
Andrew Kelley
c97c7f9e3b C backend: update to new error union semantics 2022-05-24 15:34:52 -07:00
Andrew Kelley
3264abe3d8 stage2: fixes for error union semantics
* Sema: avoid unnecessary safety checks when an error set is empty.
 * Sema: make zirErrorToInt handle comptime errors that are represented
   as integers.
 * Sema: make empty error sets properly integrate with
   typeHasOnePossibleValue.
 * Type: correct the ABI alignment and size of error unions which have
   both zero-bit error set and zero-bit payload. The previous code did
   not account for the fact that we still need to store a bit for
   whether there is an error.
 * LLVM: lower error unions possibly with the payload first or with the
   error code first, depending on alignment. Previously it always put
   the error code first and used a padding array.
 * LLVM: lower functions which have an empty error set as the return
   type the same as anyerror, so that they can be used where
   fn()anyerror function pointers are expected. In such functions, Zig
   will lower ret to returning zero instead of void.

As a result, one more behavior test is passing.
2022-05-24 15:34:52 -07:00
Andrew Kelley
818fbd9c56 stage2: string literal interning
This is a temporary addition to stage2 in order to match stage1 behavior,
however the end-game once the lang spec is settled will be to use a global
InternPool for comptime memoized objects, making this behavior consistent
across all types, not only string literals. Or, we might decide to not
guarantee string literals to have equal comptime pointers, in which case
this commit can be reverted.
2022-05-24 01:01:24 -07:00
Jakub Konka
cbefd354a6 Bump support macOS versions; clean up allocs in llvm.targetTriple 2022-05-22 22:31:41 +02:00
Jakub Konka
e306d04473 Return an error when macOS ABI is not {none, simulator, macabi} 2022-05-22 17:45:07 +02:00
Jakub Konka
f8a1a2c4a1 stage2: append min version to target triple when lowering to LLVM 2022-05-22 17:45:07 +02:00
Andrew Kelley
f31f86a86a LLVM: fix calling convention lowering involving pointers
The previous commit caused LLVM module verification failure because we
attemped to bitcast LLVM pointers to i64 parameters. This is exactly
what we want, however it's technically not allowed according to LLVM's
type system. It could have been fixed trivially by using ptrtoint
instead of bitcast in the case of pointers, however, out of concern for
inttoptr being problematic for the optimizer, I put in special code to
detect when a given parameter can be treated as its actual type rather
than an integer type. This makes Zig's output LLVM IR closer to what
Clang outputs.
2022-05-21 00:09:30 -07:00
Andrew Kelley
1697a6f044 LLVM: rework calling convention lowering
The previous implementation of calling conventions was hacky and broken.
This commit reworks lowerFnParamTy into iterateParamTypes which returns
enum tags indicating how to handle each parameter. This is then used in
the three places that matter:
 * lowering a function type to llvm type
 * converting function parameters to the canonical type representation
   (with respect to isByRef).
 * converting canonical type representation to function arguments at
   callsites (again with respect to isByRef).

As a result, we are one step closer to the C ABI tests passing. Before
this commit, attempting to build them crashed the compiler. I isolated
the broken function and verified that it now is lowered correctly. I
will keep working on this one piece at a time until all the C ABI tests
pass, and then I will enable all of them in the CI.
2022-05-20 21:50:23 -07:00
Andrew Kelley
b6798c26ef stage2: fix pointer arithmetic result type
This makes it so the result of doing pointer arithmetic creates a new
pointer type that has adjusted alignment.
2022-05-17 23:50:38 -07:00
Andrew Kelley
00f3d84f38 LLVM: support mixing extern and export with the same symbol name 2022-05-17 23:50:38 -07:00
Veikka Tuominen
e369752430 Sema: do not call returnError when returning payload of error union 2022-05-16 17:42:51 -07:00
Veikka Tuominen
53a5aee3b3 stage2: enable error return tracing on llvm backend 2022-05-16 17:42:51 -07:00
Veikka Tuominen
66c3988e5e stage2: disable error return tracing on unsupported targets 2022-05-16 17:42:51 -07:00
Veikka Tuominen
eee8fffec7 stage2: implement error return traces 2022-05-16 17:42:51 -07:00
Andrew Kelley
03ed0f0d28 C backend: implement overflow arithmetic
Most of the work here was additions to zig.h. The lowering code is
mainly responsible for calling the correct function name depending on
the operand type.

Some of the compiler-rt calls here are not implemented yet and are
non-standard symbols due to the C programming language not needing them.

After this commit, the behavior tests with -ofmt=c are passing again.
2022-05-16 13:55:26 -07:00
William Sengir
a5ea22d069 LLVM: correctly pad result tuple of airOverflow 2022-05-16 13:55:26 -07:00
William Sengir
c2cb9b7cad stage2: vectorize shl_with_overflow in LLVM backend 2022-05-16 13:55:26 -07:00