;@llvm.global_ctors = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @_init_z }]
@abc = appending global [1 x { i32, void ()* }] [ { i32, void ()* } { i32 65535, void ()* @_init_z }]

declare i32 @puts(i8*)
@initlist = appending global [0 x {i32, void()*}] []

@msg2 = internal constant [6 x i8] c"main!\00"
@msg4 = internal constant [3 x i8] c"z!\00"

define void @_init_z() {
  %m = getelementptr [3 x i8]* @msg4, i32 0, i32 0
  call i32 @puts(i8* %m)
  ret void
}

define i32 @main() {
begin:
  %abcnext = getelementptr [1 x {i32, void()*}]* @abc, i32 1
  %abcnexti = ptrtoint [1 x {i32, void()*}]* %abcnext to i32
  %abci = ptrtoint [1 x {i32, void()*}]* @abc to i32
  %abcsize = sub i32 %abcnexti, %abci

  %abc1 = getelementptr [1 x {i32, void()*}]* @abc, i32 0, i32 1
  %abc1i = ptrtoint {i32, void()*}* %abc1 to i32
  %abc0 = getelementptr [1 x {i32, void()*}]* @abc, i32 0, i32 0
  %abc0i = ptrtoint {i32, void()*}* %abc0 to i32
  %abc0size = sub i32 %abc1i, %abc0i

  %len = udiv i32 %abcsize, %abc0size

  br label %cond

cond:
  %counter = phi i32 [0, %begin], [%x, %loop]
  %lt = icmp ult i32 %counter, %len
  br i1 %lt, label %loop, label %done

loop:
  %m = getelementptr [1 x {i32, void()*}]* @abc, i32 0, i32 %counter, i32 1
  %f = load void()** %m
  call void %f()

  %x = add i32 %counter, 1
  br label %cond

done:
  ret i32 0
}
