536 Commits

Author SHA1 Message Date
Luuk de Gram
43cb19ea4d wasm: Implement @wasmMemoryGrow builtin
Similarly to the other wasm builtin, this implements the grow variation where the memory
index is a comptime known value. The operand as well as the result are runtime values.
This also verifies during semantic analysis the target we're building for is wasm, or else
emits a compilation error. This means that other backends do not have to handle this AIR instruction,
other than the wasm and LLVM backends.
2022-03-03 16:33:46 -07:00
Luuk de Gram
ec4c30ae48 wasm: Implement @wasmMemorySize() builtin
This implements the `wasmMemorySize` builtin, in Sema and the Wasm backend.
The Stage2 implementation differs from stage1 in the way that `index` must be a comptime value.
The stage1 variant is incorrect, as the index is part of the instruction encoding, and therefore,
cannot be a runtime value.
2022-03-03 16:33:46 -07:00
Cody Tapscott
85610a9aff stage2 llvm: Lower 0-bit field-ptr as ptr-to-void 2022-03-03 13:08:14 -07:00
Andrew Kelley
b33f3b23c9 LLVM: fix lowering of unions and switches
`Module.Union.getLayout` now additionally returns a `padding` field
which tells how many bytes are between the final field end offset and
the ending offset of the union. This is used by the LLVM backend to
explicitly insert padding.

LLVM backend: lowering of unions now inserts additional padding so that
LLVM's internals will agree on the ABI size to match what ABI size zig
wants unions to be. This is an alternative to calling LLVMABISizeOfType
and LLVMABIAlignmentOfType which end up crashing when recursive struct
definitions come into play. We no longer ever call these two functions
and the bindings are deleted to avoid future footgun firings.

LLVM backend: lowering of unions now represents untagged unions
consistently. Before it was tripping an assertion.

LLVM backend: switch cases call inttoptr on the case items and condition
if necessary. Prevents tripping an LLVM assertion.

After this commit, we are no longer tripping over any LLVM assertions.
2022-03-03 01:19:49 -07:00
Andrew Kelley
220708e7c3 LLVM: aggregate_init supports structs
in addition to tuples
2022-03-02 13:35:15 -07:00
Veikka Tuominen
ef4aca2dc4 stage2: implement @extern 2022-03-02 12:15:50 +02:00
Andrew Kelley
ed2364a148 stage2: introduce anonymous struct literals 2022-03-01 23:46:57 -07:00
Andrew Kelley
6f303c01f3 LLVM: add extra padding to structs and tuples sometimes
* Sema: resolve type fully when emitting an alloc AIR instruction to
   avoid tripping assertion for checking struct field alignment.
 * LLVM backend: keep a reference to the LLVM target data alive during
   lowering so that we can ask LLVM what it thinks the ABI alignment
   and size of LLVM types are. We need this in order to lower tuples and
   structs so that we can put in extra padding bytes when Zig disagrees
   with LLVM about the size or alignment of something.
 * LLVM backend: make the LLVM struct type packed that contains the most
   aligned union field and the padding. This prevents the struct from
   being too big according to LLVM. In the future, we may want to
   consider instead emitting unions in a "flat" manner; putting the tag,
   most aligned union field, and padding all in the same struct field
   space.
 * LLVM backend: make structs with 2 or fewer fields return isByRef=false.
   This results in more efficient codegen. This required lowering of
   bitcast to sometimes store the struct into an alloca, ptrcast, and
   then load because LLVM does not allow bitcasting structs.
 * enable more passing behavior tests.
2022-03-01 18:24:00 -07:00
Andrew Kelley
f6aaab9406 LLVM: fix tripping assertions
Packed structs were tripping an LLVM assertion due to calling
`LLVMConstZExt` from i16 to i16. Solved by using instead
`LLVMConstZExtOrBitCast`.

