// #target: macos-x64
module test;

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

fn void main()
{
    float[3] foo = { 2, 4.5, 8 };
    float[<3>] foo2 = { 2, 4.5, 8 };
    foreach (a : foo)
    {
        printf("Value: %f\n", a);
    }
    foreach (float* &a : foo)
    {
        *a *= 2;
        printf("Value: %f\n", *a);
    }
    foreach (void* &a : foo)
    {
        printf("Value: %f\n", *((float*)(a)));
    }
    foreach (i, a : foo)
    {
        printf("Value[%d]: %f\n", i, a);
    }
    foreach (char i, double a : foo)
    {
        printf("Value2[%d]: %f\n", i, a);
    }
    foreach (double a : foo)
    {
        printf("Value3: %f\n", a);
    }

    foreach (a : foo2)
    {
        printf("Value: %f\n", a);
    }
    foreach (float* &a : foo2)
    {
        *a *= 2;
        printf("Value: %f\n", *a);
    }
    foreach (i, a : foo2)
    {
        printf("Value[%d]: %f\n", i, a);
    }
    foreach (char i, double a : foo2)
    {
        printf("Value2[%d]: %f\n", i, a);
    }
    foreach (double a : foo2)
    {
        printf("Value3: %f\n", a);
    }
}

/* #expect: test.ll

entry:
  %foo = alloca [3 x float], align 4
  %foo2 = alloca <3 x float>, align 16
  %.anon = alloca i64, align 8
  %a = alloca float, align 4
  %.anon1 = alloca i64, align 8
  %a5 = alloca ptr, align 8
  %.anon10 = alloca i64, align 8
  %a14 = alloca ptr, align 8
  %.anon19 = alloca i64, align 8
  %i = alloca i64, align 8
  %a23 = alloca float, align 4
  %.anon28 = alloca i64, align 8
  %i32 = alloca i8, align 1
  %a33 = alloca double, align 8
  %.anon38 = alloca i64, align 8
  %a42 = alloca double, align 8
  %.anon47 = alloca i64, align 8
  %a51 = alloca float, align 4
  %.anon55 = alloca i64, align 8
  %a59 = alloca ptr, align 8
  %.anon65 = alloca i64, align 8
  %i69 = alloca i64, align 8
  %a70 = alloca float, align 4
  %.anon75 = alloca i64, align 8
  %i79 = alloca i8, align 1
  %a81 = alloca double, align 8
  %.anon87 = alloca i64, align 8
  %a91 = alloca double, align 8
  call void @llvm.memcpy.p0.p0.i32(ptr align 4 %foo, ptr align 4 @.__const, i32 12, i1 false)
  store <4 x float> <float 2.000000e+00, float 4.500000e+00, float 8.000000e+00, float undef>, ptr %foo2, align 16
  store i64 0, ptr %.anon, align 8
  br label %loop.cond

loop.cond:                                        ; preds = %loop.body, %entry
  %0 = load i64, ptr %.anon, align 8
  %gt = icmp ugt i64 3, %0
  br i1 %gt, label %loop.body, label %loop.exit

loop.body:                                        ; preds = %loop.cond
  %1 = load i64, ptr %.anon, align 8
  %ptroffset = getelementptr inbounds [4 x i8], ptr %foo, i64 %1
  %2 = load float, ptr %ptroffset, align 4
  store float %2, ptr %a, align 4
  %3 = load float, ptr %a, align 4
  %fpfpext = fpext float %3 to double
  call void (ptr, ...) @printf(ptr @.str, double %fpfpext)
  %4 = load i64, ptr %.anon, align 8
  %addnuw = add nuw i64 %4, 1
  store i64 %addnuw, ptr %.anon, align 8
  br label %loop.cond

loop.exit:                                        ; preds = %loop.cond
  store i64 0, ptr %.anon1, align 8
  br label %loop.cond2

loop.cond2:                                       ; preds = %loop.body4, %loop.exit
  %5 = load i64, ptr %.anon1, align 8
  %gt3 = icmp ugt i64 3, %5
  br i1 %gt3, label %loop.body4, label %loop.exit9

loop.body4:                                       ; preds = %loop.cond2
  %6 = load i64, ptr %.anon1, align 8
  %ptroffset6 = getelementptr inbounds [4 x i8], ptr %foo, i64 %6
  store ptr %ptroffset6, ptr %a5, align 8
  %7 = load ptr, ptr %a5, align 8
  %8 = load float, ptr %7, align 4
  %fmul = fmul float %8, 2.000000e+00
  store float %fmul, ptr %7, align 4
  %9 = load ptr, ptr %a5, align 8
  %10 = load float, ptr %9, align 4
  %fpfpext7 = fpext float %10 to double
  call void (ptr, ...) @printf(ptr @.str.1, double %fpfpext7)
  %11 = load i64, ptr %.anon1, align 8
  %addnuw8 = add nuw i64 %11, 1
  store i64 %addnuw8, ptr %.anon1, align 8
  br label %loop.cond2

loop.exit9:                                       ; preds = %loop.cond2
  store i64 0, ptr %.anon10, align 8
  br label %loop.cond11

loop.cond11:                                      ; preds = %loop.body13, %loop.exit9
  %12 = load i64, ptr %.anon10, align 8
  %gt12 = icmp ugt i64 3, %12
  br i1 %gt12, label %loop.body13, label %loop.exit18

loop.body13:                                      ; preds = %loop.cond11
  %13 = load i64, ptr %.anon10, align 8
  %ptroffset15 = getelementptr inbounds [4 x i8], ptr %foo, i64 %13
  store ptr %ptroffset15, ptr %a14, align 8
  %14 = load ptr, ptr %a14, align 8
  %15 = load float, ptr %14, align 4
  %fpfpext16 = fpext float %15 to double
  call void (ptr, ...) @printf(ptr @.str.2, double %fpfpext16)
  %16 = load i64, ptr %.anon10, align 8
  %addnuw17 = add nuw i64 %16, 1
  store i64 %addnuw17, ptr %.anon10, align 8
  br label %loop.cond11

loop.exit18:                                      ; preds = %loop.cond11
  store i64 0, ptr %.anon19, align 8
  br label %loop.cond20

loop.cond20:                                      ; preds = %loop.body22, %loop.exit18
  %17 = load i64, ptr %.anon19, align 8
  %gt21 = icmp ugt i64 3, %17
  br i1 %gt21, label %loop.body22, label %loop.exit27

loop.body22:                                      ; preds = %loop.cond20
  %18 = load i64, ptr %.anon19, align 8
  store i64 %18, ptr %i, align 8
  %19 = load i64, ptr %.anon19, align 8
  %ptroffset24 = getelementptr inbounds [4 x i8], ptr %foo, i64 %19
  %20 = load float, ptr %ptroffset24, align 4
  store float %20, ptr %a23, align 4
  %21 = load float, ptr %a23, align 4
  %fpfpext25 = fpext float %21 to double
  %22 = load i64, ptr %i, align 8
  call void (ptr, ...) @printf(ptr @.str.3, i64 %22, double %fpfpext25)
  %23 = load i64, ptr %.anon19, align 8
  %addnuw26 = add nuw i64 %23, 1
  store i64 %addnuw26, ptr %.anon19, align 8
  br label %loop.cond20

loop.exit27:                                      ; preds = %loop.cond20
  store i64 0, ptr %.anon28, align 8
  br label %loop.cond29

loop.cond29:                                      ; preds = %loop.body31, %loop.exit27
  %24 = load i64, ptr %.anon28, align 8
  %gt30 = icmp ugt i64 3, %24
  br i1 %gt30, label %loop.body31, label %loop.exit37

loop.body31:                                      ; preds = %loop.cond29
  %25 = load i64, ptr %.anon28, align 8
  %trunc = trunc i64 %25 to i8
  store i8 %trunc, ptr %i32, align 1
  %26 = load i64, ptr %.anon28, align 8
  %ptroffset34 = getelementptr inbounds [4 x i8], ptr %foo, i64 %26
  %27 = load float, ptr %ptroffset34, align 4
  %fpfpext35 = fpext float %27 to double
  store double %fpfpext35, ptr %a33, align 8
  %28 = load i8, ptr %i32, align 1
  %zext = zext i8 %28 to i32
  %29 = load double, ptr %a33, align 8
  call void (ptr, ...) @printf(ptr @.str.4, i32 %zext, double %29)
  %30 = load i64, ptr %.anon28, align 8
  %addnuw36 = add nuw i64 %30, 1
  store i64 %addnuw36, ptr %.anon28, align 8
  br label %loop.cond29

loop.exit37:                                      ; preds = %loop.cond29
  store i64 0, ptr %.anon38, align 8
  br label %loop.cond39

loop.cond39:                                      ; preds = %loop.body41, %loop.exit37
  %31 = load i64, ptr %.anon38, align 8
  %gt40 = icmp ugt i64 3, %31
  br i1 %gt40, label %loop.body41, label %loop.exit46

loop.body41:                                      ; preds = %loop.cond39
  %32 = load i64, ptr %.anon38, align 8
  %ptroffset43 = getelementptr inbounds [4 x i8], ptr %foo, i64 %32
  %33 = load float, ptr %ptroffset43, align 4
  %fpfpext44 = fpext float %33 to double
  store double %fpfpext44, ptr %a42, align 8
  %34 = load double, ptr %a42, align 8
  call void (ptr, ...) @printf(ptr @.str.5, double %34)
  %35 = load i64, ptr %.anon38, align 8
  %addnuw45 = add nuw i64 %35, 1
  store i64 %addnuw45, ptr %.anon38, align 8
  br label %loop.cond39

loop.exit46:                                      ; preds = %loop.cond39
  store i64 0, ptr %.anon47, align 8
  br label %loop.cond48

loop.cond48:                                      ; preds = %loop.body50, %loop.exit46
  %36 = load i64, ptr %.anon47, align 8
  %gt49 = icmp ugt i64 3, %36
  br i1 %gt49, label %loop.body50, label %loop.exit54

loop.body50:                                      ; preds = %loop.cond48
  %37 = load <4 x float>, ptr %foo2, align 16
  %extractvec = shufflevector <4 x float> %37, <4 x float> poison, <3 x i32> <i32 0, i32 1, i32 2>
  %38 = load i64, ptr %.anon47, align 8
  %39 = extractelement <3 x float> %extractvec, i64 %38
  store float %39, ptr %a51, align 4
  %40 = load float, ptr %a51, align 4
  %fpfpext52 = fpext float %40 to double
  call void (ptr, ...) @printf(ptr @.str.6, double %fpfpext52)
  %41 = load i64, ptr %.anon47, align 8
  %addnuw53 = add nuw i64 %41, 1
  store i64 %addnuw53, ptr %.anon47, align 8
  br label %loop.cond48

loop.exit54:                                      ; preds = %loop.cond48
  store i64 0, ptr %.anon55, align 8
  br label %loop.cond56

loop.cond56:                                      ; preds = %loop.body58, %loop.exit54
  %42 = load i64, ptr %.anon55, align 8
  %gt57 = icmp ugt i64 3, %42
  br i1 %gt57, label %loop.body58, label %loop.exit64

loop.body58:                                      ; preds = %loop.cond56
  %43 = load i64, ptr %.anon55, align 8
  %ptroffset60 = getelementptr inbounds [4 x i8], ptr %foo2, i64 %43
  store ptr %ptroffset60, ptr %a59, align 8
  %44 = load ptr, ptr %a59, align 8
  %45 = load float, ptr %44, align 4
  %fmul61 = fmul float %45, 2.000000e+00
  store float %fmul61, ptr %44, align 4
  %46 = load ptr, ptr %a59, align 8
  %47 = load float, ptr %46, align 4
  %fpfpext62 = fpext float %47 to double
  call void (ptr, ...) @printf(ptr @.str.7, double %fpfpext62)
  %48 = load i64, ptr %.anon55, align 8
  %addnuw63 = add nuw i64 %48, 1
  store i64 %addnuw63, ptr %.anon55, align 8
  br label %loop.cond56

loop.exit64:                                      ; preds = %loop.cond56
  store i64 0, ptr %.anon65, align 8
  br label %loop.cond66

loop.cond66:                                      ; preds = %loop.body68, %loop.exit64
  %49 = load i64, ptr %.anon65, align 8
  %gt67 = icmp ugt i64 3, %49
  br i1 %gt67, label %loop.body68, label %loop.exit74

loop.body68:                                      ; preds = %loop.cond66
  %50 = load i64, ptr %.anon65, align 8
  store i64 %50, ptr %i69, align 8
  %51 = load <4 x float>, ptr %foo2, align 16
  %extractvec71 = shufflevector <4 x float> %51, <4 x float> poison, <3 x i32> <i32 0, i32 1, i32 2>
  %52 = load i64, ptr %.anon65, align 8
  %53 = extractelement <3 x float> %extractvec71, i64 %52
  store float %53, ptr %a70, align 4
  %54 = load float, ptr %a70, align 4
  %fpfpext72 = fpext float %54 to double
  %55 = load i64, ptr %i69, align 8
  call void (ptr, ...) @printf(ptr @.str.8, i64 %55, double %fpfpext72)
  %56 = load i64, ptr %.anon65, align 8
  %addnuw73 = add nuw i64 %56, 1
  store i64 %addnuw73, ptr %.anon65, align 8
  br label %loop.cond66

loop.exit74:                                      ; preds = %loop.cond66
  store i64 0, ptr %.anon75, align 8
  br label %loop.cond76

loop.cond76:                                      ; preds = %loop.body78, %loop.exit74
  %57 = load i64, ptr %.anon75, align 8
  %gt77 = icmp ugt i64 3, %57
  br i1 %gt77, label %loop.body78, label %loop.exit86

loop.body78:                                      ; preds = %loop.cond76
  %58 = load i64, ptr %.anon75, align 8
  %trunc80 = trunc i64 %58 to i8
  store i8 %trunc80, ptr %i79, align 1
  %59 = load <4 x float>, ptr %foo2, align 16
  %extractvec82 = shufflevector <4 x float> %59, <4 x float> poison, <3 x i32> <i32 0, i32 1, i32 2>
  %60 = load i64, ptr %.anon75, align 8
  %61 = extractelement <3 x float> %extractvec82, i64 %60
  %fpfpext83 = fpext float %61 to double
  store double %fpfpext83, ptr %a81, align 8
  %62 = load i8, ptr %i79, align 1
  %zext84 = zext i8 %62 to i32
  %63 = load double, ptr %a81, align 8
  call void (ptr, ...) @printf(ptr @.str.9, i32 %zext84, double %63)
  %64 = load i64, ptr %.anon75, align 8
  %addnuw85 = add nuw i64 %64, 1
  store i64 %addnuw85, ptr %.anon75, align 8
  br label %loop.cond76

loop.exit86:                                      ; preds = %loop.cond76
  store i64 0, ptr %.anon87, align 8
  br label %loop.cond88

loop.cond88:                                      ; preds = %loop.body90, %loop.exit86
  %65 = load i64, ptr %.anon87, align 8
  %gt89 = icmp ugt i64 3, %65
  br i1 %gt89, label %loop.body90, label %loop.exit95

loop.body90:                                      ; preds = %loop.cond88
  %66 = load <4 x float>, ptr %foo2, align 16
  %extractvec92 = shufflevector <4 x float> %66, <4 x float> poison, <3 x i32> <i32 0, i32 1, i32 2>
  %67 = load i64, ptr %.anon87, align 8
  %68 = extractelement <3 x float> %extractvec92, i64 %67
  %fpfpext93 = fpext float %68 to double
  store double %fpfpext93, ptr %a91, align 8
  %69 = load double, ptr %a91, align 8
  call void (ptr, ...) @printf(ptr @.str.10, double %69)
  %70 = load i64, ptr %.anon87, align 8
  %addnuw94 = add nuw i64 %70, 1
  store i64 %addnuw94, ptr %.anon87, align 8
  br label %loop.cond88

loop.exit95:                                      ; preds = %loop.cond88
  ret void
}
