| Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
|
|
|
|
|
|
all behavior tests passing in this branch
|
|
* add safety panic for resuming a function which is returning, pending
an await
* remove IrInstructionResultPtr
* add IrInstructionReturnBegin. This does the early return in async
functions; does nothing in normal functions.
* `await` gets a result location
* `analyze_fn_async` will call `analyze_fn_body` if necessary.
* async function frames have a result pointer field for themselves
to access and one for the awaiter to supply before the atomic rmw.
when returning, async functions copy the result to the awaiter result
pointer, if it is non-null.
* async function frames have a stack trace pointer which is supplied by
the awaiter before the atomicrmw. Later in the frame is a stack trace
struct and addresses, which is used for its own calls and awaits.
* when awaiting an async function, if an early return occurred, the
awaiter tail resumes the frame.
* when an async function returns, early return does a suspend
(in IrInstructionReturnBegin) before copying
the error return trace data, result, and running the defers.
After the last defer runs, the frame will no longer be accessed.
* proper acquire/release atomic ordering attributes in async functions.
|
|
this IR instruction is no longer needed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rbscott-comptime-union-init
|
|
|
|
|
|
|
|
@round
and expand @sqrt
This revealed that the accuracy of ln is not as good as the current algorithm in
musl and glibc, and should be ported again.
v2: actually include tests
v3: fix reversal of in and out arguments on f128M_sqrt()
add test for @sqrt on comptime_float
do not include @nearbyInt() until it works on all targets.
|
|
|
|
floats
Not all of the softfloat library is being built....
Vector support is very buggy at the moment, but should work when the bugs are fixed.
(as I had the same code working with another vector function, that hasn't been merged yet).
|
|
|
|
|
|
|
|
somewhere along this branch, #1901 has been fixed.
|
|
|
|
|
|
|
|
```zig
export fn entry() void {
var x: @Vector(4, i32) = undefined;
var y: [4]i32 = x;
}
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%x = alloca <4 x i32>, align 16
%y = alloca [4 x i32], align 4
%0 = bitcast <4 x i32>* %x to i8*, !dbg !47
call void @llvm.memset.p0i8.i64(i8* align 16 %0, i8 -86, i64 16, i1 false), !dbg !47
call void @llvm.dbg.declare(metadata <4 x i32>* %x, metadata !39, metadata !DIExpression()), !dbg !47
%1 = load <4 x i32>, <4 x i32>* %x, align 16, !dbg !48
%2 = bitcast [4 x i32]* %y to <4 x i32>*, !dbg !48
store <4 x i32> %1, <4 x i32>* %2, align 16, !dbg !48
call void @llvm.dbg.declare(metadata [4 x i32]* %y, metadata !45, metadata !DIExpression()), !dbg !49
ret void, !dbg !50
}
```
|
|
```zig
export fn entry() void {
var x = foo();
var ptr = &x.b;
var y = ptr.*;
}
const Foo = packed struct {
a: u24 = 1,
b: Bar = Bar{},
};
const Bar = packed struct {
a: u4 = 2,
b: u4 = 3,
};
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%x = alloca %Foo, align 1
%ptr = alloca i32*, align 8
%y = alloca %Bar, align 1
call fastcc void @foo(%Foo* sret %x), !dbg !55
call void @llvm.dbg.declare(metadata %Foo* %x, metadata !39, metadata !DIExpression()), !dbg !56
%0 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0, !dbg !57
store i32* %0, i32** %ptr, align 8, !dbg !57
call void @llvm.dbg.declare(metadata i32** %ptr, metadata !51, metadata !DIExpression()), !dbg !58
%1 = load i32*, i32** %ptr, align 8, !dbg !59
%2 = load i32, i32* %1, align 1, !dbg !60
%3 = lshr i32 %2, 24, !dbg !60
%4 = trunc i32 %3 to i8, !dbg !60
%5 = bitcast %Bar* %y to i8*, !dbg !60
store i8 %4, i8* %5, !dbg !60
call void @llvm.dbg.declare(metadata %Bar* %y, metadata !54, metadata !DIExpression()), !dbg !61
ret void, !dbg !62
}
```
|
|
|
|
|
|
|
|
|
|
|
|
```zig
export fn entry() void {
var buf: [10]u8 = undefined;
const slice1: []const u8 = &buf;
const slice2 = buf[0..];
}
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%buf = alloca [10 x i8], align 1
%slice1 = alloca %"[]u8", align 8
%slice2 = alloca %"[]u8", align 8
%0 = bitcast [10 x i8]* %buf to i8*, !dbg !46
call void @llvm.memset.p0i8.i64(i8* align 1 %0, i8 -86, i64 10, i1 false), !dbg !46
call void @llvm.dbg.declare(metadata [10 x i8]* %buf, metadata !39, metadata !DIExpression()), !dbg !46
%1 = getelementptr inbounds %"[]u8", %"[]u8"* %slice1, i32 0, i32 0, !dbg !47
%2 = getelementptr inbounds [10 x i8], [10 x i8]* %buf, i64 0, i64 0, !dbg !47
store i8* %2, i8** %1, align 8, !dbg !47
%3 = getelementptr inbounds %"[]u8", %"[]u8"* %slice1, i32 0, i32 1, !dbg !47
store i64 10, i64* %3, align 8, !dbg !47
call void @llvm.dbg.declare(metadata %"[]u8"* %slice1, metadata !44, metadata !DIExpression()), !dbg !48
%4 = getelementptr inbounds %"[]u8", %"[]u8"* %slice2, i32 0, i32 0, !dbg !49
%5 = getelementptr inbounds [10 x i8], [10 x i8]* %buf, i64 0, i64 0, !dbg !49
store i8* %5, i8** %4, align 8, !dbg !49
%6 = getelementptr inbounds %"[]u8", %"[]u8"* %slice2, i32 0, i32 1, !dbg !49
store i64 10, i64* %6, align 8, !dbg !49
call void @llvm.dbg.declare(metadata %"[]u8"* %slice2, metadata !45, metadata !DIExpression()), !dbg !50
ret void, !dbg !51
}
```
|
|
```zig
export fn entry() void {
var x = @bitCast(f32, foo());
}
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%x = alloca float, align 4
%0 = bitcast float* %x to %Foo*, !dbg !42
call fastcc void @foo(%Foo* sret %0), !dbg !42
call void @llvm.dbg.declare(metadata float* %x, metadata !39, metadata !DIExpression()), !dbg !43
ret void, !dbg !44
}
```
|
|
```zig
export fn entry() void {
var x = Foo{ .bar = bar() };
}
```
```llvm
define void @entry() #2 !dbg !44 {
Entry:
%x = alloca %Foo, align 4
%0 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 1, !dbg !68
store i1 true, i1* %0, align 1, !dbg !68
%1 = getelementptr inbounds %Foo, %Foo* %x, i32 0, i32 0, !dbg !68
%2 = bitcast { i32, [4 x i8] }* %1 to %Bar*, !dbg !68
call fastcc void @bar(%Bar* sret %2), !dbg !68
call void @llvm.dbg.declare(metadata %Foo* %x, metadata !48, metadata !DIExpression()), !dbg !69
ret void, !dbg !70
}
```
|
|
|
|
```zig
export fn entry() void {
const static = Foo{
.x = 9,
.bar = Bar{ .y = 10 },
};
const runtime = foo(true);
}
fn foo(c: bool) Foo {
return Foo{
.x = 12,
.bar = if (c) bar1() else bar2(),
};
}
fn bar1() Bar {
return Bar{ .y = 34 };
}
fn bar2() Bar {
return Bar{ .y = 56 };
}
```
```llvm
@0 = internal unnamed_addr constant %Foo { i32 9, %Bar { i32 10 } }, align 4
@1 = internal unnamed_addr constant %Bar { i32 34 }, align 4
@2 = internal unnamed_addr constant %Bar { i32 56 }, align 4
define void @entry() #2 !dbg !35 {
Entry:
%runtime = alloca %Foo, align 4
call void @llvm.dbg.declare(metadata %Foo* @0, metadata !39, metadata !DIExpression()), !dbg !50
call fastcc void @foo(%Foo* sret %runtime, i1 true), !dbg !51
call void @llvm.dbg.declare(metadata %Foo* %runtime, metadata !49, metadata !DIExpression()), !dbg !52
ret void, !dbg !53
}
define internal fastcc void @foo(%Foo* nonnull sret, i1) unnamed_addr #2 !dbg !54 {
Entry:
%c = alloca i1, align 1
store i1 %1, i1* %c, align 1
call void @llvm.dbg.declare(metadata i1* %c, metadata !60, metadata !DIExpression()), !dbg !61
%2 = getelementptr inbounds %Foo, %Foo* %0, i32 0, i32 0, !dbg !62
store i32 12, i32* %2, align 4, !dbg !62
%3 = getelementptr inbounds %Foo, %Foo* %0, i32 0, i32 1, !dbg !64
%4 = load i1, i1* %c, align 1, !dbg !65
br i1 %4, label %Then, label %Else, !dbg !65
Then: ; preds = %Entry
call fastcc void @bar1(%Bar* sret %3), !dbg !66
br label %EndIf, !dbg !64
Else: ; preds = %Entry
call fastcc void @bar2(%Bar* sret %3), !dbg !67
br label %EndIf, !dbg !64
EndIf: ; preds = %Else, %Then
ret void, !dbg !68
}
define internal fastcc void @bar1(%Bar* nonnull sret) unnamed_addr #2 !dbg !69 {
Entry:
%1 = bitcast %Bar* %0 to i8*, !dbg !73
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 bitcast (%Bar* @1 to i8*), i64 4, i1 false), !dbg !73
ret void, !dbg !73
}
define internal fastcc void @bar2(%Bar* nonnull sret) unnamed_addr #2 !dbg !75 {
Entry:
%1 = bitcast %Bar* %0 to i8*, !dbg !76
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %1, i8* align 4 bitcast (%Bar* @2 to i8*), i64 4, i1 false), !dbg !76
ret void, !dbg !76
}
!39 = !DILocalVariable(name: "static", scope: !40, file: !5, line: 2, type: !41)
!49 = !DILocalVariable(name: "runtime", scope: !40, file: !5, line: 6, type: !41)
```
|
|
```zig
export fn entry() void {
var c = true;
var x = if (c) foo() else bar();
}
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%c = alloca i1, align 1
%x = alloca %Foo, align 4
store i1 true, i1* %c, align 1, !dbg !47
call void @llvm.dbg.declare(metadata i1* %c, metadata !39, metadata !DIExpression()), !dbg !48
%0 = load i1, i1* %c, align 1, !dbg !49
br i1 %0, label %Then, label %Else, !dbg !49
Then: ; preds = %Entry
call fastcc void @foo(%Foo* sret %x), !dbg !50
br label %EndIf, !dbg !51
Else: ; preds = %Entry
call fastcc void @bar(%Foo* sret %x), !dbg !52
br label %EndIf, !dbg !51
EndIf: ; preds = %Else, %Then
call void @llvm.dbg.declare(metadata %Foo* %x, metadata !42, metadata !DIExpression()), !dbg !53
ret void, !dbg !54
}
```
|
|
Note that only the index variable requires a stack allocation, and the
memcpy for the element is gone.
```zig
export fn entry() void {
var buf: [10]i32 = undefined;
for (buf) |x| {}
}
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%buf = alloca [10 x i32], align 4
%i = alloca i64, align 8
%0 = bitcast [10 x i32]* %buf to i8*, !dbg !47
call void @llvm.memset.p0i8.i64(i8* align 4 %0, i8 -86, i64 40, i1 false), !dbg !47
call void @llvm.dbg.declare(metadata [10 x i32]* %buf, metadata !39, metadata !DIExpression()), !dbg !47
store i64 0, i64* %i, align 8, !dbg !48
call void @llvm.dbg.declare(metadata i64* %i, metadata !45, metadata !DIExpression()), !dbg !48
br label %ForCond, !dbg !48
ForCond: ; preds = %ForBody, %Entry
%1 = load i64, i64* %i, align 8, !dbg !48
%2 = icmp ult i64 %1, 10, !dbg !48
br i1 %2, label %ForBody, label %ForEnd, !dbg !48
ForBody: ; preds = %ForCond
%3 = getelementptr inbounds [10 x i32], [10 x i32]* %buf, i64 0, i64 %1, !dbg !48
call void @llvm.dbg.declare(metadata i32* %3, metadata !46, metadata !DIExpression()), !dbg !49
%4 = add nuw i64 %1, 1, !dbg !48
store i64 %4, i64* %i, align 8, !dbg !48
br label %ForCond, !dbg !48
ForEnd: ; preds = %ForCond
ret void, !dbg !50
}
```
|
|
Note that neither the payload capture variable nor the error capture
variable require a stack allocation.
```zig
export fn entry() void {
var c: anyerror!i32 = 1234;
while (c) |hi| {} else |e| {}
}
```
```llvm
define void @entry() #2 !dbg !39 {
Entry:
%c = alloca { i16, i32 }, align 4
%0 = bitcast { i16, i32 }* %c to i8*, !dbg !52
call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast ({ i16, i32 }* @0 to i8*), i64 8, i1 false), !dbg !52
call void @llvm.dbg.declare(metadata { i16, i32 }* %c, metadata !43, metadata !DIExpression()), !dbg !52
br label %WhileCond, !dbg !53
WhileCond: ; preds = %WhileBody, %Entry
%1 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 0, !dbg !54
%2 = load i16, i16* %1, align 2, !dbg !54
%3 = icmp ne i16 %2, 0, !dbg !54
br i1 %3, label %WhileElse, label %WhileBody, !dbg !54
WhileBody: ; preds = %WhileCond
%4 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 1, !dbg !53
call void @llvm.dbg.declare(metadata i32* %4, metadata !50, metadata !DIExpression()), !dbg !53
br label %WhileCond, !dbg !53
WhileElse: ; preds = %WhileCond
%5 = getelementptr inbounds { i16, i32 }, { i16, i32 }* %c, i32 0, i32 0, !dbg !55
call void @llvm.dbg.declare(metadata i16* %5, metadata !51, metadata !DIExpression()), !dbg !55
ret void, !dbg !56
}
```
|
|
|
|
```zig
export fn entry() void {
var c = true;
var x = if (c) u8(4) else u32(10);
}
```
```llvm
define void @entry() #2 !dbg !35 {
Entry:
%c = alloca i1, align 1
%x = alloca i32, align 4
store i1 true, i1* %c, align 1, !dbg !44
call void @llvm.dbg.declare(metadata i1* %c, metadata !39, metadata !DIExpression()), !dbg !45
%0 = load i1, i1* %c, align 1, !dbg !46
br i1 %0, label %Then, label %Else, !dbg !46
Then: ; preds = %Entry
br label %EndIf, !dbg !47
Else: ; preds = %Entry
br label %EndIf, !dbg !47
EndIf: ; preds = %Else, %Then
%1 = phi i32 [ 4, %Then ], [ 10, %Else ], !dbg !47
store i32 %1, i32* %x, align 4, !dbg !47
call void @llvm.dbg.declare(metadata i32* %x, metadata !42, metadata !DIExpression()), !dbg !48
ret void, !dbg !49
}
```
|