// #target: macos-x64
import libc;

fn void testf()
{
    float[<4>] y = { 1, 2, 3, 4 };
    float[<4>] z = { 2, 2, 2, -100 };
    y += z;
    libc::printf("Add %f %f %f %f\n", y[0], y[1], y[2], y[3]);
    y++;
    libc::printf("Inc %f %f %f %f\n", y[0], y[1], y[2], y[3]);
    ++y;
    libc::printf("Inc %f %f %f %f\n", y[0], y[1], y[2], y[3]);
    y--;
    libc::printf("Dec %f %f %f %f\n", y[0], y[1], y[2], y[3]);
}

fn void testi()
{
    int[<4>] y = { 1, 2, 3, 4 };
    int[<4>] z = { 2, 2, 2, -100 };
    y += z;
    libc::printf("Add %d %d %d %d\n", y[0], y[1], y[2], y[3]);
    y++;
    libc::printf("Inc %d %d %d %d\n", y[0], y[1], y[2], y[3]);
    ++y;
    libc::printf("Inc %d %d %d %d\n", y[0], y[1], y[2], y[3]);
    int[<4>]w = y--;
    libc::printf("Dec %d %d %d %d\n", y[0], y[1], y[2], y[3]);
    libc::printf("Original %d %d %d %d\n", w[0], w[1], w[2], w[3]);
}

fn void main()
{
    testf();
    testi();
}