Unions were tripping an LLVM assertion due to a typo using the union
llvm type to construct an integer value rather than the tag type.
2022-03-01 14:58:37 -07:00
Andrew Kelley
1b194931b0 LLVM: fix when sret and isByRef ret_ty disagree
This can happen functions use the C ABI.
2022-03-01 14:58:37 -07:00
Andrew Kelley
d5100dc815 stage2: fix frame_address AIR instruction
Various places were assuming different union tags. Now it is
consistently a no-op instruction, just like the similar
instruction ret_addr.
2022-02-28 13:38:33 -07:00
Veikka Tuominen
90bce11f62 stage2: implement @frameAddress 2022-02-28 13:09:14 -07:00
Veikka Tuominen
1bbca4f935 stage2: fix bitcast to optional ptr in llvm backend; omit safety check for intToPtr on optional ptr 2022-02-27 12:15:49 +02:00
Andrew Kelley
2687b8f7f4 stage2: implement @unionInit
The ZIR instruction `union_init_ptr` is renamed to `union_init`.
I made it always use by-value semantics for now, not taking the time to
invest in result location semantics, in case we decide to change the
rules for unions. This way is much simpler.

There is a new AIR instruction: union_init. This is for a comptime known
tag, runtime-known field value.
vector_init is renamed to aggregate_init, which solves a TODO comment.
2022-02-26 20:59:36 -07:00
Veikka Tuominen
bf3c88b68d stage2: various fixes to get one test passing
* resolve error sets before merging them
* implement tupleFieldPtr
* make ret_ptr behave like alloc with zero sized types in llvm backend
2022-02-26 18:44:23 -05:00
Veikka Tuominen
cbd5d6c704 spirv spec: do not align packed struct fields 2022-02-24 19:48:34 +02:00
Veikka Tuominen
b034c45b2b stage2: implement fieldParentPtr 2022-02-24 19:48:34 +02:00
Andrew Kelley
6249a24e81 stage2: integer-backed packed structs
This implements #10113 for the self-hosted compiler only. It removes the
ability to override alignment of packed struct fields, and removes the
ability to put pointers and arrays inside packed structs.

After this commit, nearly all the behavior tests pass for the stage2 llvm
backend that involve packed structs.

I didn't implement the compile errors or compile error tests yet. I'm
waiting until we have stage2 building itself and then I want to rework
the compile error test harness with inspiration from Vexu's arocc test
harness. At that point it should be a much nicer dev experience to work
on compile errors.
2022-02-23 23:59:25 -07:00
Veikka Tuominen
df38c46bee
Merge pull request #10929 from davidmrt98/cbe
stage2: C backend: fix codegen for field_ptr/elem_ptr values
2022-02-22 15:25:50 +02:00
Andrew Kelley
9dc98fbabb Sema: fix comptime union initialization
The mechanism behind initializing a union's tag is a bit complicated,
depending on whether the union is initialized at runtime,
forced comptime, or implicit comptime.

`coerce_result_ptr` now does not force a block to be a runtime context;
instead of adding runtime instructions directly, it forwards analysis to
the respective functions for initializing optionals and error unions.

`validateUnionInit` now has logic to still emit a runtime
`set_union_tag` instruction even if the union pointer is comptime-known,
for the case of a pointer that is not comptime mutable, such as a
variable or the result of `@intToPtr`.

`validateStructInit` looks for a completely different pattern now; it
now handles the possibility of the corresponding AIR instruction for
the `field_ptr` to be missing or the corresponding `store` to be missing.
See the new comment added to the function for more details. An
equivalent change should probably be made to `validateArrayInit`.

`analyzeOptionalPayloadPtr` and `analyzeErrUnionPayloadPtr` functions now
emit a `optional_payload_ptr_set` or `errunion_payload_ptr_set`
instruction respectively if `initializing` is true and the pointer value
is not comptime-mutable.

`storePtr2` now tries the comptime pointer store before checking if the
element type has one possible value because the comptime pointer store
can have side effects of setting a union tag, setting an optional payload
non-null, or setting an error union to be non-error.

The LLVM backend `lowerParentPtr` function is improved to take into
account the differences in how the LLVM values are lowered depending on
the Zig type. It now handles unions correctly as well as additionally
handling optionals and error unions.

In the LLVM backend, the instructions `optional_payload_ptr_set` and
`errunion_payload_ptr_set` check liveness analysis and only do the side
effects in the case the result of the instruction is unused.

