unsigned long long generate(unsigned long long max) {
  unsigned long long sum = 0;
  unsigned long long three = 3;
  unsigned long long five = 5;
  unsigned long long prev_three = 0;
  unsigned long long prev_five = 0;
  while (three < max || five < max) {
    if (three < max && three != five && three != prev_three) {
      sum += three;
    }
    if (five < max && three != five && five != prev_five) {
      sum += five;
    }
    prev_three = three;
    prev_five = five;
    if (three < five) {
      three += 3;
    } else if (five < three) {
      five += 5;
    } else {
      three += 3;
      five += 5;
    }
  }
  return sum;
}


x86 assembly (clang, -O0):
<generate>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movq   $0x0,-0x10(%rbp)
movq   $0x3,-0x18(%rbp)
movq   $0x5,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x18(%rbp),%rcx
mov    $0x1,%al
cmp    -0x8(%rbp),%rcx
mov    %al,-0x31(%rbp)
jb     1151 <generate+0x51>
mov    -0x20(%rbp),%rax
cmp    -0x8(%rbp),%rax
setb   %al
mov    %al,-0x31(%rbp)
mov    -0x31(%rbp),%al
test   $0x1,%al
jne    1161 <generate+0x61>
jmp    123d <generate+0x13d>
mov    -0x18(%rbp),%rax
cmp    -0x8(%rbp),%rax
jae    1197 <generate+0x97>
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
je     1197 <generate+0x97>
mov    -0x18(%rbp),%rax
cmp    -0x28(%rbp),%rax
je     1197 <generate+0x97>
mov    -0x18(%rbp),%rax
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x8(%rbp),%rax
jae    11cd <generate+0xcd>
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
je     11cd <generate+0xcd>
mov    -0x20(%rbp),%rax
cmp    -0x30(%rbp),%rax
je     11cd <generate+0xcd>
mov    -0x20(%rbp),%rax
add    -0x10(%rbp),%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    11fc <generate+0xfc>
mov    -0x18(%rbp),%rax
add    $0x3,%rax
mov    %rax,-0x18(%rbp)
jmp    1238 <generate+0x138>
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    121b <generate+0x11b>
mov    -0x20(%rbp),%rax
add    $0x5,%rax
mov    %rax,-0x20(%rbp)
jmp    1233 <generate+0x133>
mov    -0x18(%rbp),%rax
add    $0x3,%rax
mov    %rax,-0x18(%rbp)
mov    -0x20(%rbp),%rax
add    $0x5,%rax
mov    %rax,-0x20(%rbp)
jmp    1238 <generate+0x138>
jmp    1130 <generate+0x30>
mov    -0x10(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<generate>:
push   %r15
push   %r14
push   %rbx
cmp    $0x4,%rdi
jb     11c6 <generate+0xc6>
cmp    $0x6,%rdi
setae  %r8b
mov    $0x3,%r10d
mov    $0x5,%r14d
mov    $0x1,%r11b
xor    %r9d,%r9d
xor    %ebx,%ebx
xor    %ecx,%ecx
xor    %eax,%eax
nop
mov    %rax,%r15
mov    %r10,%rdx
mov    %r14,%rsi
cmp    %rcx,%r10
mov    %r10,%rax
cmove  %r9,%rax
cmp    %rbx,%r14
mov    %r14,%rbx
cmove  %r9,%rbx
cmp    %r14,%r10
cmove  %r9,%rax
cmove  %r9,%rbx
test   $0x1,%r11b
cmove  %r9,%rax
add    %r15,%rax
test   $0x1,%r8b
cmove  %r9,%rbx
cmp    %r14,%r10
jae    1180 <generate+0x80>
lea    0x3(%rdx),%r10
mov    %rsi,%r14
jmp    1198 <generate+0x98>
nopl   0x0(%rax)
jbe    1190 <generate+0x90>
lea    0x5(%rsi),%r14
mov    %rdx,%r10
jmp    1198 <generate+0x98>
nopl   0x0(%rax,%rax,1)
lea    0x3(%rdx),%r10
lea    0x5(%rsi),%r14
add    %rbx,%rax
cmp    %rdi,%r14
setb   %r8b
mov    %rsi,%rbx
mov    %rdx,%rcx
cmp    %rdi,%r10
setb   %r11b
jb     1130 <generate+0x30>
mov    %rsi,%rbx
mov    %rdx,%rcx
cmp    %rdi,%r14
jb     1130 <generate+0x30>
jmp    11c8 <generate+0xc8>
xor    %eax,%eax
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define i64 @generate(i64 %0) {
%2 = alloca i64
%3 = alloca i64
%4 = alloca i64
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
store i64 %0, i64* %2
store i64 0, i64* %3
store i64 3, i64* %4
store i64 5, i64* %5
store i64 0, i64* %6
store i64 0, i64* %7
br label %8
8: ; preds = %72, %1
%9 = load i64, i64* %4
%10 = load i64, i64* %2
%11 = icmp ult i64 %9, %10
br i1 %11, label %16, label %12
12: ; preds = %8
%13 = load i64, i64* %5
%14 = load i64, i64* %2
%15 = icmp ult i64 %13, %14
br label %16
16: ; preds = %12, %8
%17 = phi i1 [ true, %8 ], [ %15, %12 ]
br i1 %17, label %18, label %73
18: ; preds = %16
%19 = load i64, i64* %4
%20 = load i64, i64* %2
%21 = icmp ult i64 %19, %20
br i1 %21, label %22, label %34
22: ; preds = %18
%23 = load i64, i64* %4
%24 = load i64, i64* %5
%25 = icmp ne i64 %23, %24
br i1 %25, label %26, label %34
26: ; preds = %22
%27 = load i64, i64* %4
%28 = load i64, i64* %6
%29 = icmp ne i64 %27, %28
br i1 %29, label %30, label %34
30: ; preds = %26
%31 = load i64, i64* %4
%32 = load i64, i64* %3
%33 = add i64 %32, %31
store i64 %33, i64* %3
br label %34
34: ; preds = %30, %26, %22, %18
%35 = load i64, i64* %5
%36 = load i64, i64* %2
%37 = icmp ult i64 %35, %36
br i1 %37, label %38, label %50
38: ; preds = %34
%39 = load i64, i64* %4
%40 = load i64, i64* %5
%41 = icmp ne i64 %39, %40
br i1 %41, label %42, label %50
42: ; preds = %38
%43 = load i64, i64* %5
%44 = load i64, i64* %7
%45 = icmp ne i64 %43, %44
br i1 %45, label %46, label %50
46: ; preds = %42
%47 = load i64, i64* %5
%48 = load i64, i64* %3
%49 = add i64 %48, %47
store i64 %49, i64* %3
br label %50
50: ; preds = %46, %42, %38, %34
%51 = load i64, i64* %4
store i64 %51, i64* %6
%52 = load i64, i64* %5
store i64 %52, i64* %7
%53 = load i64, i64* %4
%54 = load i64, i64* %5
%55 = icmp ult i64 %53, %54
br i1 %55, label %56, label %59
56: ; preds = %50
%57 = load i64, i64* %4
%58 = add i64 %57, 3
store i64 %58, i64* %4
br label %72
59: ; preds = %50
%60 = load i64, i64* %5
%61 = load i64, i64* %4
%62 = icmp ult i64 %60, %61
br i1 %62, label %63, label %66
63: ; preds = %59
%64 = load i64, i64* %5
%65 = add i64 %64, 5
store i64 %65, i64* %5
br label %71
66: ; preds = %59
%67 = load i64, i64* %4
%68 = add i64 %67, 3
store i64 %68, i64* %4
%69 = load i64, i64* %5
%70 = add i64 %69, 5
store i64 %70, i64* %5
br label %71
71: ; preds = %66, %63
br label %72
72: ; preds = %71, %56
br label %8
73: ; preds = %16
%74 = load i64, i64* %3
ret i64 %74
}

LLVM IR (-O2):
define i64 @generate(i64 %0) {
%2 = icmp ugt i64 %0, 3
br i1 %2, label %3, label %42
3: ; preds = %1
%4 = icmp ugt i64 %0, 5
br label %5
5: ; preds = %3, %36
%6 = phi i1 [ %40, %36 ], [ %4, %3 ]
%7 = phi i1 [ %39, %36 ], [ true, %3 ]
%8 = phi i64 [ %10, %36 ], [ 0, %3 ]
%9 = phi i64 [ %11, %36 ], [ 0, %3 ]
%10 = phi i64 [ %38, %36 ], [ 5, %3 ]
%11 = phi i64 [ %37, %36 ], [ 3, %3 ]
%12 = phi i64 [ %25, %36 ], [ 0, %3 ]
%13 = xor i1 %7, true
%14 = icmp eq i64 %11, %10
%15 = select i1 %13, i1 true, i1 %14
%16 = icmp eq i64 %11, %9
%17 = select i1 %15, i1 true, i1 %16
%18 = select i1 %17, i64 0, i64 %11
%19 = add i64 %18, %12
%20 = xor i1 %6, true
%21 = select i1 %20, i1 true, i1 %14
%22 = icmp eq i64 %10, %8
%23 = select i1 %21, i1 true, i1 %22
%24 = select i1 %23, i64 0, i64 %10
%25 = add i64 %19, %24
%26 = icmp ult i64 %11, %10
br i1 %26, label %27, label %29
27: ; preds = %5
%28 = add i64 %11, 3
br label %36
29: ; preds = %5
%30 = icmp ult i64 %10, %11
br i1 %30, label %31, label %33
31: ; preds = %29
%32 = add i64 %10, 5
br label %36
33: ; preds = %29
%34 = add i64 %11, 3
%35 = add i64 %10, 5
br label %36
36: ; preds = %31, %33, %27
%37 = phi i64 [ %28, %27 ], [ %11, %31 ], [ %34, %33 ]
%38 = phi i64 [ %10, %27 ], [ %32, %31 ], [ %35, %33 ]
%39 = icmp ult i64 %37, %0
%40 = icmp ult i64 %38, %0
%41 = select i1 %39, i1 true, i1 %40
br i1 %41, label %5, label %42
42: ; preds = %36, %1
%43 = phi i64 [ 0, %1 ], [ %25, %36 ]
ret i64 %43
}