#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*/ free(int *);
int *generate_prime_array(int);
int *malloc(int);
int *generate_primes(int n) {
  bool *prime_array = generate_prime_array(n);
  int count = 0;
  for (int i = 2; i < n; i++) {
    if (prime_array[i]) {
      ++count;
    }
  }
  int *primes = malloc(count * sizeof(int) + 1);
  primes[count] = 0;
  for (int i = 2, position = 0; i < n; ++i) {
    if (prime_array[i]) {
      primes[position++] = i;
    }
  }
  free(prime_array);
  return primes;
}


x86 assembly (clang, -O0):
<generate_primes>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x4(%rbp)
mov    -0x4(%rbp),%edi
call   1050 <generate_prime_array@plt>
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
movl   $0x2,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    118f <generate_primes+0x5f>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
cmpl   $0x0,(%rax,%rcx,4)
je     117c <generate_primes+0x4c>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1181 <generate_primes+0x51>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1155 <generate_primes+0x25>
movslq -0x14(%rbp),%rax
shl    $0x2,%rax
add    $0x1,%rax
mov    %eax,%edi
call   1040 <malloc@plt>
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x14(%rbp),%rcx
movl   $0x0,(%rax,%rcx,4)
movl   $0x2,-0x24(%rbp)
movl   $0x0,-0x28(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    120c <generate_primes+0xdc>
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
cmpl   $0x0,(%rax,%rcx,4)
je     11f9 <generate_primes+0xc9>
mov    -0x24(%rbp),%edx
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x28(%rbp)
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
jmp    11fe <generate_primes+0xce>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    11c3 <generate_primes+0x93>
mov    -0x10(%rbp),%rdi
call   1030 <free@plt>
mov    -0x20(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<generate_primes>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %edi,%r14d
call   1050 <generate_prime_array@plt>
mov    %rax,%rbx
xor    %ebp,%ebp
mov    %r14d,%r15d
cmp    $0x3,%r14d
jl     1270 <generate_primes+0x140>
lea    -0x2(%r15),%rcx
cmp    $0x8,%rcx
jae    1168 <generate_primes+0x38>
xor    %ebp,%ebp
mov    $0x2,%eax
jmp    1260 <generate_primes+0x130>
mov    %rcx,%rax
and    $0xfffffffffffffff8,%rax
lea    -0x8(%rax),%rsi
mov    %rsi,%rdx
shr    $0x3,%rdx
add    $0x1,%rdx
test   %rsi,%rsi
je     1318 <generate_primes+0x1e8>
mov    %rdx,%rdi
and    $0xfffffffffffffffe,%rdi
pxor   %xmm2,%xmm2
mov    $0x2,%esi
movdqa 0xe61(%rip),%xmm3
pxor   %xmm5,%xmm5
pxor   %xmm4,%xmm4
nopw   0x0(%rax,%rax,1)
movdqu (%rbx,%rsi,4),%xmm6
movdqu 0x10(%rbx,%rsi,4),%xmm7
movdqu 0x20(%rbx,%rsi,4),%xmm0
movdqu 0x30(%rbx,%rsi,4),%xmm1
pcmpeqd %xmm2,%xmm6
paddd  %xmm5,%xmm6
pcmpeqd %xmm2,%xmm7
paddd  %xmm4,%xmm7
pcmpeqd %xmm2,%xmm0
pcmpeqd %xmm2,%xmm1
paddd  %xmm3,%xmm0
paddd  %xmm6,%xmm0
paddd  %xmm3,%xmm1
paddd  %xmm7,%xmm1
add    $0x10,%rsi
movdqa %xmm0,%xmm5
movdqa %xmm1,%xmm4
add    $0xfffffffffffffffe,%rdi
jne    11b0 <generate_primes+0x80>
test   $0x1,%dl
je     1231 <generate_primes+0x101>
movdqu (%rbx,%rsi,4),%xmm2
movdqu 0x10(%rbx,%rsi,4),%xmm3
pxor   %xmm4,%xmm4
pcmpeqd %xmm4,%xmm2
paddd  %xmm2,%xmm0
pcmpeqd %xmm4,%xmm3
paddd  %xmm3,%xmm1
pcmpeqd %xmm2,%xmm2
psubd  %xmm2,%xmm0
psubd  %xmm2,%xmm1
paddd  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddd  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddd  %xmm1,%xmm0
movd   %xmm0,%ebp
cmp    %rax,%rcx
je     1270 <generate_primes+0x140>
or     $0x2,%rax
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
cmpl   $0x1,(%rbx,%rax,4)
sbb    $0xffffffff,%ebp
add    $0x1,%rax
cmp    %rax,%r15
jne    1260 <generate_primes+0x130>
lea    0x1(,%rbp,4),%edi
call   1040 <malloc@plt>
mov    %rax,%r12
mov    %ebp,%eax
movl   $0x0,(%r12,%rax,4)
cmp    $0x3,%r14d
jl     12ab <generate_primes+0x17b>
jne    12bf <generate_primes+0x18f>
xor    %ecx,%ecx
mov    $0x2,%eax
test   $0x1,%r15b
je     12ab <generate_primes+0x17b>
cmpl   $0x0,(%rbx,%rax,4)
je     12ab <generate_primes+0x17b>
movslq %ecx,%rcx
mov    %eax,(%r12,%rcx,4)
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %r12,%rax
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret
lea    -0x2(%r15),%rdx
and    $0xfffffffffffffffe,%rdx
neg    %rdx
xor    %ecx,%ecx
mov    $0x2,%eax
mov    $0x3,%esi
jmp    12f5 <generate_primes+0x1c5>
nopl   0x0(%rax,%rax,1)
add    $0x2,%esi
lea    (%rdx,%rax,1),%rdi
add    $0x2,%rdi
add    $0x2,%rax
cmp    $0x2,%rdi
je     1298 <generate_primes+0x168>
cmpl   $0x0,(%rbx,%rax,4)
je     1305 <generate_primes+0x1d5>
movslq %ecx,%rdi
add    $0x1,%ecx
mov    %eax,(%r12,%rdi,4)
cmpl   $0x0,0x4(%rbx,%rax,4)
je     12e0 <generate_primes+0x1b0>
movslq %ecx,%rdi
add    $0x1,%ecx
mov    %esi,(%r12,%rdi,4)
jmp    12e0 <generate_primes+0x1b0>
pxor   %xmm0,%xmm0
mov    $0x2,%esi
pxor   %xmm1,%xmm1
test   $0x1,%dl
jne    1206 <generate_primes+0xd6>
jmp    1231 <generate_primes+0x101>

LLVM IR (-O0):
define i32* @generate_primes(i32 %0) {
%2 = alloca i32
%3 = alloca i32*
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32*
%7 = alloca i32
%8 = alloca i32
store i32 %0, i32* %2
%9 = load i32, i32* %2
%10 = call i32* @generate_prime_array(i32 %9)
store i32* %10, i32** %3
store i32 0, i32* %4
store i32 2, i32* %5
br label %11
11: ; preds = %26, %1
%12 = load i32, i32* %5
%13 = load i32, i32* %2
%14 = icmp slt i32 %12, %13
br i1 %14, label %15, label %29
15: ; preds = %11
%16 = load i32*, i32** %3
%17 = load i32, i32* %5
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds i32, i32* %16, i64 %18
%20 = load i32, i32* %19
%21 = icmp ne i32 %20, 0
br i1 %21, label %22, label %25
22: ; preds = %15
%23 = load i32, i32* %4
%24 = add nsw i32 %23, 1
store i32 %24, i32* %4
br label %25
25: ; preds = %22, %15
br label %26
26: ; preds = %25
%27 = load i32, i32* %5
%28 = add nsw i32 %27, 1
store i32 %28, i32* %5
br label %11
29: ; preds = %11
%30 = load i32, i32* %4
%31 = sext i32 %30 to i64
%32 = mul i64 %31, 4
%33 = add i64 %32, 1
%34 = trunc i64 %33 to i32
%35 = call i32* @malloc(i32 %34)
store i32* %35, i32** %6
%36 = load i32*, i32** %6
%37 = load i32, i32* %4
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds i32, i32* %36, i64 %38
store i32 0, i32* %39
store i32 2, i32* %7
store i32 0, i32* %8
br label %40
40: ; preds = %59, %29
%41 = load i32, i32* %7
%42 = load i32, i32* %2
%43 = icmp slt i32 %41, %42
br i1 %43, label %44, label %62
44: ; preds = %40
%45 = load i32*, i32** %3
%46 = load i32, i32* %7
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds i32, i32* %45, i64 %47
%49 = load i32, i32* %48
%50 = icmp ne i32 %49, 0
br i1 %50, label %51, label %58
51: ; preds = %44
%52 = load i32, i32* %7
%53 = load i32*, i32** %6
%54 = load i32, i32* %8
%55 = add nsw i32 %54, 1
store i32 %55, i32* %8
%56 = sext i32 %54 to i64
%57 = getelementptr inbounds i32, i32* %53, i64 %56
store i32 %52, i32* %57
br label %58
58: ; preds = %51, %44
br label %59
59: ; preds = %58
%60 = load i32, i32* %7
%61 = add nsw i32 %60, 1
store i32 %61, i32* %7
br label %40
62: ; preds = %40
%63 = load i32*, i32** %3
%64 = call i32 @free(i32* %63)
%65 = load i32*, i32** %6
ret i32* %65
}

LLVM IR (-O2):
define noalias i32* @generate_primes(i32 %0) {
%2 = tail call i32* @generate_prime_array(i32 %0)
%3 = icmp sgt i32 %0, 2
br i1 %3, label %4, label %83
4: ; preds = %1
%5 = zext i32 %0 to i64
%6 = add nsw i64 %5, -2
%7 = icmp ult i64 %6, 8
br i1 %7, label %80, label %8
8: ; preds = %4
%9 = and i64 %6, -8
%10 = or i64 %9, 2
%11 = add nsw i64 %9, -8
%12 = lshr exact i64 %11, 3
%13 = add nuw nsw i64 %12, 1
%14 = and i64 %13, 1
%15 = icmp eq i64 %11, 0
br i1 %15, label %54, label %16
16: ; preds = %8
%17 = and i64 %13, 4611686018427387902
br label %18
18: ; preds = %18, %16
%19 = phi i64 [ 0, %16 ], [ %49, %18 ]
%20 = phi <4 x i32> [ zeroinitializer, %16 ], [ %47, %18 ]
%21 = phi <4 x i32> [ zeroinitializer, %16 ], [ %48, %18 ]
%22 = phi i64 [ 0, %16 ], [ %50, %18 ]
%23 = or i64 %19, 2
%24 = getelementptr inbounds i32, i32* %2, i64 %23
%25 = bitcast i32* %24 to <4 x i32>*
%26 = load <4 x i32>, <4 x i32>* %25
%27 = getelementptr inbounds i32, i32* %24, i64 4
%28 = bitcast i32* %27 to <4 x i32>*
%29 = load <4 x i32>, <4 x i32>* %28
%30 = icmp ne <4 x i32> %26, zeroinitializer
%31 = icmp ne <4 x i32> %29, zeroinitializer
%32 = zext <4 x i1> %30 to <4 x i32>
%33 = zext <4 x i1> %31 to <4 x i32>
%34 = add <4 x i32> %20, %32
%35 = add <4 x i32> %21, %33
%36 = or i64 %19, 10
%37 = getelementptr inbounds i32, i32* %2, i64 %36
%38 = bitcast i32* %37 to <4 x i32>*
%39 = load <4 x i32>, <4 x i32>* %38
%40 = getelementptr inbounds i32, i32* %37, i64 4
%41 = bitcast i32* %40 to <4 x i32>*
%42 = load <4 x i32>, <4 x i32>* %41
%43 = icmp ne <4 x i32> %39, zeroinitializer
%44 = icmp ne <4 x i32> %42, zeroinitializer
%45 = zext <4 x i1> %43 to <4 x i32>
%46 = zext <4 x i1> %44 to <4 x i32>
%47 = add <4 x i32> %34, %45
%48 = add <4 x i32> %35, %46
%49 = add nuw i64 %19, 16
%50 = add i64 %22, 2
%51 = icmp eq i64 %50, %17
br i1 %51, label %52, label %18
52: ; preds = %18
%53 = or i64 %49, 2
br label %54
54: ; preds = %52, %8
%55 = phi <4 x i32> [ undef, %8 ], [ %47, %52 ]
%56 = phi <4 x i32> [ undef, %8 ], [ %48, %52 ]
%57 = phi i64 [ 2, %8 ], [ %53, %52 ]
%58 = phi <4 x i32> [ zeroinitializer, %8 ], [ %47, %52 ]
%59 = phi <4 x i32> [ zeroinitializer, %8 ], [ %48, %52 ]
%60 = icmp eq i64 %14, 0
br i1 %60, label %74, label %61
61: ; preds = %54
%62 = getelementptr inbounds i32, i32* %2, i64 %57
%63 = bitcast i32* %62 to <4 x i32>*
%64 = load <4 x i32>, <4 x i32>* %63
%65 = getelementptr inbounds i32, i32* %62, i64 4
%66 = bitcast i32* %65 to <4 x i32>*
%67 = load <4 x i32>, <4 x i32>* %66
%68 = icmp ne <4 x i32> %64, zeroinitializer
%69 = icmp ne <4 x i32> %67, zeroinitializer
%70 = zext <4 x i1> %68 to <4 x i32>
%71 = zext <4 x i1> %69 to <4 x i32>
%72 = add <4 x i32> %58, %70
%73 = add <4 x i32> %59, %71
br label %74
74: ; preds = %54, %61
%75 = phi <4 x i32> [ %55, %54 ], [ %72, %61 ]
%76 = phi <4 x i32> [ %56, %54 ], [ %73, %61 ]
%77 = add <4 x i32> %76, %75
%78 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %77)
%79 = icmp eq i64 %6, %9
br i1 %79, label %83, label %80
80: ; preds = %4, %74
%81 = phi i64 [ 2, %4 ], [ %10, %74 ]
%82 = phi i32 [ 0, %4 ], [ %78, %74 ]
br label %97
83: ; preds = %97, %74, %1
%84 = phi i32 [ 0, %1 ], [ %78, %74 ], [ %104, %97 ]
%85 = zext i32 %84 to i64
%86 = shl i32 %84, 2
%87 = or i32 %86, 1
%88 = tail call i32* @malloc(i32 %87)
%89 = getelementptr inbounds i32, i32* %88, i64 %85
store i32 0, i32* %89
br i1 %3, label %90, label %119
90: ; preds = %83
%91 = zext i32 %0 to i64
%92 = and i64 %91, 1
%93 = icmp eq i32 %0, 3
br i1 %93, label %107, label %94
94: ; preds = %90
%95 = add nsw i64 %91, -2
%96 = and i64 %95, -2
br label %121
97: ; preds = %80, %97
%98 = phi i64 [ %105, %97 ], [ %81, %80 ]
%99 = phi i32 [ %104, %97 ], [ %82, %80 ]
%100 = getelementptr inbounds i32, i32* %2, i64 %98
%101 = load i32, i32* %100
%102 = icmp ne i32 %101, 0
%103 = zext i1 %102 to i32
%104 = add nuw nsw i32 %99, %103
%105 = add nuw nsw i64 %98, 1
%106 = icmp eq i64 %105, %5
br i1 %106, label %83, label %97
107: ; preds = %144, %90
%108 = phi i64 [ 2, %90 ], [ %146, %144 ]
%109 = phi i32 [ 0, %90 ], [ %145, %144 ]
%110 = icmp eq i64 %92, 0
br i1 %110, label %119, label %111
111: ; preds = %107
%112 = getelementptr inbounds i32, i32* %2, i64 %108
%113 = load i32, i32* %112
%114 = icmp eq i32 %113, 0
br i1 %114, label %119, label %115
115: ; preds = %111
%116 = sext i32 %109 to i64
%117 = getelementptr inbounds i32, i32* %88, i64 %116
%118 = trunc i64 %108 to i32
store i32 %118, i32* %117
br label %119
119: ; preds = %107, %115, %111, %83
%120 = tail call i32 @free(i32* %2)
ret i32* %88
121: ; preds = %144, %94
%122 = phi i64 [ 2, %94 ], [ %146, %144 ]
%123 = phi i32 [ 0, %94 ], [ %145, %144 ]
%124 = phi i64 [ 0, %94 ], [ %147, %144 ]
%125 = getelementptr inbounds i32, i32* %2, i64 %122
%126 = load i32, i32* %125
%127 = icmp eq i32 %126, 0
br i1 %127, label %133, label %128
128: ; preds = %121
%129 = add nsw i32 %123, 1
%130 = sext i32 %123 to i64
%131 = getelementptr inbounds i32, i32* %88, i64 %130
%132 = trunc i64 %122 to i32
store i32 %132, i32* %131
br label %133
133: ; preds = %121, %128
%134 = phi i32 [ %129, %128 ], [ %123, %121 ]
%135 = or i64 %122, 1
%136 = getelementptr inbounds i32, i32* %2, i64 %135
%137 = load i32, i32* %136
%138 = icmp eq i32 %137, 0
br i1 %138, label %144, label %139
139: ; preds = %133
%140 = add nsw i32 %134, 1
%141 = sext i32 %134 to i64
%142 = getelementptr inbounds i32, i32* %88, i64 %141
%143 = trunc i64 %135 to i32
store i32 %143, i32* %142
br label %144
144: ; preds = %139, %133
%145 = phi i32 [ %140, %139 ], [ %134, %133 ]
%146 = add nuw nsw i64 %122, 2
%147 = add i64 %124, 2
%148 = icmp eq i64 %147, %96
br i1 %148, label %107, label %121
}