Changing how defer works. Remove of undef. Simplify ensure.

This commit is contained in:
Christoffer Lerno
2022-03-05 01:44:09 +01:00
committed by Christoffer Lerno
parent 9b0dfe8ba3
commit 069a2d40cb
40 changed files with 1411 additions and 1080 deletions

View File

@@ -53,30 +53,18 @@ entry:
define i32 @simple_test.test2(i32* %0, i32 %1) #0 {
entry:
%return = alloca i32, align 4
%gt = icmp sgt i32 %1, 100
call void @llvm.assume(i1 %gt)
store i32 444, i32* %0, align 8
store i32 %1, i32* %return, align 4
%2 = load i32, i32* %return, align 4
%lt = icmp slt i32 %2, 200
call void @llvm.assume(i1 %lt)
%3 = load i32, i32* %return, align 4
ret i32 %3
ret i32 %1
}
define i32 @simple_test.test3(i32 %0) #0 {
entry:
%return = alloca i32, align 4
%gt = icmp sgt i32 %0, 0
call void @llvm.assume(i1 %gt)
%add = add i32 %0, 1
store i32 %add, i32* %return, align 4
%1 = load i32, i32* %return, align 4
%gt1 = icmp sgt i32 %1, 0
call void @llvm.assume(i1 %gt1)
%2 = load i32, i32* %return, align 4
ret i32 %2
ret i32 %add
}
define void @simple_test.main() #0 {

View File

