#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 */
scalar_t__ sqrt(long);
double waste_time(long n) {
  double res = 0;
  long i = 0;
  while (i < n * 200) {
    i++;
    res += sqrt(i);
  }
  return res;
}


x86 assembly (clang, -O0):
<waste_time>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x10(%rbp)
movq   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%rax
imul   $0xc8,-0x8(%rbp),%rcx
cmp    %rcx,%rax
jge    116a <waste_time+0x5a>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rdi
call   1030 <sqrt@plt>
cvtsi2sd %rax,%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    112c <waste_time+0x1c>
movsd  -0x10(%rbp),%xmm0
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<waste_time>:
push   %r15
push   %r14
push   %rbx
sub    $0x10,%rsp
test   %rdi,%rdi
jle    114f <waste_time+0x3f>
imul   $0xc8,%rdi,%rax
cmp    $0x2,%rax
mov    $0x1,%r15d
cmovge %rax,%r15
lea    -0x1(%r15),%rax
mov    %r15d,%r14d
and    $0x1,%r14d
cmp    $0x3,%rax
jae    1158 <waste_time+0x48>
xorpd  %xmm0,%xmm0
xor    %ebx,%ebx
jmp    11ec <waste_time+0xdc>
xorpd  %xmm0,%xmm0
jmp    1236 <waste_time+0x126>
movabs $0x7ffffffffffffff8,%rax
ff ff 7f
and    %rax,%r15
xorpd  %xmm0,%xmm0
xor    %ebx,%ebx
nopl   0x0(%rax,%rax,1)
movsd  %xmm0,0x8(%rsp)
lea    0x1(%rbx),%rdi
call   1030 <sqrt@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
lea    0x2(%rbx),%rdi
call   1030 <sqrt@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
lea    0x3(%rbx),%rdi
call   1030 <sqrt@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0x8(%rsp),%xmm0
movsd  %xmm0,0x8(%rsp)
add    $0x4,%rbx
mov    %rbx,%rdi
call   1030 <sqrt@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
addsd  0x8(%rsp),%xmm0
cmp    %rbx,%r15
jne    1170 <waste_time+0x60>
test   %r14,%r14
je     1236 <waste_time+0x126>
add    $0x1,%rbx
cs nopw 0x0(%rax,%rax,1)
nop
movsd  %xmm0,0x8(%rsp)
mov    %rbx,%rdi
call   1030 <sqrt@plt>
xorps  %xmm0,%xmm0
cvtsi2sd %rax,%xmm0
movsd  0x8(%rsp),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0x8(%rsp),%xmm0
add    $0x1,%rbx
add    $0xffffffffffffffff,%r14
jne    1200 <waste_time+0xf0>
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define double @waste_time(i64 %0) {
%2 = alloca i64
%3 = alloca double
%4 = alloca i64
store i64 %0, i64* %2
store double 0.000000e+00, double* %3
store i64 0, i64* %4
br label %5
5: ; preds = %10, %1
%6 = load i64, i64* %4
%7 = load i64, i64* %2
%8 = mul nsw i64 %7, 200
%9 = icmp slt i64 %6, %8
br i1 %9, label %10, label %18
10: ; preds = %5
%11 = load i64, i64* %4
%12 = add nsw i64 %11, 1
store i64 %12, i64* %4
%13 = load i64, i64* %4
%14 = call i64 @sqrt(i64 %13)
%15 = sitofp i64 %14 to double
%16 = load double, double* %3
%17 = fadd double %16, %15
store double %17, double* %3
br label %5
18: ; preds = %5
%19 = load double, double* %3
ret double %19
}

LLVM IR (-O2):
define double @waste_time(i64 %0) {
%2 = icmp sgt i64 %0, 0
br i1 %2, label %3, label %48
3: ; preds = %1
%4 = mul i64 %0, 200
%5 = call i64 @llvm.smax.i64(i64 %4, i64 1)
%6 = add nsw i64 %5, -1
%7 = and i64 %5, 1
%8 = icmp ult i64 %6, 3
br i1 %8, label %33, label %9
9: ; preds = %3
%10 = and i64 %5, 9223372036854775800
br label %11
11: ; preds = %11, %9
%12 = phi i64 [ 0, %9 ], [ %27, %11 ]
%13 = phi double [ 0.000000e+00, %9 ], [ %30, %11 ]
%14 = phi i64 [ 0, %9 ], [ %31, %11 ]
%15 = or i64 %12, 1
%16 = tail call i64 @sqrt(i64 %15)
%17 = sitofp i64 %16 to double
%18 = fadd double %13, %17
%19 = or i64 %12, 2
%20 = tail call i64 @sqrt(i64 %19)
%21 = sitofp i64 %20 to double
%22 = fadd double %18, %21
%23 = or i64 %12, 3
%24 = tail call i64 @sqrt(i64 %23)
%25 = sitofp i64 %24 to double
%26 = fadd double %22, %25
%27 = add nuw nsw i64 %12, 4
%28 = tail call i64 @sqrt(i64 %27)
%29 = sitofp i64 %28 to double
%30 = fadd double %26, %29
%31 = add i64 %14, 4
%32 = icmp eq i64 %31, %10
br i1 %32, label %33, label %11
33: ; preds = %11, %3
%34 = phi double [ undef, %3 ], [ %30, %11 ]
%35 = phi i64 [ 0, %3 ], [ %27, %11 ]
%36 = phi double [ 0.000000e+00, %3 ], [ %30, %11 ]
%37 = icmp eq i64 %7, 0
br i1 %37, label %48, label %38
38: ; preds = %33, %38
%39 = phi i64 [ %42, %38 ], [ %35, %33 ]
%40 = phi double [ %45, %38 ], [ %36, %33 ]
%41 = phi i64 [ %46, %38 ], [ 0, %33 ]
%42 = add nuw nsw i64 %39, 1
%43 = tail call i64 @sqrt(i64 %42)
%44 = sitofp i64 %43 to double
%45 = fadd double %40, %44
%46 = add i64 %41, 1
%47 = icmp eq i64 %46, %7
br i1 %47, label %48, label %38
48: ; preds = %33, %38, %1
%49 = phi double [ 0.000000e+00, %1 ], [ %34, %33 ], [ %45, %38 ]
ret double %49
}