// #target: macos-x64

module foo;
fn int test()
{
    static int x = 0;
    return 1 + x++;
}

extern fn void printf(char*, ...);

fn void main()
{
    int i = 10;
    do
    {
        printf("%d\n", test());
        if (i > 100) break;
    } while (i-- > 0);
    i = 1;
    do
    {
        printf("%d, %d\n", i, test());
        if (i % 3 == 0) break;
    } while (i++ < 100);
}

/* #expect: foo.ll
source_filename = "foo"
target datalayout = "e-m:o-p270:32:32-p271:32
target triple = "x86_64-apple

@test.x = internal unnamed_addr global i32 0, align 4
@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1
@.str.1 = private unnamed_addr constant [8 x i8] c"%d, %d\0A\00", align 1


define i32 @foo.test() #0 {
entry:
  %0 = load i32, ptr @test.x, align 4
  %add = add i32 %0, 1
  store i32 %add, ptr @test.x, align 4
  %add1 = add i32 1, %0
  ret i32 %add1
}


declare void @printf(ptr, ...) #0


define void @foo.main() #0 {
entry:
  %i = alloca i32, align 4
  store i32 10, ptr %i, align 4
  br label %loop.body

loop.body:                                        ; preds = %loop.cond, %entry
  %0 = call i32 @foo.test()
  call void (ptr, ...) @printf(ptr @.str, i32 %0)
  %1 = load i32, ptr %i, align 4
  %gt = icmp sgt i32 %1, 100
  br i1 %gt, label %if.then, label %if.exit

if.then:                                          ; preds = %loop.body
  br label %loop.exit

if.exit:                                          ; preds = %loop.body
  br label %loop.cond

loop.cond:                                        ; preds = %if.exit
  %2 = load i32, ptr %i, align 4
  %sub = sub i32 %2, 1
  store i32 %sub, ptr %i, align 4
  %gt1 = icmp sgt i32 %2, 0
  br i1 %gt1, label %loop.body, label %loop.exit

loop.exit:                                        ; preds = %loop.cond, %if.then
  store i32 1, ptr %i, align 4
  br label %loop.body2

loop.body2:                                       ; preds = %loop.cond5, %loop.exit
  %3 = call i32 @foo.test()
  %4 = load i32, ptr %i, align 4
  call void (ptr, ...) @printf(ptr @.str.1, i32 %4, i32 %3)
  %5 = load i32, ptr %i, align 4
  %smod = srem i32 %5, 3
  %eq = icmp eq i32 %smod, 0
  br i1 %eq, label %if.then3, label %if.exit4

if.then3:                                         ; preds = %loop.body2
  br label %loop.exit6

if.exit4:                                         ; preds = %loop.body2
  br label %loop.cond5

loop.cond5:                                       ; preds = %if.exit4
  %6 = load i32, ptr %i, align 4
  %add = add i32 %6, 1
  store i32 %add, ptr %i, align 4
  %lt = icmp slt i32 %6, 100
  br i1 %lt, label %loop.body2, label %loop.exit6

loop.exit6:                                       ; preds = %loop.cond5, %if.then3
  ret void
}


define i32 @main(i32 %0, ptr %1) #0 {
entry:
  call void @foo.main()
  ret i32 0
}
