unsigned long foobarsum(unsigned long limit) {
  unsigned long iter, sum = 0;
  for (iter = 0; iter < limit; ++iter) {
    if (iter % 3 == 0) {
      sum += iter;
    } else if (iter % 5 == 0) {
      sum += iter;
    }
  }
  return sum;
}


x86 assembly (clang, -O0):
<foobarsum>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movq   $0x0,-0x18(%rbp)
movq   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%rax
cmp    -0x8(%rbp),%rax
jae    118e <foobarsum+0x8e>
mov    -0x10(%rbp),%rax
mov    $0x3,%ecx
xor    %edx,%edx
div    %rcx
cmp    $0x0,%rdx
jne    114f <foobarsum+0x4f>
mov    -0x10(%rbp),%rax
add    -0x18(%rbp),%rax
mov    %rax,-0x18(%rbp)
jmp    1178 <foobarsum+0x78>
mov    -0x10(%rbp),%rax
mov    $0x5,%ecx
xor    %edx,%edx
div    %rcx
cmp    $0x0,%rdx
jne    1173 <foobarsum+0x73>
mov    -0x10(%rbp),%rax
add    -0x18(%rbp),%rax
mov    %rax,-0x18(%rbp)
jmp    1178 <foobarsum+0x78>
jmp    117d <foobarsum+0x7d>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1118 <foobarsum+0x18>
mov    -0x18(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<foobarsum>:
xor    %ecx,%ecx
test   %rdi,%rdi
je     1160 <foobarsum+0x60>
movabs $0xcccccccccccccccd,%r9
cc cc cc
movabs $0xaaaaaaaaaaaaaaab,%r10
aa aa aa
xor    %esi,%esi
jmp    112c <foobarsum+0x2c>
nop
add    %rax,%rcx
add    $0x1,%rsi
cmp    %rsi,%rdi
je     1160 <foobarsum+0x60>
mov    %rsi,%rax
mul    %r9
mov    %rdx,%r8
mov    %rsi,%rax
mul    %r10
shr    %rdx
lea    (%rdx,%rdx,2),%rdx
mov    %rsi,%rax
cmp    %rsi,%rdx
je     1120 <foobarsum+0x20>
shr    $0x2,%r8
lea    (%r8,%r8,4),%rax
cmp    %rsi,%rax
mov    $0x0,%eax
cmove  %rsi,%rax
jmp    1120 <foobarsum+0x20>
mov    %rcx,%rax
ret

LLVM IR (-O0):
define i64 @foobarsum(i64 %0) {
%2 = alloca i64
%3 = alloca i64
%4 = alloca i64
store i64 %0, i64* %2
store i64 0, i64* %4
store i64 0, i64* %3
br label %5
5: ; preds = %27, %1
%6 = load i64, i64* %3
%7 = load i64, i64* %2
%8 = icmp ult i64 %6, %7
br i1 %8, label %9, label %30
9: ; preds = %5
%10 = load i64, i64* %3
%11 = urem i64 %10, 3
%12 = icmp eq i64 %11, 0
br i1 %12, label %13, label %17
13: ; preds = %9
%14 = load i64, i64* %3
%15 = load i64, i64* %4
%16 = add i64 %15, %14
store i64 %16, i64* %4
br label %26
17: ; preds = %9
%18 = load i64, i64* %3
%19 = urem i64 %18, 5
%20 = icmp eq i64 %19, 0
br i1 %20, label %21, label %25
21: ; preds = %17
%22 = load i64, i64* %3
%23 = load i64, i64* %4
%24 = add i64 %23, %22
store i64 %24, i64* %4
br label %25
25: ; preds = %21, %17
br label %26
26: ; preds = %25, %13
br label %27
27: ; preds = %26
%28 = load i64, i64* %3
%29 = add i64 %28, 1
store i64 %29, i64* %3
br label %5
30: ; preds = %5
%31 = load i64, i64* %4
ret i64 %31
}

LLVM IR (-O2):
define i64 @foobarsum(i64 %0) {
%2 = icmp eq i64 %0, 0
br i1 %2, label %17, label %3
3: ; preds = %1, %12
%4 = phi i64 [ %14, %12 ], [ 0, %1 ]
%5 = phi i64 [ %15, %12 ], [ 0, %1 ]
%6 = urem i64 %5, 3
%7 = icmp eq i64 %6, 0
br i1 %7, label %12, label %8
8: ; preds = %3
%9 = urem i64 %5, 5
%10 = icmp eq i64 %9, 0
%11 = select i1 %10, i64 %5, i64 0
br label %12
12: ; preds = %3, %8
%13 = phi i64 [ %11, %8 ], [ %5, %3 ]
%14 = add i64 %13, %4
%15 = add nuw i64 %5, 1
%16 = icmp eq i64 %15, %0
br i1 %16, label %17, label %3
17: ; preds = %12, %1
%18 = phi i64 [ 0, %1 ], [ %14, %12 ]
ret i64 %18
}