// #target: macos-x64
module test;
extern fn void printf(char*, ...);

faultdef FOO;

fn int? abc(int x)
{
	printf("Enter abc\n");
	defer catch printf("Abc catch %d\n", x);
	defer try printf("Abc try %d\n", x);
	defer printf("Abc normal %d\n", x);
	return x > 0 ? FOO~ : 0;
}
fn int? bcd(int x)
{
	printf("Enter bcd\n");
	for (int i = 0; i < 10; i++)
	{
		printf("bcd loop\n");
		defer catch printf("Bcd %d catch %d\n", i, x);
		defer try printf("Bcd %d try %d\n", i, x);
		defer printf("Bcd %d normal %d\n", i, x);
		if (i == 1) continue;
		printf("bcd check\n");
		if (i == 2) return x > 0 ? FOO~ : 0;
	}
	return 0;
}

fn int main()
{
	(void)abc(3);
	(void)abc(-1);
	(void)bcd(3);
	(void)bcd(-1);
	return 1;
}


/* #expect: test.ll

define i64 @test.abc(ptr %0, i32 %1) #0 {
entry:
  %reterr = alloca i64, align 8
  call void (ptr, ...) @printf(ptr @.str)
  %gt = icmp sgt i32 %1, 0
  br i1 %gt, label %cond.lhs, label %cond.rhs

cond.lhs:                                         ; preds = %entry
  store i64 ptrtoint (ptr @test.FOO to i64), ptr %reterr, align 8
  br label %err_retblock

cond.rhs:                                         ; preds = %entry
  br label %cond.phi

cond.phi:                                         ; preds = %cond.rhs
  call void (ptr, ...) @printf(ptr @.str.1, i32 %1)
  call void (ptr, ...) @printf(ptr @.str.2, i32 %1)
  store i32 0, ptr %0, align 4
  ret i64 0

err_retblock:                                     ; preds = %cond.lhs
  call void (ptr, ...) @printf(ptr @.str.3, i32 %1)
  call void (ptr, ...) @printf(ptr @.str.4, i32 %1)
  %2 = load i64, ptr %reterr, align 8
  ret i64 %2
}

define i64 @test.bcd(ptr %0, i32 %1) #0 {
entry:
  %i = alloca i32, align 4
  %reterr = alloca i64, align 8
  %reterr4 = alloca i64, align 8
  call void (ptr, ...) @printf(ptr @.str.5)
  store i32 0, ptr %i, align 4
  br label %loop.cond

loop.cond:                                        ; preds = %loop.inc, %entry
  %2 = load i32, ptr %i, align 4
  %lt = icmp slt i32 %2, 10
  br i1 %lt, label %loop.body, label %loop.exit

loop.body:                                        ; preds = %loop.cond
  call void (ptr, ...) @printf(ptr @.str.6)
  %3 = load i32, ptr %i, align 4
  %eq = icmp eq i32 %3, 1
  br i1 %eq, label %if.then, label %if.exit

if.then:                                          ; preds = %loop.body
  %4 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.7, i32 %4, i32 %1)
  %5 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.8, i32 %5, i32 %1)
  br label %loop.inc

if.exit:                                          ; preds = %loop.body
  call void (ptr, ...) @printf(ptr @.str.9)
  %6 = load i32, ptr %i, align 4
  %eq1 = icmp eq i32 %6, 2
  br i1 %eq1, label %if.then2, label %if.exit3

if.then2:                                         ; preds = %if.exit
  %gt = icmp sgt i32 %1, 0
  br i1 %gt, label %cond.lhs, label %cond.rhs

cond.lhs:                                         ; preds = %if.then2
  store i64 ptrtoint (ptr @test.FOO to i64), ptr %reterr, align 8
  br label %err_retblock

cond.rhs:                                         ; preds = %if.then2
  br label %cond.phi

cond.phi:                                         ; preds = %cond.rhs
  %7 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.10, i32 %7, i32 %1)
  %8 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.11, i32 %8, i32 %1)
  store i32 0, ptr %0, align 4
  ret i64 0

err_retblock:                                     ; preds = %cond.lhs
  %9 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.12, i32 %9, i32 %1)
  %10 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.13, i32 %10, i32 %1)
  %11 = load i64, ptr %reterr, align 8
  ret i64 %11

if.exit3:                                         ; preds = %if.exit
  %12 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.14, i32 %12, i32 %1)
  %13 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.15, i32 %13, i32 %1)
  br label %loop.inc

loop.inc:                                         ; preds = %if.exit3, %if.then
  %14 = load i32, ptr %i, align 4
  %add = add i32 %14, 1
  store i32 %add, ptr %i, align 4
  br label %loop.cond

loop.exit:                                        ; preds = %loop.cond
  store i32 0, ptr %0, align 4
  ret i64 0
}