A few wasm and C backend test cases regressed, but they are due to TODOs
in lowering of constants, so this is progress.
2022-02-21 23:49:38 -07:00
Andrew Kelley
74303a3d95
Merge pull request #10925 from Vexu/stage2
stage2: support anon init through error unions and optionals
2022-02-21 14:18:17 -05:00
gwenzek
628e9e6d04
enable Gpu address spaces (#10884) 2022-02-21 14:05:27 -05:00
Veikka Tuominen
27c63bf433 stage2: implement errunion_payload_ptr_set 2022-02-19 20:48:00 +02:00
Veikka Tuominen
89f6ff1771 stage2: correct use of .unwrap_err_union_* in LLVM and C backend 2022-02-19 20:21:48 +02:00
David Martschenko
176f7b8600 C backend: adjust order of parameters in renderDeclName 2022-02-19 13:05:09 +01:00
David Martschenko
4a6454fb8d C backend: fix codegen for field_ptr/elem_ptr values 2022-02-19 13:04:59 +01:00
Andrew Kelley
2e1c16d649
Merge pull request #10924 from ziglang/air-independence-day
AIR independence day
2022-02-19 02:57:48 -05:00
Andrew Kelley
4e1e5ab622 stage2: make AIR not reference ZIR for inline assembly
Instead it stores all the information it needs to into AIR.

closes #10784
2022-02-18 19:41:32 -07:00
Cody Tapscott
db80dff4e0 Add backend-specific skips for bitreverse, byteswap tests 2022-02-18 14:28:32 -07:00
Cody Tapscott
ef417f19e1 stage2: Implement @bitReverse and @byteSwap
This change implements the above built-ins for Sema and the LLVM
backend. Other backends have had placeholders added for lowering.
2022-02-18 14:28:32 -07:00
Cody Tapscott
1639fd4c45 Fix 2D array support for C backend
This updates the C backend to use proper array types.

In order to do that, this commit also:
 - fixes up elem_ptr and field_ptr handling
 - adds `renderTypecast` (renders in C typecast format, e.g. "int* [10]")
 - adds a bit special handling for undefined pointers, which is necessary
   to support slice/elem_ptr to undefined decls
2022-02-16 12:57:11 -07:00
Cody Tapscott
c4baa6696e cbe: Add writeCValueDeref and small re-factor 2022-02-16 12:19:54 -07:00
John Schmidt
807edd2234
LLVM backend: refactor LLVM bitcount ops (#10882)
Use `llvm.getIntrinsic` instead of `llvm.getNamedFunction`
2022-02-14 21:52:12 -05:00
Andrew Kelley
a005ac9d3c stage2: implement @popCount for SIMD vectors 2022-02-12 20:44:30 -07:00
Andrew Kelley
91508e10ab LLVM backend: handle unnamed structs when lowering array values
LLVM doesn't support lowering union values, so we have to use unnamed
structs to do it, which means any type that contains a union as an
element, even if it is nested in another type, has to have a mechanism
to detect when it can't be lowered normally and has to resort itself to
an unnamed struct.

This includes arrays.
2022-02-12 11:18:23 +01:00
Andrew Kelley
38236533f1 LLVM backend: avoid creating invalid LLVM types
Fixes assertions from creating i0 types which are not allowed in LLVM.
2022-02-12 11:18:23 +01:00
Andrew Kelley
d72f832b1e LLVM backend: call constPtrToInt instead of constBitCast
when appropriate. Avoids tripping an LLVM assertion.
2022-02-12 11:18:23 +01:00
Andrew Kelley
335c680cde LLVM backend: fix union with only 1 tag tripping llvm assertion 2022-02-12 11:18:23 +01:00
Andrew Kelley
a024aff932 make f80 less hacky; lower as u80 on non-x86
Get rid of `std.math.F80Repr`. Instead of trying to match the memory
layout of f80, we treat it as a value, same as the other floating point
types. The functions `make_f80` and `break_f80` are introduced to
compose an f80 value out of its parts, and the inverse operation.

stage2 LLVM backend: fix pointer to zero length array tripping LLVM
assertion. It now checks for when the element type is a zero-bit type
and lowers such thing the same way that pointers to other zero-bit types
are lowered.

Both stage1 and stage2 LLVM backends are adjusted so that f80 is lowered
as x86_fp80 on x86_64 and i386 architectures, and identical to a u80 on
others. LLVM constants are lowered in a less hacky way now that #10860
is fixed, by using the expression `(exp << 64) | fraction` using llvm
constants.

Sema is improved to handle c_longdouble by recursively handling it
correctly for whatever the float bit width is. In both stage1 and
stage2.
2022-02-12 11:18:23 +01:00
Andrew Kelley
166db1a3ed stage1: fix f80 size and alignment on x86 and arm
* F80Repr extern struct needs no explicit padding; let's match the
   target padding.
 * stage2: fix lowering of f80 constants.
 * stage1: decide ABI size and alignment of f80 based on alignment of
   u64. x86 has alignof u64 equal to 4 but arm has it as 8.
 * stage2: fix Value.floatReadFromMemory to use F80Repr
2022-02-12 11:18:23 +01:00
Andrew Kelley
f293fbbeaf stage2: LLVM backend: adjust replaceAllUsesWith usage
replaceAllUsesWith requires the type to be unchanged. So we bitcast
the new global to the old type and use that as the thing to replace
old uses.

Fixes an LLVM assertion found while troubleshooting #10837.
2022-02-12 11:18:23 +01:00
Andrew Kelley
c10fdde5a6 stage2: LLVM backend: make unnamed struct globals
LLVM union globals have to be lowered as unnamed structs if the
non-most-aligned field is the active tag. In this case it bubbles up so
that structs containing unions have the same restriction.

This fix needs to be applied to optionals and other callsites of
createNamedStruct.

The bug fixed in this commit was revealed in searching for
the cause of #10837.
2022-02-10 00:27:02 -07:00
John Schmidt
7f0cf395aa stage2: implement all builtin floatops for f{16,32,64}
- Merge `floatop.zig` and `floatop_stage1.zig` since most tests now pass
  on stage2.
- Add more behavior tests for a bunch of functions.
2022-02-09 20:29:41 -05:00
John Schmidt
722d4a11bb stage2: implement @sqrt for f{16,32,64}
Support for f128, comptime_float, and c_longdouble require improvements
to compiler_rt and will implemented in a later PR. Some of the code in
this commit could be made more generic, for instance `llvm.airSqrt`
could probably be `llvm.airUnaryMath`, but let's cross that
bridge when we get to it.
2022-02-07 16:52:19 -07:00
Andrew Kelley
9acf06d28a
Merge pull request #10803 from ziglang/decl-has-lib-name
stage2: store externs lib name as part of decl
2022-02-07 13:30:59 -05:00
Jakub Konka
556f0ce5bf stage2: add new Decl subtype, ExternFn
`ExternFn` will contain a maybe-lib-name if it was defined with
the `extern` keyword like so

```zig
extern "c" fn write(usize, usize, usize) usize;
```

`lib_name` will live as long as `ExternFn` decl does.
2022-02-06 08:42:14 +01:00
gwenzek
0e1afb4d98
stage2: add support for Nvptx target
sample command:

/home/guw/github/zig/stage2/bin/zig build-obj cuda_kernel.zig -target nvptx64-cuda -O ReleaseSafe
this will create a kernel.ptx

expose PtxKernel call convention from LLVM
kernels are `export fn f() callconv(.PtxKernel)`
2022-02-05 16:33:00 +02:00
Andrew Kelley
3e99495ed8
Merge pull request #10742 from ziglang/ArrayHashMapEql
std: make ArrayHashMap eql function accept an additional param
2022-02-01 13:20:28 -05:00
Andrew Kelley
39983d7ff5 stage2: update to new ArrayHashMap API 2022-01-31 21:12:37 -07:00
Andrew Kelley
fb7060d3c2 stage2: implement shl_exact and shr_exact
These produce an undefined value when one bits are shifted out.

New AIR instruction: shr_exact.
2022-01-30 16:23:31 -07:00