#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ bar(int *);
int /*<<< orphan*/ foo(int, int *);
void vla_func(int n) {
  int vla[n];
  typedef int typedef_vla[n];
  typedef_vla td_vla;
  int i;
  for (i = 0; i < n; i++) {
    vla[i] = 2 + i;
    td_vla[i] = 4 + i;
  }
  foo(n, vla);
  bar(vla);
  return;
}


x86 assembly (clang, -O0):
<vla_func>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%eax
mov    %rsp,%rcx
mov    %rcx,-0x10(%rbp)
lea    0xf(,%rax,4),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x38(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x18(%rbp)
mov    -0x4(%rbp),%eax
lea    0xf(,%rax,4),%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x30(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11b5 <vla_func+0x95>
mov    -0x30(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    -0x24(%rbp),%esi
add    $0x2,%esi
movslq -0x24(%rbp),%rdx
mov    %esi,(%rcx,%rdx,4)
mov    -0x24(%rbp),%edx
add    $0x4,%edx
movslq -0x24(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1179 <vla_func+0x59>
mov    -0x38(%rbp),%rsi
mov    -0x4(%rbp),%edi
call   1040 <foo@plt>
mov    -0x38(%rbp),%rdi
call   1030 <bar@plt>
mov    -0x10(%rbp),%rax
mov    %rax,%rsp
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<vla_func>:
push   %rbp
mov    %rsp,%rbp
push   %rbx
push   %rax
mov    %edi,%eax
mov    %rsp,%rbx
lea    0xf(,%rax,4),%rcx
and    $0xfffffffffffffff0,%rcx
sub    %rcx,%rbx
mov    %rbx,%rsp
test   %edi,%edi
jle    12cf <vla_func+0x1af>
cmp    $0x8,%edi
jae    1151 <vla_func+0x31>
xor    %ecx,%ecx
jmp    12c0 <vla_func+0x1a0>
mov    %eax,%ecx
and    $0xfffffff8,%ecx
lea    -0x8(%rcx),%rdx
mov    %rdx,%rsi
shr    $0x3,%rsi
add    $0x1,%rsi
mov    %esi,%r8d
and    $0x3,%r8d
cmp    $0x18,%rdx
jae    1181 <vla_func+0x61>
movdqa 0xe86(%rip),%xmm0
xor    %edx,%edx
jmp    1265 <vla_func+0x145>
and    $0xfffffffffffffffc,%rsi
movdqa 0xe73(%rip),%xmm0
xor    %edx,%edx
movdqa 0xe78(%rip),%xmm8
movdqa 0xe7f(%rip),%xmm9
movdqa 0xe86(%rip),%xmm10
movdqa 0xe8d(%rip),%xmm11
movdqa 0xe95(%rip),%xmm5
movdqa 0xe9d(%rip),%xmm6
movdqa 0xea5(%rip),%xmm7
movdqa 0xead(%rip),%xmm1
movdqa 0xeb5(%rip),%xmm2
nopl   0x0(%rax,%rax,1)
movdqa %xmm0,%xmm3
paddd  %xmm8,%xmm3
movdqa %xmm0,%xmm4
paddd  %xmm9,%xmm4
movdqa %xmm3,(%rbx,%rdx,4)
movdqa %xmm4,0x10(%rbx,%rdx,4)
movdqa %xmm0,%xmm3
paddd  %xmm10,%xmm3
movdqa %xmm0,%xmm4
paddd  %xmm11,%xmm4
movdqa %xmm3,0x20(%rbx,%rdx,4)
movdqa %xmm4,0x30(%rbx,%rdx,4)
movdqa %xmm0,%xmm3
paddd  %xmm5,%xmm3
movdqa %xmm0,%xmm4
paddd  %xmm6,%xmm4
movdqa %xmm3,0x40(%rbx,%rdx,4)
movdqa %xmm4,0x50(%rbx,%rdx,4)
movdqa %xmm0,%xmm3
paddd  %xmm7,%xmm3
movdqa %xmm0,%xmm4
paddd  %xmm1,%xmm4
movdqa %xmm3,0x60(%rbx,%rdx,4)
movdqa %xmm4,0x70(%rbx,%rdx,4)
add    $0x20,%rdx
paddd  %xmm2,%xmm0
add    $0xfffffffffffffffc,%rsi
jne    11e0 <vla_func+0xc0>
test   %r8,%r8
je     12b8 <vla_func+0x198>
lea    (%rbx,%rdx,4),%rdx
add    $0x10,%rdx
shl    $0x5,%r8
xor    %esi,%esi
movdqa 0xd90(%rip),%xmm1
movdqa 0xd98(%rip),%xmm2
movdqa 0xe10(%rip),%xmm3
movdqa %xmm0,%xmm4
paddd  %xmm1,%xmm4
movdqa %xmm0,%xmm5
paddd  %xmm2,%xmm5
movdqa %xmm4,-0x10(%rdx,%rsi,1)
movdqa %xmm5,(%rdx,%rsi,1)
paddd  %xmm3,%xmm0
add    $0x20,%rsi
cmp    %rsi,%r8
jne    1290 <vla_func+0x170>
cmp    %rax,%rcx
je     12cf <vla_func+0x1af>
nopl   (%rax)
lea    0x2(%rcx),%edx
mov    %edx,(%rbx,%rcx,4)
add    $0x1,%rcx
cmp    %rcx,%rax
jne    12c0 <vla_func+0x1a0>
mov    %rbx,%rsi
call   1040 <foo@plt>
mov    %rbx,%rdi
call   1030 <bar@plt>
lea    -0x8(%rbp),%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
define void @vla_func(i32 %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i64
%5 = alloca i64
%6 = alloca i32
store i32 %0, i32* %2
%7 = load i32, i32* %2
%8 = zext i32 %7 to i64
%9 = call i8* @llvm.stacksave()
store i8* %9, i8** %3
%10 = alloca i32, i64 %8
store i64 %8, i64* %4
%11 = load i32, i32* %2
%12 = zext i32 %11 to i64
%13 = alloca i32, i64 %12
store i64 %12, i64* %5
store i32 0, i32* %6
br label %14
14: ; preds = %29, %1
%15 = load i32, i32* %6
%16 = load i32, i32* %2
%17 = icmp slt i32 %15, %16
br i1 %17, label %18, label %32
18: ; preds = %14
%19 = load i32, i32* %6
%20 = add nsw i32 2, %19
%21 = load i32, i32* %6
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds i32, i32* %10, i64 %22
store i32 %20, i32* %23
%24 = load i32, i32* %6
%25 = add nsw i32 4, %24
%26 = load i32, i32* %6
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i32, i32* %13, i64 %27
store i32 %25, i32* %28
br label %29
29: ; preds = %18
%30 = load i32, i32* %6
%31 = add nsw i32 %30, 1
store i32 %31, i32* %6
br label %14
32: ; preds = %14
%33 = load i32, i32* %2
%34 = call i32 @foo(i32 %33, i32* %10)
%35 = call i32 @bar(i32* %10)
%36 = load i8*, i8** %3
ret void
}

LLVM IR (-O2):
define void @vla_func(i32 %0) {
%2 = zext i32 %0 to i64
%3 = alloca i32, i64 %2
%4 = icmp sgt i32 %0, 0
br i1 %4, label %5, label %80
5: ; preds = %1
%6 = icmp ult i32 %0, 8
br i1 %6, label %71, label %7
7: ; preds = %5
%8 = and i64 %2, 4294967288
%9 = add nsw i64 %8, -8
%10 = lshr exact i64 %9, 3
%11 = add nuw nsw i64 %10, 1
%12 = and i64 %11, 3
%13 = icmp ult i64 %9, 24
br i1 %13, label %51, label %14
14: ; preds = %7
%15 = and i64 %11, 4611686018427387900
br label %16
16: ; preds = %16, %14
%17 = phi i64 [ 0, %14 ], [ %47, %16 ]
%18 = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, %14 ], [ %48, %16 ]
%19 = phi i64 [ 0, %14 ], [ %49, %16 ]
%20 = getelementptr inbounds i32, i32* %3, i64 %17
%21 = add <4 x i32> %18, <i32 2, i32 2, i32 2, i32 2>
%22 = add <4 x i32> %18, <i32 6, i32 6, i32 6, i32 6>
%23 = bitcast i32* %20 to <4 x i32>*
store <4 x i32> %21, <4 x i32>* %23
%24 = getelementptr inbounds i32, i32* %20, i64 4
%25 = bitcast i32* %24 to <4 x i32>*
store <4 x i32> %22, <4 x i32>* %25
%26 = or i64 %17, 8
%27 = getelementptr inbounds i32, i32* %3, i64 %26
%28 = add <4 x i32> %18, <i32 10, i32 10, i32 10, i32 10>
%29 = add <4 x i32> %18, <i32 14, i32 14, i32 14, i32 14>
%30 = bitcast i32* %27 to <4 x i32>*
store <4 x i32> %28, <4 x i32>* %30
%31 = getelementptr inbounds i32, i32* %27, i64 4
%32 = bitcast i32* %31 to <4 x i32>*
store <4 x i32> %29, <4 x i32>* %32
%33 = or i64 %17, 16
%34 = getelementptr inbounds i32, i32* %3, i64 %33
%35 = add <4 x i32> %18, <i32 18, i32 18, i32 18, i32 18>
%36 = add <4 x i32> %18, <i32 22, i32 22, i32 22, i32 22>
%37 = bitcast i32* %34 to <4 x i32>*
store <4 x i32> %35, <4 x i32>* %37
%38 = getelementptr inbounds i32, i32* %34, i64 4
%39 = bitcast i32* %38 to <4 x i32>*
store <4 x i32> %36, <4 x i32>* %39
%40 = or i64 %17, 24
%41 = getelementptr inbounds i32, i32* %3, i64 %40
%42 = add <4 x i32> %18, <i32 26, i32 26, i32 26, i32 26>
%43 = add <4 x i32> %18, <i32 30, i32 30, i32 30, i32 30>
%44 = bitcast i32* %41 to <4 x i32>*
store <4 x i32> %42, <4 x i32>* %44
%45 = getelementptr inbounds i32, i32* %41, i64 4
%46 = bitcast i32* %45 to <4 x i32>*
store <4 x i32> %43, <4 x i32>* %46
%47 = add nuw i64 %17, 32
%48 = add <4 x i32> %18, <i32 32, i32 32, i32 32, i32 32>
%49 = add i64 %19, 4
%50 = icmp eq i64 %49, %15
br i1 %50, label %51, label %16
51: ; preds = %16, %7
%52 = phi i64 [ 0, %7 ], [ %47, %16 ]
%53 = phi <4 x i32> [ <i32 0, i32 1, i32 2, i32 3>, %7 ], [ %48, %16 ]
%54 = icmp eq i64 %12, 0
br i1 %54, label %69, label %55
55: ; preds = %51, %55
%56 = phi i64 [ %65, %55 ], [ %52, %51 ]
%57 = phi <4 x i32> [ %66, %55 ], [ %53, %51 ]
%58 = phi i64 [ %67, %55 ], [ 0, %51 ]
%59 = getelementptr inbounds i32, i32* %3, i64 %56
%60 = add <4 x i32> %57, <i32 2, i32 2, i32 2, i32 2>
%61 = add <4 x i32> %57, <i32 6, i32 6, i32 6, i32 6>
%62 = bitcast i32* %59 to <4 x i32>*
store <4 x i32> %60, <4 x i32>* %62
%63 = getelementptr inbounds i32, i32* %59, i64 4
%64 = bitcast i32* %63 to <4 x i32>*
store <4 x i32> %61, <4 x i32>* %64
%65 = add nuw i64 %56, 8
%66 = add <4 x i32> %57, <i32 8, i32 8, i32 8, i32 8>
%67 = add i64 %58, 1
%68 = icmp eq i64 %67, %12
br i1 %68, label %69, label %55
69: ; preds = %55, %51
%70 = icmp eq i64 %8, %2
br i1 %70, label %80, label %71
71: ; preds = %5, %69
%72 = phi i64 [ 0, %5 ], [ %8, %69 ]
br label %73
73: ; preds = %71, %73
%74 = phi i64 [ %78, %73 ], [ %72, %71 ]
%75 = getelementptr inbounds i32, i32* %3, i64 %74
%76 = trunc i64 %74 to i32
%77 = add i32 %76, 2
store i32 %77, i32* %75
%78 = add nuw nsw i64 %74, 1
%79 = icmp eq i64 %78, %2
br i1 %79, label %80, label %73
80: ; preds = %73, %69, %1
%81 = call i32 @foo(i32 %0, i32* %3)
%82 = call i32 @bar(i32* %3)
ret void
}