@@ -21,7 +21,7 @@ fn void main()
test(10); // Prints "B!A"
}
// #expect: defer1.ll
/* #expect: defer1.ll
define void @defer1.test(i32 %0) #0 {
entry:
@@ -30,48 +30,24 @@ entry:
if.then: ; preds = %entry
%1 = call i32 @"std::io.print"(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i32 0, i32 0))
br label %exit
exit: ; preds = %if.then
%2 = call i32 @"std::io.println"(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.1, i32 0, i32 0)) #1
br label %exit1
exit1: ; preds = %exit
ret void
if.exit: ; preds = %entry
%eq2 = icmp eq i32 %0, 0
br i1 %eq2, label %if.then3, label %if.exit7
%eq1 = icmp eq i32 %0, 0
br i1 %eq1, label %if.then2, label %if.exit3
if.then3: ; preds = %if.exit
if.then2: ; preds = %if.exit
%3 = call i32 @"std::io.print"(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.2, i32 0, i32 0))
br label %exit4
exit4: ; preds = %if.then3
%4 = call i32 @"std::io.print"(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i32 0, i32 0))
br label %exit5
exit5: ; preds = %exit4
%5 = call i32 @"std::io.println"(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i32 0, i32 0)) #1
br label %exit6
exit6: ; preds = %exit5
ret void
if.exit7: ; preds = %if.exit
if.exit3: ; preds = %if.exit
%6 = call i32 @"std::io.print"(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.5, i32 0, i32 0))
br label %exit8
exit8: ; preds = %if.exit7
%7 = call i32 @"std::io.print"(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.6, i32 0, i32 0))
%8 = call i32 @"std::io.print"(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.7, i32 0, i32 0))
br label %exit9
exit9: ; preds = %exit8
%9 = call i32 @"std::io.println"(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.8, i32 0, i32 0)) #1
br label %exit10
exit10: ; preds = %exit9
ret void
}

View File

@@ -0,0 +1,83 @@
// #target: x64-darwin
module foo;
extern fn void printf(char*,...);
macro int abc(x)
{
defer printf("Out x %d\n", x);
x *= 2;
if (x > 100) return x = x - 100;
printf("Normal end\n");
return x;
}
fn void main()
{
defer printf("On exit\n");
@abc(123);
@abc(3);
}
/* #expect: foo.ll
define void @foo.main() #0 {
entry:
%x = alloca i32, align 4
%blockret = alloca i32, align 4
%x1 = alloca i32, align 4
%blockret2 = alloca i32, align 4
store i32 123, i32* %x, align 4
%0 = load i32, i32* %x, align 4
%mul = mul i32 %0, 2
store i32 %mul, i32* %x, align 4
%1 = load i32, i32* %x, align 4
%gt = icmp sgt i32 %1, 100
br i1 %gt, label %if.then, label %if.exit
if.then: ; preds = %entry
%2 = load i32, i32* %x, align 4
%sub = sub i32 %2, 100
store i32 %sub, i32* %x, align 4
%3 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0), i32 %3)
store i32 %sub, i32* %blockret, align 4
br label %expr_block.exit
if.exit: ; preds = %entry
call void (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.1, i32 0, i32 0))
%4 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i32 0, i32 0), i32 %4)
%5 = load i32, i32* %x, align 4
store i32 %5, i32* %blockret, align 4
br label %expr_block.exit
expr_block.exit: ; preds = %if.exit, %if.then
store i32 3, i32* %x1, align 4
%6 = load i32, i32* %x1, align 4
%mul3 = mul i32 %6, 2
store i32 %mul3, i32* %x1, align 4
%7 = load i32, i32* %x1, align 4
%gt4 = icmp sgt i32 %7, 100
br i1 %gt4, label %if.then5, label %if.exit7
if.then5: ; preds = %expr_block.exit
%8 = load i32, i32* %x1, align 4
%sub6 = sub i32 %8, 100
store i32 %sub6, i32* %x1, align 4
%9 = load i32, i32* %x1, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.3, i32 0, i32 0), i32 %9)
store i32 %sub6, i32* %blockret2, align 4
br label %expr_block.exit8
if.exit7: ; preds = %expr_block.exit
call void (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.4, i32 0, i32 0))
%10 = load i32, i32* %x1, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.5, i32 0, i32 0), i32 %10)
%11 = load i32, i32* %x1, align 4
store i32 %11, i32* %blockret2, align 4
br label %expr_block.exit8
expr_block.exit8: ; preds = %if.exit7, %if.then5
call void (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.6, i32 0, i32 0))
ret void
}

View File

@@ -45,12 +45,6 @@ entry:
call void @foo.foo1()
call void (i8*, ...) @printf(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i32 0, i32 0), i32 3)
call void @foo2.foo2()
br label %exit
exit: ; preds = %entry
call void @foo2.foo2()
br label %exit1
exit1: ; preds = %exit
ret void
}

View File

@@ -21,6 +21,7 @@ fn void main()
define void @foo.main() #0 {
entry:
%x = alloca i32, align 4
%blockret = alloca i32, align 4
%x1 = alloca i32, align 4
store i32 0, i32* %x, align 4
store i32 0, i32* %x1, align 4
@@ -32,9 +33,10 @@ entry:
store i32 %add2, i32* %x, align 4
%add3 = add i32 %add, %add2
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0))
br label %exit
store i32 %add3, i32* %blockret, align 4
br label %expr_block.exit
exit: ; preds = %entry
expr_block.exit: ; preds = %entry
%3 = load i32, i32* %x, align 4
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i32 0, i32 0), i32 %3)
ret void

View File

@@ -38,9 +38,6 @@ entry:
%add1 = add i32 %3, 1
store i32 %add1, i32* %x, align 4
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.1, i32 0, i32 0), i32 %3)
br label %exit
exit: ; preds = %entry
%5 = load i32, i32* %a, align 4
store i32 %5, i32* %y, align 4
%6 = load i32, i32* %x, align 4
@@ -51,9 +48,6 @@ exit: ; preds = %entry
%add3 = add i32 %8, 1
store i32 %add3, i32* %x, align 4
%9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.3, i32 0, i32 0), i32 %8)
br label %exit4
exit4: ; preds = %exit
%10 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.4, i32 0, i32 0))
ret void
}

View File

@@ -81,7 +81,6 @@ fn void main()
@.str = private unnamed_addr constant [16 x i8] c"%f => %d => %f\0A\00", align 1
@.str.1 = private unnamed_addr constant [18 x i8] c"%e => %llu => %e\0A\00", align 1
; Function Attrs: nounwind
define i64 @userland_bitcast.testFoo(i16 signext %0) #0 {
entry:
%z = alloca %Foo, align 2
@@ -104,6 +103,7 @@ entry:
store i16 %0, i16* %6, align 2
%7 = load %Foo, %Foo* %z, align 2
store %Foo %7, %Foo* %expr, align 2
store i64 0, i64* %x, align 8
%ptrptr = bitcast %Foo* %expr to i16*
store i16* %ptrptr, i16** %b, align 8
%ptrptr1 = bitcast i64* %x to i16*
@@ -144,6 +144,14 @@ entry:
%i = alloca i64, align 8
%tempcoerce = alloca i32, align 4
store float %0, float* %expr, align 4
%1 = getelementptr inbounds [4 x i8], [4 x i8]* %x, i64 0, i64 0
store i8 0, i8* %1, align 1
%2 = getelementptr inbounds [4 x i8], [4 x i8]* %x, i64 0, i64 1
store i8 0, i8* %2, align 1
%3 = getelementptr inbounds [4 x i8], [4 x i8]* %x, i64 0, i64 2
store i8 0, i8* %3, align 1
%4 = getelementptr inbounds [4 x i8], [4 x i8]* %x, i64 0, i64 3
store i8 0, i8* %4, align 1
%ptrptr = bitcast float* %expr to i8*
store i8* %ptrptr, i8** %b, align 8
%ptrptr1 = bitcast [4 x i8]* %x to i8*
@@ -152,30 +160,30 @@ entry:
br label %loop.cond
loop.cond: ; preds = %loop.body, %entry
%1 = load i64, i64* %i, align 8
%lt = icmp ult i64 %1, 4
%5 = load i64, i64* %i, align 8
%lt = icmp ult i64 %5, 4
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%2 = load i8*, i8** %to, align 8
%3 = load i64, i64* %i, align 8
%ptroffset = getelementptr inbounds i8, i8* %2, i64 %3
%4 = load i8*, i8** %b, align 8
%5 = load i64, i64* %i, align 8
%ptroffset2 = getelementptr inbounds i8, i8* %4, i64 %5
%6 = load i8, i8* %ptroffset2, align 1
store i8 %6, i8* %ptroffset, align 1
%6 = load i8*, i8** %to, align 8
%7 = load i64, i64* %i, align 8
%add = add i64 %7, 1
%ptroffset = getelementptr inbounds i8, i8* %6, i64 %7
%8 = load i8*, i8** %b, align 8
%9 = load i64, i64* %i, align 8
%ptroffset2 = getelementptr inbounds i8, i8* %8, i64 %9
%10 = load i8, i8* %ptroffset2, align 1
store i8 %10, i8* %ptroffset, align 1
%11 = load i64, i64* %i, align 8
%add = add i64 %11, 1
store i64 %add, i64* %i, align 8
br label %loop.cond
loop.exit: ; preds = %loop.cond
%8 = bitcast i32* %tempcoerce to i8*
%9 = bitcast [4 x i8]* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %8, i8* align 1 %9, i32 4, i1 false)
%10 = load i32, i32* %tempcoerce, align 4
ret i32 %10
%12 = bitcast i32* %tempcoerce to i8*
%13 = bitcast [4 x i8]* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 4 %12, i8* align 1 %13, i32 4, i1 false)
%14 = load i32, i32* %tempcoerce, align 4
ret i32 %14
}
define void @userland_bitcast.main() #0 {
@@ -209,6 +217,7 @@ entry:
store float 0x4028B4BC60000000, float* %f, align 4
%0 = load float, float* %f, align 4
store float %0, float* %expr, align 4
store i32 0, i32* %x, align 4
%ptrptr = bitcast float* %expr to i32*
store i32* %ptrptr, i32** %b, align 8
store i32* %x, i32** %to, align 8
@@ -239,6 +248,7 @@ loop.exit: ; preds = %loop.cond
store i32 %8, i32* %i, align 4
%9 = load i32, i32* %i, align 4
store i32 %9, i32* %expr3, align 4
store float 0.000000e+00, float* %x4, align 4
store i32* %expr3, i32** %b5, align 8
%ptrptr7 = bitcast float* %x4 to i32*
store i32* %ptrptr7, i32** %to6, align 8
@@ -276,6 +286,7 @@ loop.exit15: ; preds = %loop.cond9
store double 1.235300e+268, double* %d, align 8
%21 = load double, double* %d, align 8
store double %21, double* %expr17, align 8
store i64 0, i64* %x18, align 8
%ptrptr20 = bitcast double* %expr17 to i64*
store i64* %ptrptr20, i64** %b19, align 8
store i64* %x18, i64** %to21, align 8
@@ -306,6 +317,7 @@ loop.exit29: ; preds = %loop.cond23
store i64 %29, i64* %l, align 8
%30 = load double, double* %d, align 8
store double %30, double* %expr30, align 8
store double 0.000000e+00, double* %x31, align 8
%ptrptr33 = bitcast double* %expr30 to i64*
store i64* %ptrptr33, i64** %b32, align 8
%ptrptr35 = bitcast double* %x31 to i64*
@@ -340,4 +352,5 @@ loop.exit43: ; preds = %loop.cond37
%41 = load double, double* %d2, align 8
call void (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.1, i32 0, i32 0), double %39, i64 %40, double %41)
ret void
}
}

View File

@@ -18,11 +18,10 @@ fn int main(int argc, char** argv)
{
int a = 0;
{
defer
{
defer do {
if (a == 1) break;
defer1();
}
} while(0);
defer2();
}
defer defer3();
@@ -58,82 +57,58 @@ entry:
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %entry
br label %exit
br label %loop.exit
if.exit: ; preds = %entry
call void @foo.defer1()
br label %exit
br label %loop.exit
exit: ; preds = %if.exit, %if.then
loop.exit: ; preds = %if.exit, %if.then
br label %loop.cond
loop.cond: ; preds = %exit6, %exit
loop.cond: ; preds = %if.exit3, %loop.exit
%3 = load i32, i32* %a, align 4
%intbool = icmp ne i32 %3, 0
br i1 %intbool, label %loop.body, label %loop.exit
br i1 %intbool, label %loop.body, label %loop.exit4
loop.body: ; preds = %loop.cond
%eq1 = icmp eq i32 %0, 1
br i1 %eq1, label %if.then2, label %if.exit4
br i1 %eq1, label %if.then2, label %if.exit3
if.then2: ; preds = %loop.body
call void @foo.defer4()
br label %exit3
br label %loop.exit4
exit3: ; preds = %if.then2
br label %loop.exit
if.exit4: ; preds = %loop.body
if.exit3: ; preds = %loop.body
call void @foo.defer6()
call void @foo.defer5()
br label %exit5
exit5: ; preds = %if.exit4
call void @foo.defer4()
br label %exit6
exit6: ; preds = %exit5
br label %loop.cond
loop.exit: ; preds = %exit3, %loop.cond
br label %loop.cond7
loop.exit4: ; preds = %if.then2, %loop.cond
br label %loop.cond5
loop.cond7: ; preds = %loop.exit
loop.cond5: ; preds = %loop.exit4
%4 = load i32, i32* %a, align 4
%intbool8 = icmp ne i32 %4, 0
br i1 %intbool8, label %loop.body9, label %loop.exit18
%intbool6 = icmp ne i32 %4, 0
br i1 %intbool6, label %loop.body7, label %loop.exit11
loop.body9: ; preds = %loop.cond7
%eq10 = icmp eq i32 %0, 1
br i1 %eq10, label %if.then11, label %if.exit13
loop.body7: ; preds = %loop.cond5
%eq8 = icmp eq i32 %0, 1
br i1 %eq8, label %if.then9, label %if.exit10
if.then11: ; preds = %loop.body9
if.then9: ; preds = %loop.body7
call void @foo.defer8()
br label %exit12
br label %loop.exit11
exit12: ; preds = %if.then11
br label %loop.exit18
if.exit13: ; preds = %loop.body9
if.exit10: ; preds = %loop.body7
call void @foo.defer10()
call void @foo.defer9()
br label %exit14
exit14: ; preds = %if.exit13
call void @foo.defer8()
br label %exit15
br label %loop.exit11
exit15: ; preds = %exit14
br label %loop.exit18
loop.exit18: ; preds = %exit15, %exit12, %loop.cond7
loop.exit11: ; preds = %if.exit10, %if.then9, %loop.cond5
call void @foo.defer7()
br label %exit19
exit19: ; preds = %loop.exit18
call void @foo.defer3()
br label %exit20
exit20: ; preds = %exit19
ret i32 0
}

View File

@@ -23,7 +23,8 @@ fn int main(int argc, char** argv)
return 0;
}
// #expect: test.ll
/* #expect: test.ll
define i32 @main(i32 %0, i8** %1) #0 {
@@ -32,7 +33,7 @@ entry:
store i32 0, i32* %a, align 4
br label %loop.cond
loop.cond: ; preds = %exit3, %entry
loop.cond: ; preds = %if.exit, %entry
%2 = load i32, i32* %a, align 4
%intbool = icmp ne i32 %2, 0
br i1 %intbool, label %loop.body, label %loop.exit
@@ -44,28 +45,16 @@ loop.body: ; preds = %loop.cond
if.then: ; preds = %loop.body
call void @test.testA()
call void @test.testB()
br label %exit
exit: ; preds = %if.then
call void @test.test2()
br label %exit1
exit1: ; preds = %exit
br label %loop.exit
if.exit: ; preds = %loop.body
call void @test.test3()
call void @test.testA()
call void @test.testB()
br label %exit2
exit2: ; preds = %if.exit
call void @test.test2()
br label %exit3
exit3: ; preds = %exit2
br label %loop.cond
loop.exit: ; preds = %exit1, %loop.cond
loop.exit: ; preds = %if.then, %loop.cond
ret i32 0
}

View File

@@ -19,7 +19,7 @@ fn void test(int i)
}
}
// #expect: defer_break_switch.ll
/* #expect: defer_break_switch.ll
define void @defer_break_switch.test(i32 %0) #0 {
entry:
@@ -33,7 +33,7 @@ switch.entry: ; preds = %entry
%1 = load i32, i32* %switch, align 4
switch i32 %1, label %switch.exit [
i32 1, label %switch.case
i32 2, label %switch.case2
i32 2, label %switch.case1
]
switch.case: ; preds = %switch.entry
@@ -43,23 +43,17 @@ switch.case: ; preds = %switch.entry
if.then: ; preds = %switch.case
call void @defer_break_switch.test2()
br label %exit
exit: ; preds = %if.then
br label %switch.exit
if.exit: ; preds = %switch.case
call void @defer_break_switch.test1()
call void @defer_break_switch.test2()
br label %exit1
exit1: ; preds = %if.exit
br label %switch.exit
switch.case2: ; preds = %switch.entry
switch.case1: ; preds = %switch.entry
call void @defer_break_switch.test1()
br label %switch.exit
switch.exit: ; preds = %switch.case2, %exit1, %exit, %switch.entry
switch.exit: ; preds = %switch.case1, %if.exit, %if.then, %switch.entry
ret void
}

View File

@@ -0,0 +1,38 @@
// #target: x64-darwin
module foo;
fn void test()
{
int a;
do
{
a++;
defer a++;
} while(a < 10);
}
/* #expect: foo.ll
define void @foo.test() #0 {
entry:
%a = alloca i32, align 4
store i32 0, i32* %a, align 4
br label %loop.body
loop.cond: ; preds = %loop.body
%0 = load i32, i32* %a, align 4
%lt = icmp slt i32 %0, 10
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond, %entry
%1 = load i32, i32* %a, align 4
%add = add i32 %1, 1
store i32 %add, i32* %a, align 4
%2 = load i32, i32* %a, align 4
%add1 = add i32 %2, 1
store i32 %add1, i32* %a, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
ret void
}

View File

@@ -0,0 +1,71 @@
// #target: x64-darwin
module foo;
extern fn void printf(char*,...);
fn void test(int x)
{
defer printf("---\n");
{|
defer printf("Hello %d\n", x);
x *= 2;
if (x < 100) return;
x *= 10000;
|};
printf("+++\n");
if (x == 0)
{
printf("0x\n");
return;
}
if (x == 1) return;
}
fn void main()
{
test(123);
test(1);
test(0);
}
/* #expect: foo.ll
define void @foo.test(i32 %0) #0 {
entry:
%x = alloca i32, align 4
store i32 %0, i32* %x, align 4
%1 = load i32, i32* %x, align 4
%mul = mul i32 %1, 2
store i32 %mul, i32* %x, align 4
%2 = load i32, i32* %x, align 4
%lt = icmp slt i32 %2, 100
br i1 %lt, label %if.then, label %if.exit
if.then: ; preds = %entry
%3 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i32 0, i32 0), i32 %3)
br label %expr_block.exit
if.exit: ; preds = %entry
%4 = load i32, i32* %x, align 4
%mul1 = mul i32 %4, 10000
store i32 %mul1, i32* %x, align 4
%5 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i32 0, i32 0), i32 %5)
br label %expr_block.exit
expr_block.exit: ; preds = %if.exit, %if.then
call void (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.2, i32 0, i32 0))
%6 = load i32, i32* %x, align 4
%eq = icmp eq i32 %6, 0
br i1 %eq, label %if.then2, label %if.exit3
if.then2: ; preds = %expr_block.exit
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.3, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.4, i32 0, i32 0))
ret void
if.exit3: ; preds = %expr_block.exit
%7 = load i32, i32* %x, align 4
%eq4 = icmp eq i32 %7, 1
br i1 %eq4, label %if.then5, label %if.exit6
if.then5: ; preds = %if.exit3
call void (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.5, i32 0, i32 0))
ret void
if.exit6: ; preds = %if.exit3
call void (i8*, ...) @printf(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.6, i32 0, i32 0))
ret void
}

View File

@@ -22,15 +22,17 @@ fn void test_line()
// #expect: defer_in_defer.ll
define void @defer_in_defer.test() #0 {
entry:
call void @defer_in_defer.test4()
call void @defer_in_defer.test2()
call void @defer_in_defer.test3()
br label %exit
exit:
call void @defer_in_defer.test1()
ret void
}
define void @defer_in_defer.test_line() #0 {
entry:
call void @defer_in_defer.test1()
br label %exit
ret void
}

View File

@@ -0,0 +1,120 @@
// #target: x64-darwin
module test;
extern fn void printf(char*,...);
fn void test(int x)
{
defer
{
do
{
defer printf("Hello %d\n", x);
x *= 2;
if (x < 100) break;
x *= 10000;
};
}
if (x == 1)
{
printf("1x\n");
return;
}
if (x == 0) return;
}
fn void main()
{
test(123);
test(1);
test(0);
}
/* #expect: test.ll
define void @test.test(i32 %0) #0 {
entry:
%x = alloca i32, align 4
store i32 %0, i32* %x, align 4
%1 = load i32, i32* %x, align 4
%eq = icmp eq i32 %1, 1
br i1 %eq, label %if.then, label %if.exit3
if.then: ; preds = %entry
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0))
%2 = load i32, i32* %x, align 4
%mul = mul i32 %2, 2
store i32 %mul, i32* %x, align 4
%3 = load i32, i32* %x, align 4
%lt = icmp slt i32 %3, 100
br i1 %lt, label %if.then1, label %if.exit
if.then1: ; preds = %if.then
%4 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.1, i32 0, i32 0), i32 %4)
br label %loop.exit
if.exit: ; preds = %if.then
%5 = load i32, i32* %x, align 4
%mul2 = mul i32 %5, 10000
store i32 %mul2, i32* %x, align 4
%6 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.2, i32 0, i32 0), i32 %6)
br label %loop.exit
loop.exit: ; preds = %if.exit, %if.then1
ret void
if.exit3: ; preds = %entry
%7 = load i32, i32* %x, align 4
%eq4 = icmp eq i32 %7, 0
br i1 %eq4, label %if.then5, label %if.exit12
if.then5: ; preds = %if.exit3
%8 = load i32, i32* %x, align 4
%mul6 = mul i32 %8, 2
store i32 %mul6, i32* %x, align 4
%9 = load i32, i32* %x, align 4
%lt7 = icmp slt i32 %9, 100
br i1 %lt7, label %if.then8, label %if.exit9
if.then8: ; preds = %if.then5
%10 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.3, i32 0, i32 0), i32 %10)
br label %loop.exit11
if.exit9: ; preds = %if.then5
%11 = load i32, i32* %x, align 4
%mul10 = mul i32 %11, 10000
store i32 %mul10, i32* %x, align 4
%12 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.4, i32 0, i32 0), i32 %12)
br label %loop.exit11
loop.exit11: ; preds = %if.exit9, %if.then8
ret void
if.exit12: ; preds = %if.exit3
%13 = load i32, i32* %x, align 4
%mul13 = mul i32 %13, 2
store i32 %mul13, i32* %x, align 4
%14 = load i32, i32* %x, align 4
%lt14 = icmp slt i32 %14, 100
br i1 %lt14, label %if.then15, label %if.exit16
if.then15: ; preds = %if.exit12
%15 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.5, i32 0, i32 0), i32 %15)
br label %loop.exit18
if.exit16: ; preds = %if.exit12
%16 = load i32, i32* %x, align 4
%mul17 = mul i32 %16, 10000
store i32 %mul17, i32* %x, align 4
%17 = load i32, i32* %x, align 4
call void (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.6, i32 0, i32 0), i32 %17)
br label %loop.exit18
loop.exit18: ; preds = %if.exit16, %if.then15
ret void
}

View File

@@ -19,7 +19,7 @@ fn void test(int i)
}
}
// #expect: defer_next_switch.ll
/* #expect: defer_next_switch.ll
define void @defer_next_switch.test(i32 %0) #0 {
entry:
@@ -33,7 +33,7 @@ switch.entry: ; preds = %entry
%1 = load i32, i32* %switch, align 4
switch i32 %1, label %switch.exit [
i32 1, label %switch.case
i32 2, label %switch.case2
i32 2, label %switch.case1
]
switch.case: ; preds = %switch.entry
@@ -43,23 +43,17 @@ switch.case: ; preds = %switch.entry
if.then: ; preds = %switch.case
call void @defer_next_switch.test2()
br label %exit
exit: ; preds = %if.then
br label %switch.case2
br label %switch.case1
if.exit: ; preds = %switch.case
call void @defer_next_switch.test1()
call void @defer_next_switch.test2()
br label %exit1
exit1: ; preds = %if.exit
br label %switch.exit
switch.case2: ; preds = %switch.entry, %exit
switch.case1: ; preds = %switch.entry, %if.then
call void @defer_next_switch.test1()
br label %switch.exit
switch.exit: ; preds = %switch.case2, %exit1, %switch.entry
switch.exit: ; preds = %switch.case1, %if.exit, %switch.entry
ret void
}

View File

@@ -42,7 +42,7 @@ entry:
store i32 0, i32* %a, align 4
br label %loop.cond
loop.cond: ; preds = %exit3, %entry
loop.cond: ; preds = %if.exit, %entry
%2 = load i32, i32* %a, align 4
%intbool = icmp ne i32 %2, 0
br i1 %intbool, label %loop.body, label %loop.exit
@@ -55,85 +55,46 @@ if.then: ; preds = %loop.body
%3 = load i32, i32* %a, align 4
%add = add i32 %3, %0
call void @test.test2()
br label %exit
exit: ; preds = %if.then
call void @test.test1()
br label %exit1
exit1: ; preds = %exit
ret i32 %add
if.exit: ; preds = %loop.body
call void @test.test4()
call void @test.test3()
br label %exit2
exit2: ; preds = %if.exit
call void @test.test2()
br label %exit3
exit3: ; preds = %exit2
br label %loop.cond
loop.exit: ; preds = %loop.cond
br label %loop.cond4
br label %loop.cond1
loop.cond4: ; preds = %loop.exit
loop.cond1: ; preds = %loop.exit
%4 = load i32, i32* %a, align 4
%intbool5 = icmp ne i32 %4, 0
br i1 %intbool5, label %loop.body6, label %loop.exit21
%intbool2 = icmp ne i32 %4, 0
br i1 %intbool2, label %loop.body3, label %loop.exit8
loop.body6: ; preds = %loop.cond4
%eq7 = icmp eq i32 %0, 1
br i1 %eq7, label %if.then8, label %if.exit13
loop.body3: ; preds = %loop.cond1
%eq4 = icmp eq i32 %0, 1
br i1 %eq4, label %if.then5, label %if.exit7
if.then8: ; preds = %loop.body6
if.then5: ; preds = %loop.body3
%5 = load i32, i32* %a, align 4
%add9 = add i32 %5, 2
%add6 = add i32 %5, 2
call void @test.test6()
br label %exit10
exit10: ; preds = %if.then8
call void @test.test5()
br label %exit11
exit11: ; preds = %exit10
call void @test.test1()
br label %exit12
ret i32 %add6
exit12: ; preds = %exit11
ret i32 %add9
if.exit13: ; preds = %loop.body6
if.exit7: ; preds = %loop.body3
call void @test.test8()
call void @test.test7()
br label %exit14
exit14: ; preds = %if.exit13
call void @test.test6()
br label %exit15
exit15: ; preds = %exit14
call void @test.test5()
br label %exit16
exit16: ; preds = %exit15
call void @test.test1()
br label %exit17
exit17: ; preds = %exit16
ret i32 4
loop.exit21: ; preds = %loop.cond4
%add22 = add i32 0, %0
loop.exit8: ; preds = %loop.cond1
%add9 = add i32 0, %0
call void @test.test5()
br label %exit23
exit23: ; preds = %loop.exit21
call void @test.test1()
br label %exit24
exit24: ; preds = %exit23
ret i32 %add22
}
ret i32 %add9
}

View File

@@ -4,7 +4,6 @@ fn void test()
defer
{
i = i + 1;
break;
}
return;
}

View File

@@ -0,0 +1,108 @@
// #target: x64-darwin
module test;
extern fn void printf(char*,...);
fn void test(int x)
{
defer
{
for (int i = 0; i < 3; i++)
{
printf("%d\n", x + i);
}
}
if (x == 1)
{
printf("1x\n");
return;
}
if (x == 0) return;
}
fn void main()
{
test(123);
test(1);
test(0);
}
/* #expect: test.ll
define void @test.test(i32 %0) #0 {
entry:
%i = alloca i32, align 4
%i4 = alloca i32, align 4
%i12 = alloca i32, align 4
%eq = icmp eq i32 %0, 1
br i1 %eq, label %if.then, label %if.exit
if.then: ; preds = %entry
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0))
store i32 0, i32* %i, align 4
br label %loop.cond
loop.cond: ; preds = %loop.body, %if.then
%1 = load i32, i32* %i, align 4
%lt = icmp slt i32 %1, 3
br i1 %lt, label %loop.body, label %loop.exit
loop.body: ; preds = %loop.cond
%2 = load i32, i32* %i, align 4
%add = add i32 %0, %2
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i32 0, i32 0), i32 %add)
%3 = load i32, i32* %i, align 4
%add1 = add i32 %3, 1
store i32 %add1, i32* %i, align 4
br label %loop.cond
loop.exit: ; preds = %loop.cond
ret void
if.exit: ; preds = %entry
%eq2 = icmp eq i32 %0, 0
br i1 %eq2, label %if.then3, label %if.exit11
if.then3: ; preds = %if.exit
store i32 0, i32* %i4, align 4
br label %loop.cond5
loop.cond5: ; preds = %loop.body7, %if.then3
%4 = load i32, i32* %i4, align 4
%lt6 = icmp slt i32 %4, 3
br i1 %lt6, label %loop.body7, label %loop.exit10
loop.body7: ; preds = %loop.cond5
%5 = load i32, i32* %i4, align 4
%add8 = add i32 %0, %5
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), i32 %add8)
%6 = load i32, i32* %i4, align 4
%add9 = add i32 %6, 1
store i32 %add9, i32* %i4, align 4
br label %loop.cond5
loop.exit10: ; preds = %loop.cond5
ret void
if.exit11: ; preds = %if.exit
store i32 0, i32* %i12, align 4
br label %loop.cond13
loop.cond13: ; preds = %loop.body15, %if.exit11
%7 = load i32, i32* %i12, align 4
%lt14 = icmp slt i32 %7, 3
br i1 %lt14, label %loop.body15, label %loop.exit18
loop.body15: ; preds = %loop.cond13
%8 = load i32, i32* %i12, align 4
%add16 = add i32 %0, %8
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.3, i32 0, i32 0), i32 %add16)
%9 = load i32, i32* %i12, align 4
%add17 = add i32 %9, 1
store i32 %add17, i32* %i12, align 4
br label %loop.cond13
loop.exit18: ; preds = %loop.cond13
ret void
}

View File

@@ -40,12 +40,9 @@ if.then: ; preds = %entry
%2 = load i32, i32* %x, align 4
%add = add i32 %2, 1
store i32 %add, i32* %x, align 4
br label %exit
exit: ; preds = %if.then
br label %if.exit
if.exit: ; preds = %exit, %entry
if.exit: ; preds = %if.then, %entry
ret void
}

View File

@@ -7,7 +7,7 @@ fn int main()
{
return 1;
}
}
};
return 0;
}
@@ -20,5 +20,5 @@ fn void test1()
{
break BAR; // #error: Cannot find a labelled statement with the name 'BAR'
}
}
};
}

View File

@@ -185,15 +185,5 @@ fn void test24()
int a = b123; // #error: 'int[2][3]' into 'int'
}
fn void test25()
{
const A = void; // #error: Constants cannot be undefined.
}
fn void test26()
{
const int A = void; // #error: Constants cannot be undefined.
}