/* #expect: vector_incdec.ll

define void @vector_incdec.testf() #0 {
entry:
  %y = alloca <4 x float>, align 16
  %z = alloca <4 x float>, align 16
  store <4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>, ptr %y, align 16
  store <4 x float> <float 2.000000e+00, float 2.000000e+00, float 2.000000e+00, float -1.000000e+02>, ptr %z, align 16
  %0 = load <4 x float>, ptr %y, align 16
  %1 = load <4 x float>, ptr %z, align 16
  %fadd = fadd <4 x float> %0, %1
  store <4 x float> %fadd, ptr %y, align 16
  %2 = load <4 x float>, ptr %y, align 16
  %3 = extractelement <4 x float> %2, i64 0
  %fpfpext = fpext float %3 to double
  %4 = load <4 x float>, ptr %y, align 16
  %5 = extractelement <4 x float> %4, i64 1
  %fpfpext1 = fpext float %5 to double
  %6 = load <4 x float>, ptr %y, align 16
  %7 = extractelement <4 x float> %6, i64 2
  %fpfpext2 = fpext float %7 to double
  %8 = load <4 x float>, ptr %y, align 16
  %9 = extractelement <4 x float> %8, i64 3
  %fpfpext3 = fpext float %9 to double
  %10 = call i32 (ptr, ...) @printf(ptr @.str, double %fpfpext, double %fpfpext1, double %fpfpext2, double %fpfpext3)
  %11 = load <4 x float>, ptr %y, align 16
  %fincdec = fadd <4 x float> %11,
  store <4 x float> %fincdec, ptr %y, align 16
  %12 = load <4 x float>, ptr %y, align 16
  %13 = extractelement <4 x float> %12, i64 0
  %fpfpext4 = fpext float %13 to double
  %14 = load <4 x float>, ptr %y, align 16
  %15 = extractelement <4 x float> %14, i64 1
  %fpfpext5 = fpext float %15 to double
  %16 = load <4 x float>, ptr %y, align 16
  %17 = extractelement <4 x float> %16, i64 2
  %fpfpext6 = fpext float %17 to double
  %18 = load <4 x float>, ptr %y, align 16
  %19 = extractelement <4 x float> %18, i64 3
  %fpfpext7 = fpext float %19 to double
  %20 = call i32 (ptr, ...) @printf(ptr @.str.1, double %fpfpext4, double %fpfpext5, double %fpfpext6, double %fpfpext7)
  %21 = load <4 x float>, ptr %y, align 16
  %fincdec8 = fadd <4 x float> %21,
  store <4 x float> %fincdec8, ptr %y, align 16
  %22 = load <4 x float>, ptr %y, align 16
  %23 = extractelement <4 x float> %22, i64 0
  %fpfpext9 = fpext float %23 to double
  %24 = load <4 x float>, ptr %y, align 16
  %25 = extractelement <4 x float> %24, i64 1
  %fpfpext10 = fpext float %25 to double
  %26 = load <4 x float>, ptr %y, align 16
  %27 = extractelement <4 x float> %26, i64 2
  %fpfpext11 = fpext float %27 to double
  %28 = load <4 x float>, ptr %y, align 16
  %29 = extractelement <4 x float> %28, i64 3
  %fpfpext12 = fpext float %29 to double
  %30 = call i32 (ptr, ...) @printf(ptr @.str.2, double %fpfpext9, double %fpfpext10, double %fpfpext11, double %fpfpext12)
  %31 = load <4 x float>, ptr %y, align 16
  %fincdec13 = fadd <4 x float> %31,
  store <4 x float> %fincdec13, ptr %y, align 16
  %32 = load <4 x float>, ptr %y, align 16
  %33 = extractelement <4 x float> %32, i64 0
  %fpfpext14 = fpext float %33 to double
  %34 = load <4 x float>, ptr %y, align 16
  %35 = extractelement <4 x float> %34, i64 1
  %fpfpext15 = fpext float %35 to double
  %36 = load <4 x float>, ptr %y, align 16
  %37 = extractelement <4 x float> %36, i64 2
  %fpfpext16 = fpext float %37 to double
  %38 = load <4 x float>, ptr %y, align 16
  %39 = extractelement <4 x float> %38, i64 3
  %fpfpext17 = fpext float %39 to double
  %40 = call i32 (ptr, ...) @printf(ptr @.str.3, double %fpfpext14, double %fpfpext15, double %fpfpext16, double %fpfpext17)
  ret void
}

define void @vector_incdec.testi() #0 {
entry:
  %y = alloca <4 x i32>, align 16
  %z = alloca <4 x i32>, align 16
  %w = alloca <4 x i32>, align 16
  store <4 x i32> <i32 1, i32 2, i32 3, i32 4>, ptr %y, align 16
  store <4 x i32> <i32 2, i32 2, i32 2, i32 -100>, ptr %z, align 16
  %0 = load <4 x i32>, ptr %y, align 16
  %1 = load <4 x i32>, ptr %z, align 16
  %add = add <4 x i32> %0, %1
  store <4 x i32> %add, ptr %y, align 16
  %2 = load <4 x i32>, ptr %y, align 16
  %3 = extractelement <4 x i32> %2, i64 0
  %4 = load <4 x i32>, ptr %y, align 16
  %5 = extractelement <4 x i32> %4, i64 1
  %6 = load <4 x i32>, ptr %y, align 16
  %7 = extractelement <4 x i32> %6, i64 2
  %8 = load <4 x i32>, ptr %y, align 16
  %9 = extractelement <4 x i32> %8, i64 3
  %10 = call i32 (ptr, ...) @printf(ptr @.str.4, i32 %3, i32 %5, i32 %7, i32 %9)
  %11 = load <4 x i32>, ptr %y, align 16
  %add1 = add <4 x i32> %11,
  store <4 x i32> %add1, ptr %y, align 16
  %12 = load <4 x i32>, ptr %y, align 16
  %13 = extractelement <4 x i32> %12, i64 0
  %14 = load <4 x i32>, ptr %y, align 16
  %15 = extractelement <4 x i32> %14, i64 1
  %16 = load <4 x i32>, ptr %y, align 16
  %17 = extractelement <4 x i32> %16, i64 2
  %18 = load <4 x i32>, ptr %y, align 16
  %19 = extractelement <4 x i32> %18, i64 3
  %20 = call i32 (ptr, ...) @printf(ptr @.str.5, i32 %13, i32 %15, i32 %17, i32 %19)
  %21 = load <4 x i32>, ptr %y, align 16
  %add2 = add <4 x i32> %21,
  store <4 x i32> %add2, ptr %y, align 16
  %22 = load <4 x i32>, ptr %y, align 16
  %23 = extractelement <4 x i32> %22, i64 0
  %24 = load <4 x i32>, ptr %y, align 16
  %25 = extractelement <4 x i32> %24, i64 1
  %26 = load <4 x i32>, ptr %y, align 16
  %27 = extractelement <4 x i32> %26, i64 2
  %28 = load <4 x i32>, ptr %y, align 16
  %29 = extractelement <4 x i32> %28, i64 3
  %30 = call i32 (ptr, ...) @printf(ptr @.str.6, i32 %23, i32 %25, i32 %27, i32 %29)
  %31 = load <4 x i32>, ptr %y, align 16
  %sub = sub <4 x i32> %31,
  store <4 x i32> %sub, ptr %y, align 16
  store <4 x i32> %31, ptr %w, align 16
  %32 = load <4 x i32>, ptr %y, align 16
  %33 = extractelement <4 x i32> %32, i64 0
  %34 = load <4 x i32>, ptr %y, align 16
  %35 = extractelement <4 x i32> %34, i64 1
  %36 = load <4 x i32>, ptr %y, align 16
  %37 = extractelement <4 x i32> %36, i64 2
  %38 = load <4 x i32>, ptr %y, align 16
  %39 = extractelement <4 x i32> %38, i64 3
  %40 = call i32 (ptr, ...) @printf(ptr @.str.7, i32 %33, i32 %35, i32 %37, i32 %39)
  %41 = load <4 x i32>, ptr %w, align 16
  %42 = extractelement <4 x i32> %41, i64 0
  %43 = load <4 x i32>, ptr %w, align 16
  %44 = extractelement <4 x i32> %43, i64 1
  %45 = load <4 x i32>, ptr %w, align 16
  %46 = extractelement <4 x i32> %45, i64 2
  %47 = load <4 x i32>, ptr %w, align 16
  %48 = extractelement <4 x i32> %47, i64 3
  %49 = call i32 (ptr, ...) @printf(ptr @.str.8, i32 %42, i32 %44, i32 %46, i32 %48)
  ret void
}

define void @vector_incdec.main() #0 {
entry:
  call void @vector_incdec.testf()
  call void @vector_incdec.testi()
  ret void
}
