void draw_circle(char *pixelbuf, int image_width, int image_height, int x0,
                 int y0, float radius, char fill) {
  int x, y;
  int radius_i = (int)radius;
  for (y = -radius_i; y <= radius_i; y++) {
    for (x = -radius_i; x <= radius_i; x++) {
      if ((x * x) + (y * y) <= (radius_i * radius_i)) {
        if ((y + y0 >= 0) && (y + y0 < image_height) && (x + x0 >= 0) &&
            (x + x0 < image_width)) {
          *(pixelbuf + ((y + y0) * image_width) + (x + x0)) = fill;
        }
      }
    }
  }
}


x86 assembly (clang, -O0):
<draw_circle>:
push   %rbp
mov    %rsp,%rbp
mov    %r9b,%al
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8d,-0x18(%rbp)
movss  %xmm0,-0x1c(%rbp)
mov    %al,-0x1d(%rbp)
cvttss2si -0x1c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
xor    %eax,%eax
sub    -0x2c(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jg     11f9 <draw_circle+0xf9>
xor    %eax,%eax
sub    -0x2c(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jg     11e6 <draw_circle+0xe6>
mov    -0x24(%rbp),%eax
imul   -0x24(%rbp),%eax
mov    -0x28(%rbp),%ecx
imul   -0x28(%rbp),%ecx
add    %ecx,%eax
mov    -0x2c(%rbp),%ecx
imul   -0x2c(%rbp),%ecx
cmp    %ecx,%eax
jg     11d3 <draw_circle+0xd3>
mov    -0x28(%rbp),%eax
add    -0x18(%rbp),%eax
cmp    $0x0,%eax
jl     11ce <draw_circle+0xce>
mov    -0x28(%rbp),%eax
add    -0x18(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    11ce <draw_circle+0xce>
mov    -0x24(%rbp),%eax
add    -0x14(%rbp),%eax
cmp    $0x0,%eax
jl     11ce <draw_circle+0xce>
mov    -0x24(%rbp),%eax
add    -0x14(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    11ce <draw_circle+0xce>
mov    -0x1d(%rbp),%dl
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    -0x18(%rbp),%ecx
imul   -0xc(%rbp),%ecx
movslq %ecx,%rcx
add    %rcx,%rax
mov    -0x24(%rbp),%ecx
add    -0x14(%rbp),%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    11d3 <draw_circle+0xd3>
jmp    11d8 <draw_circle+0xd8>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    1144 <draw_circle+0x44>
jmp    11eb <draw_circle+0xeb>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    1130 <draw_circle+0x30>
pop    %rbp
ret

x86 assembly (clang, -O2):
<draw_circle>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rdi,-0x30(%rsp)
cvttss2si %xmm0,%edi
test   %edi,%edi
js     1420 <draw_circle+0x320>
mov    %edi,%ebp
neg    %ebp
mov    %edi,%r11d
imul   %edi,%r11d
lea    0x1(%rdi),%eax
movslq %ebp,%r12
movslq %r8d,%r14
movslq %esi,%r8
movslq %edx,%rdx
mov    %rdx,-0x38(%rsp)
lea    (%rdi,%rdi,1),%r10d
mov    %ecx,%edx
not    %edx
add    %edi,%edx
mov    %edx,-0x44(%rsp)
mov    %r10d,%edx
and    $0xfffffff8,%edx
mov    %edx,-0x48(%rsp)
movd   %r12d,%xmm0
pshufd $0x0,%xmm0,%xmm0
movdqa 0xe9c(%rip),%xmm1
paddd  %xmm0,%xmm1
movdqa %xmm1,-0x28(%rsp)
paddd  0xe9a(%rip),%xmm0
movdqa %xmm0,-0x18(%rsp)
sub    %edi,%edx
mov    %edx,-0x4c(%rsp)
movd   %r11d,%xmm0
pshufd $0x0,%xmm0,%xmm15
movd   %ecx,%xmm0
pshufd $0x0,%xmm0,%xmm3
movd   %r8d,%xmm0
pshufd $0x0,%xmm0,%xmm10
movdqa 0xe76(%rip),%xmm11
pxor   %xmm11,%xmm15
pcmpeqd %xmm12,%xmm12
movdqa 0xe83(%rip),%xmm13
mov    %r8,-0x40(%rsp)
jmp    11dd <draw_circle+0xdd>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
add    $0x1,%r12
cmp    %r12d,%eax
je     1420 <draw_circle+0x320>
mov    %r12d,%r13d
imul   %r12d,%r13d
mov    %r12,%rbx
add    %r14,%rbx
sets   %dl
cmp    -0x38(%rsp),%rbx
setge  %r15b
imul   %r8,%rbx
add    -0x30(%rsp),%rbx
or     %dl,%r15b
mov    %ebp,%edi
cmp    $0x8,%r10d
jb     13fb <draw_circle+0x2fb>
mov    %ebp,%edi
cmp    %r10d,-0x44(%rsp)
jb     13fb <draw_circle+0x2fb>
movd   %r13d,%xmm0
pshufd $0x0,%xmm0,%xmm0
movzbl %r15b,%edx
movd   %edx,%xmm1
pshuflw $0x0,%xmm1,%xmm1
pshufd $0x0,%xmm1,%xmm14
mov    -0x48(%rsp),%r8d
movdqa -0x18(%rsp),%xmm9
movdqa -0x28(%rsp),%xmm1
jmp    1264 <draw_circle+0x164>
nopl   0x0(%rax)
paddd  %xmm13,%xmm9
paddd  %xmm13,%xmm1
add    $0xfffffff8,%r8d
je     13e0 <draw_circle+0x2e0>
movdqa %xmm9,%xmm4
pmuludq %xmm9,%xmm4
pshufd $0xe8,%xmm4,%xmm8
pshufd $0xf5,%xmm9,%xmm4
pmuludq %xmm4,%xmm4
pshufd $0xe8,%xmm4,%xmm4
punpckldq %xmm4,%xmm8
movdqa %xmm1,%xmm4
pmuludq %xmm1,%xmm4
pshufd $0xe8,%xmm4,%xmm4
pshufd $0xf5,%xmm1,%xmm5
pmuludq %xmm5,%xmm5
pshufd $0xe8,%xmm5,%xmm5
punpckldq %xmm5,%xmm4
paddd  %xmm0,%xmm4
paddd  %xmm0,%xmm8
pxor   %xmm11,%xmm8
pcmpgtd %xmm15,%xmm8
pxor   %xmm11,%xmm4
pcmpgtd %xmm15,%xmm4
packssdw %xmm4,%xmm8
por    %xmm14,%xmm8
pxor   0xd59(%rip),%xmm8
movdqa %xmm1,%xmm6
paddd  %xmm3,%xmm6
movdqa %xmm9,%xmm2
paddd  %xmm3,%xmm2
movdqa %xmm2,%xmm5
pcmpgtd %xmm12,%xmm5
movdqa %xmm6,%xmm4
pcmpgtd %xmm12,%xmm4
packssdw %xmm4,%xmm5
movdqa %xmm10,%xmm4
pcmpgtd %xmm2,%xmm4
movdqa %xmm10,%xmm7
pcmpgtd %xmm6,%xmm7
packssdw %xmm7,%xmm4
pand   %xmm5,%xmm4
pand   %xmm8,%xmm4
movd   %xmm4,%edi
test   $0x1,%dil
je     132f <draw_circle+0x22f>
movd   %xmm2,%edx
mov    %r9b,(%rbx,%rdx,1)
shr    $0x10,%edi
test   $0x1,%dil
je     1345 <draw_circle+0x245>
pshufd $0x55,%xmm2,%xmm5
movd   %xmm5,%edx
mov    %r9b,(%rbx,%rdx,1)
pextrw $0x2,%xmm4,%edx
test   $0x1,%dl
je     135c <draw_circle+0x25c>
pshufd $0xee,%xmm2,%xmm5
movd   %xmm5,%edx
mov    %r9b,(%rbx,%rdx,1)
pextrw $0x3,%xmm4,%edx
test   $0x1,%dl
je     1373 <draw_circle+0x273>
pshufd $0xff,%xmm2,%xmm2
movd   %xmm2,%edx
mov    %r9b,(%rbx,%rdx,1)
pextrw $0x4,%xmm4,%edx
test   $0x1,%dl
je     1385 <draw_circle+0x285>
movd   %xmm6,%edx
mov    %r9b,(%rbx,%rdx,1)
pextrw $0x5,%xmm4,%edx
test   $0x1,%dl
je     139c <draw_circle+0x29c>
pshufd $0x55,%xmm6,%xmm2
movd   %xmm2,%edx
mov    %r9b,(%rbx,%rdx,1)
pextrw $0x6,%xmm4,%edx
test   $0x1,%dl
je     13b3 <draw_circle+0x2b3>
pshufd $0xee,%xmm6,%xmm2
movd   %xmm2,%edx
mov    %r9b,(%rbx,%rdx,1)
pextrw $0x7,%xmm4,%edx
test   $0x1,%dl
je     1250 <draw_circle+0x150>
pshufd $0xff,%xmm6,%xmm2
movd   %xmm2,%edx
mov    %r9b,(%rbx,%rdx,1)
jmp    1250 <draw_circle+0x150>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    -0x4c(%rsp),%edi
mov    -0x40(%rsp),%r8
jmp    13fb <draw_circle+0x2fb>
nopl   0x0(%rax,%rax,1)
add    $0x1,%edi
cmp    %edi,%eax
je     11d0 <draw_circle+0xd0>
mov    %edi,%edx
imul   %edi,%edx
add    %r13d,%edx
cmp    %r11d,%edx
seta   %dl
or     %r15b,%dl
jne    13f0 <draw_circle+0x2f0>
mov    %ecx,%edx
add    %edi,%edx
js     13f0 <draw_circle+0x2f0>
cmp    %esi,%edx
jge    13f0 <draw_circle+0x2f0>
mov    %edx,%edx
mov    %r9b,(%rbx,%rdx,1)
jmp    13f0 <draw_circle+0x2f0>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @draw_circle(i8* %0, i32 %1, i32 %2, i32 %3, i32 %4, float %5, i8 signext %6) {
%8 = alloca i8*
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca float
%14 = alloca i8
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
store i8* %0, i8** %8
store i32 %1, i32* %9
store i32 %2, i32* %10
store i32 %3, i32* %11
store i32 %4, i32* %12
store float %5, float* %13
store i8 %6, i8* %14
%18 = load float, float* %13
%19 = fptosi float %18 to i32
store i32 %19, i32* %17
%20 = load i32, i32* %17
%21 = sub nsw i32 0, %20
store i32 %21, i32* %16
br label %22
22: ; preds = %88, %7
%23 = load i32, i32* %16
%24 = load i32, i32* %17
%25 = icmp sle i32 %23, %24
br i1 %25, label %26, label %91
26: ; preds = %22
%27 = load i32, i32* %17
%28 = sub nsw i32 0, %27
store i32 %28, i32* %15
br label %29
29: ; preds = %84, %26
%30 = load i32, i32* %15
%31 = load i32, i32* %17
%32 = icmp sle i32 %30, %31
br i1 %32, label %33, label %87
33: ; preds = %29
%34 = load i32, i32* %15
%35 = load i32, i32* %15
%36 = mul nsw i32 %34, %35
%37 = load i32, i32* %16
%38 = load i32, i32* %16
%39 = mul nsw i32 %37, %38
%40 = add nsw i32 %36, %39
%41 = load i32, i32* %17
%42 = load i32, i32* %17
%43 = mul nsw i32 %41, %42
%44 = icmp sle i32 %40, %43
br i1 %44, label %45, label %83
45: ; preds = %33
%46 = load i32, i32* %16
%47 = load i32, i32* %12
%48 = add nsw i32 %46, %47
%49 = icmp sge i32 %48, 0
br i1 %49, label %50, label %82
50: ; preds = %45
%51 = load i32, i32* %16
%52 = load i32, i32* %12
%53 = add nsw i32 %51, %52
%54 = load i32, i32* %10
%55 = icmp slt i32 %53, %54
br i1 %55, label %56, label %82
56: ; preds = %50
%57 = load i32, i32* %15
%58 = load i32, i32* %11
%59 = add nsw i32 %57, %58
%60 = icmp sge i32 %59, 0
br i1 %60, label %61, label %82
61: ; preds = %56
%62 = load i32, i32* %15
%63 = load i32, i32* %11
%64 = add nsw i32 %62, %63
%65 = load i32, i32* %9
%66 = icmp slt i32 %64, %65
br i1 %66, label %67, label %82
67: ; preds = %61
%68 = load i8, i8* %14
%69 = load i8*, i8** %8
%70 = load i32, i32* %16
%71 = load i32, i32* %12
%72 = add nsw i32 %70, %71
%73 = load i32, i32* %9
%74 = mul nsw i32 %72, %73
%75 = sext i32 %74 to i64
%76 = getelementptr inbounds i8, i8* %69, i64 %75
%77 = load i32, i32* %15
%78 = load i32, i32* %11
%79 = add nsw i32 %77, %78
%80 = sext i32 %79 to i64
%81 = getelementptr inbounds i8, i8* %76, i64 %80
store i8 %68, i8* %81
br label %82
82: ; preds = %67, %61, %56, %50, %45
br label %83
83: ; preds = %82, %33
br label %84
84: ; preds = %83
%85 = load i32, i32* %15
%86 = add nsw i32 %85, 1
store i32 %86, i32* %15
br label %29
87: ; preds = %29
br label %88
88: ; preds = %87
%89 = load i32, i32* %16
%90 = add nsw i32 %89, 1
store i32 %90, i32* %16
br label %22
91: ; preds = %22
ret void
}

LLVM IR (-O2):
define void @draw_circle(i8* nocapture writeonly %0, i32 %1, i32 %2, i32 %3, i32 %4, float %5, i8 signext %6) {
%8 = fptosi float %5 to i32
%9 = sub i32 0, %8
%10 = icmp slt i32 %8, 0
br i1 %10, label %137, label %11
11: ; preds = %7
%12 = mul nsw i32 %8, %8
%13 = add nuw i32 %8, 1
%14 = sext i32 %9 to i64
%15 = sext i32 %4 to i64
%16 = sext i32 %1 to i64
%17 = sext i32 %2 to i64
%18 = shl i32 %8, 1
%19 = icmp ult i32 %18, 8
%20 = xor i32 %3, -1
%21 = add i32 %20, %8
%22 = icmp ult i32 %21, %18
%23 = and i32 %18, -8
%24 = sub i32 %23, %8
%25 = insertelement <8 x i32> poison, i32 %9, i64 0
%26 = shufflevector <8 x i32> %25, <8 x i32> poison, <8 x i32> zeroinitializer
%27 = add <8 x i32> %26, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
%28 = insertelement <8 x i32> poison, i32 %12, i64 0
%29 = shufflevector <8 x i32> %28, <8 x i32> poison, <8 x i32> zeroinitializer
%30 = insertelement <8 x i32> poison, i32 %3, i64 0
%31 = shufflevector <8 x i32> %30, <8 x i32> poison, <8 x i32> zeroinitializer
%32 = insertelement <8 x i32> poison, i32 %1, i64 0
%33 = shufflevector <8 x i32> %32, <8 x i32> poison, <8 x i32> zeroinitializer
br label %34
34: ; preds = %133, %11
%35 = phi i64 [ %14, %11 ], [ %134, %133 ]
%36 = mul nsw i64 %35, %35
%37 = add nsw i64 %35, %15
%38 = icmp slt i64 %37, 0
%39 = icmp sge i64 %37, %17
%40 = mul nsw i64 %37, %16
%41 = getelementptr inbounds i8, i8* %0, i64 %40
%42 = trunc i64 %36 to i32
%43 = or i1 %38, %39
%44 = or i1 %19, %22
br i1 %44, label %114, label %45
45: ; preds = %34
%46 = insertelement <8 x i32> poison, i32 %42, i64 0
%47 = shufflevector <8 x i32> %46, <8 x i32> poison, <8 x i32> zeroinitializer
%48 = insertelement <8 x i1> poison, i1 %43, i64 0
%49 = shufflevector <8 x i1> %48, <8 x i1> poison, <8 x i32> zeroinitializer
br label %50
50: ; preds = %110, %45
%51 = phi i32 [ 0, %45 ], [ %111, %110 ]
%52 = phi <8 x i32> [ %27, %45 ], [ %112, %110 ]
%53 = mul nsw <8 x i32> %52, %52
%54 = add nuw nsw <8 x i32> %53, %47
%55 = icmp ugt <8 x i32> %54, %29
%56 = select <8 x i1> %55, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i1> %49
%57 = add nsw <8 x i32> %52, %31
%58 = icmp sgt <8 x i32> %57, <i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1, i32 -1>
%59 = icmp slt <8 x i32> %57, %33
%60 = and <8 x i1> %58, %59
%61 = xor <8 x i1> %56, <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>
%62 = select <8 x i1> %61, <8 x i1> %60, <8 x i1> zeroinitializer
%63 = extractelement <8 x i1> %62, i64 0
br i1 %63, label %64, label %68
64: ; preds = %50
%65 = extractelement <8 x i32> %57, i64 0
%66 = zext i32 %65 to i64
%67 = getelementptr inbounds i8, i8* %41, i64 %66
store i8 %6, i8* %67
br label %68
68: ; preds = %64, %50
%69 = extractelement <8 x i1> %62, i64 1
br i1 %69, label %70, label %74
70: ; preds = %68
%71 = extractelement <8 x i32> %57, i64 1
%72 = zext i32 %71 to i64
%73 = getelementptr inbounds i8, i8* %41, i64 %72
store i8 %6, i8* %73
br label %74
74: ; preds = %70, %68
%75 = extractelement <8 x i1> %62, i64 2
br i1 %75, label %76, label %80
76: ; preds = %74
%77 = extractelement <8 x i32> %57, i64 2
%78 = zext i32 %77 to i64
%79 = getelementptr inbounds i8, i8* %41, i64 %78
store i8 %6, i8* %79
br label %80
80: ; preds = %76, %74
%81 = extractelement <8 x i1> %62, i64 3
br i1 %81, label %82, label %86
82: ; preds = %80
%83 = extractelement <8 x i32> %57, i64 3
%84 = zext i32 %83 to i64
%85 = getelementptr inbounds i8, i8* %41, i64 %84
store i8 %6, i8* %85
br label %86
86: ; preds = %82, %80
%87 = extractelement <8 x i1> %62, i64 4
br i1 %87, label %88, label %92
88: ; preds = %86
%89 = extractelement <8 x i32> %57, i64 4
%90 = zext i32 %89 to i64
%91 = getelementptr inbounds i8, i8* %41, i64 %90
store i8 %6, i8* %91
br label %92
92: ; preds = %88, %86
%93 = extractelement <8 x i1> %62, i64 5
br i1 %93, label %94, label %98
94: ; preds = %92
%95 = extractelement <8 x i32> %57, i64 5
%96 = zext i32 %95 to i64
%97 = getelementptr inbounds i8, i8* %41, i64 %96
store i8 %6, i8* %97
br label %98
98: ; preds = %94, %92
%99 = extractelement <8 x i1> %62, i64 6
br i1 %99, label %100, label %104
100: ; preds = %98
%101 = extractelement <8 x i32> %57, i64 6
%102 = zext i32 %101 to i64
%103 = getelementptr inbounds i8, i8* %41, i64 %102
store i8 %6, i8* %103
br label %104
104: ; preds = %100, %98
%105 = extractelement <8 x i1> %62, i64 7
br i1 %105, label %106, label %110
106: ; preds = %104
%107 = extractelement <8 x i32> %57, i64 7
%108 = zext i32 %107 to i64
%109 = getelementptr inbounds i8, i8* %41, i64 %108
store i8 %6, i8* %109
br label %110
110: ; preds = %106, %104
%111 = add nuw i32 %51, 8
%112 = add <8 x i32> %52, <i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8, i32 8>
%113 = icmp eq i32 %111, %23
br i1 %113, label %114, label %50
114: ; preds = %110, %34
%115 = phi i32 [ %9, %34 ], [ %24, %110 ]
br label %116
116: ; preds = %114, %130
%117 = phi i32 [ %131, %130 ], [ %115, %114 ]
%118 = mul nsw i32 %117, %117
%119 = add nuw nsw i32 %118, %42
%120 = icmp ugt i32 %119, %12
%121 = select i1 %120, i1 true, i1 %43
br i1 %121, label %130, label %122
122: ; preds = %116
%123 = add nsw i32 %117, %3
%124 = icmp sgt i32 %123, -1
%125 = icmp slt i32 %123, %1
%126 = and i1 %124, %125
br i1 %126, label %127, label %130
127: ; preds = %122
%128 = zext i32 %123 to i64
%129 = getelementptr inbounds i8, i8* %41, i64 %128
store i8 %6, i8* %129
br label %130
130: ; preds = %116, %127, %122
%131 = add i32 %117, 1
%132 = icmp eq i32 %117, %8
br i1 %132, label %133, label %116
133: ; preds = %130
%134 = add nsw i64 %35, 1
%135 = trunc i64 %134 to i32
%136 = icmp eq i32 %13, %135
br i1 %136, label %137, label %34
137: ; preds = %133, %7
ret void
}