#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 */
struct timeval {
  long long tv_usec;
};

/* Variables and functions */
int /*<<< orphan*/ gettimeofday(struct timeval *, int /*<<< orphan*/ *);
int /*<<< orphan*/ printf(char *, long long);
int main(void) {
  struct timeval stop, start;
  gettimeofday(&start, NULL);
  long long limite = 4000000;
  long long fibonacci[2] = {1, 2};
  long long bubble = 0, acum = 2;
  bubble = fibonacci[0] + fibonacci[1];
  while (bubble < limite) {
    fibonacci[0] = fibonacci[1];
    fibonacci[1] = bubble;
    if (bubble % 2 == 0) {
      acum += bubble;
    }
    bubble = fibonacci[0] + fibonacci[1];
  }
  printf("acum = %d", acum);
  gettimeofday(&stop, NULL);
  printf("\ntook %lu usec\n", stop.tv_usec - start.tv_usec);
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movl   $0x0,-0x4(%rbp)
lea    -0x18(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1040 <gettimeofday@plt>
movq   $0x3d0900,-0x20(%rbp)
mov    0xeb5(%rip),%rax
mov    %rax,-0x30(%rbp)
mov    0xeb2(%rip),%rax
mov    %rax,-0x28(%rbp)
movq   $0x0,-0x38(%rbp)
movq   $0x2,-0x40(%rbp)
mov    -0x30(%rbp),%rax
add    -0x28(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x20(%rbp),%rax
jge    11c9 <main+0xa9>
mov    -0x28(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x38(%rbp),%rax
mov    $0x2,%ecx
cqto
idiv   %rcx
cmp    $0x0,%rdx
jne    11b8 <main+0x98>
mov    -0x38(%rbp),%rax
add    -0x40(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x30(%rbp),%rax
add    -0x28(%rbp),%rax
mov    %rax,-0x38(%rbp)
jmp    1176 <main+0x56>
mov    -0x40(%rbp),%rsi
lea    0xe3c(%rip),%rdi
call   1030 <printf@plt>
lea    -0x10(%rbp),%rdi
xor    %eax,%eax
mov    %eax,%esi
call   1040 <gettimeofday@plt>
mov    -0x10(%rbp),%rsi
sub    -0x18(%rbp),%rsi
lea    0xe25(%rip),%rdi
call   1030 <printf@plt>
mov    -0x4(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
sub    $0x18,%rsp
lea    0x8(%rsp),%rdi
xor    %esi,%esi
call   1040 <gettimeofday@plt>
mov    $0x3,%ecx
mov    $0x2,%esi
mov    $0x2,%eax
nop
mov    %rcx,%rdx
test   $0x1,%dl
mov    $0x0,%ecx
cmove  %rdx,%rcx
add    %rcx,%rsi
add    %rdx,%rax
mov    %rax,%rcx
cmp    $0x3d0900,%rax
mov    %rdx,%rax
jl     1140 <main+0x20>
lea    0xe96(%rip),%rdi
call   1030 <printf@plt>
lea    0x10(%rsp),%rdi
xor    %esi,%esi
call   1040 <gettimeofday@plt>
mov    0x10(%rsp),%rsi
sub    0x8(%rsp),%rsi
lea    0xe7e(%rip),%rdi
call   1030 <printf@plt>
xor    %eax,%eax
add    $0x18,%rsp
ret

LLVM IR (-O0):
%struct.timeval = type { i64 }
@__const.main.fibonacci = [2 x i64] [i64 1, i64 2]
@.str = [10 x i8] c"acum = %d\00"
@.str.1 = [16 x i8] c"\0Atook %lu usec\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca %struct.timeval
%3 = alloca %struct.timeval
%4 = alloca i64
%5 = alloca [2 x i64]
%6 = alloca i64
%7 = alloca i64
store i32 0, i32* %1
%8 = call i32 @gettimeofday(%struct.timeval* %3, i32* null)
store i64 4000000, i64* %4
%9 = bitcast [2 x i64]* %5 to i8*
store i64 0, i64* %6
store i64 2, i64* %7
%10 = getelementptr inbounds [2 x i64], [2 x i64]* %5, i64 0, i64 0
%11 = load i64, i64* %10
%12 = getelementptr inbounds [2 x i64], [2 x i64]* %5, i64 0, i64 1
%13 = load i64, i64* %12
%14 = add nsw i64 %11, %13
store i64 %14, i64* %6
br label %15
15: ; preds = %32, %0
%16 = load i64, i64* %6
%17 = load i64, i64* %4
%18 = icmp slt i64 %16, %17
br i1 %18, label %19, label %38
19: ; preds = %15
%20 = getelementptr inbounds [2 x i64], [2 x i64]* %5, i64 0, i64 1
%21 = load i64, i64* %20
%22 = getelementptr inbounds [2 x i64], [2 x i64]* %5, i64 0, i64 0
store i64 %21, i64* %22
%23 = load i64, i64* %6
%24 = getelementptr inbounds [2 x i64], [2 x i64]* %5, i64 0, i64 1
store i64 %23, i64* %24
%25 = load i64, i64* %6
%26 = srem i64 %25, 2
%27 = icmp eq i64 %26, 0
br i1 %27, label %28, label %32
28: ; preds = %19
%29 = load i64, i64* %6
%30 = load i64, i64* %7
%31 = add nsw i64 %30, %29
store i64 %31, i64* %7
br label %32
32: ; preds = %28, %19
%33 = getelementptr inbounds [2 x i64], [2 x i64]* %5, i64 0, i64 0
%34 = load i64, i64* %33
%35 = getelementptr inbounds [2 x i64], [2 x i64]* %5, i64 0, i64 1
%36 = load i64, i64* %35
%37 = add nsw i64 %34, %36
store i64 %37, i64* %6
br label %15
38: ; preds = %15
%39 = load i64, i64* %7
%40 = call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i64 %39)
%41 = call i32 @gettimeofday(%struct.timeval* %2, i32* null)
%42 = getelementptr inbounds %struct.timeval, %struct.timeval* %2, i32 0, i32 0
%43 = load i64, i64* %42
%44 = getelementptr inbounds %struct.timeval, %struct.timeval* %3, i32 0, i32 0
%45 = load i64, i64* %44
%46 = sub nsw i64 %43, %45
%47 = call i32 @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.1, i64 0, i64 0), i64 %46)
%48 = load i32, i32* %1
ret i32 %48
}

LLVM IR (-O2):
%struct.timeval = type { i64 }
@.str = [10 x i8] c"acum = %d\00"
@.str.1 = [16 x i8] c"\0Atook %lu usec\0A\00"
define i32 @main() {
%1 = alloca %struct.timeval
%2 = alloca %struct.timeval
%3 = bitcast %struct.timeval* %1 to i8*
%4 = bitcast %struct.timeval* %2 to i8*
%5 = call i32 @gettimeofday(%struct.timeval* %2, i32* null)
br label %6
6: ; preds = %0, %6
%7 = phi i64 [ 2, %0 ], [ %13, %6 ]
%8 = phi i64 [ 3, %0 ], [ %14, %6 ]
%9 = phi i64 [ 2, %0 ], [ %8, %6 ]
%10 = and i64 %8, 1
%11 = icmp eq i64 %10, 0
%12 = select i1 %11, i64 %8, i64 0
%13 = add nsw i64 %12, %7
%14 = add nsw i64 %8, %9
%15 = icmp slt i64 %14, 4000000
br i1 %15, label %6, label %16
16: ; preds = %6
%17 = tail call i32 @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str, i64 0, i64 0), i64 %13)
%18 = call i32 @gettimeofday(%struct.timeval* %1, i32* null)
%19 = getelementptr inbounds %struct.timeval, %struct.timeval* %1, i64 0, i32 0
%20 = load i64, i64* %19
%21 = getelementptr inbounds %struct.timeval, %struct.timeval* %2, i64 0, i32 0
%22 = load i64, i64* %21
%23 = sub nsw i64 %20, %22
%24 = tail call i32 @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.1, i64 0, i64 0), i64 %23)
ret i32 0
}