void draw_hist(int *bin, int max) {
  int i, j, sum, amax, ncol = 256, nrow = 256, *sbin;
  short int *hist;
  sbin = (int *)malloc(ncol * sizeof(int));
  hist = (short int *)malloc(ncol * nrow * sizeof(short int));
  amax = 0;
  for (i = 0; i < 4096; i += (4096 / ncol)) {
    sum = 0;
    for (j = 0; j < (4096 / ncol); ++j)
      sum += *(bin + i + j);
    *(sbin + i * ncol / 4096) = sum;
    if (sum > amax)
      amax = sum;
  }
  if (max != 0)
    amax = max;
  for (i = 0; i < ncol; ++i) {
    for (j = 0; j < nrow; ++j) {
      if (j <= (*(sbin + i) * (nrow - 1) / amax))
        *(hist + i + ncol * j) = 4096 - 1;
      else
        *(hist + i + ncol * j) = 0;
    }
  }
  put_image((unsigned char *)hist, "hist.img", 2 * ncol * nrow);
  free(hist);
  free(sbin);
}


x86 assembly (clang, -O0):
<draw_hist>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movl   $0x100,-0x20(%rbp)
movl   $0x100,-0x24(%rbp)
movslq -0x20(%rbp),%rdi
shl    $0x2,%rdi
call   1050 <malloc@plt>
mov    %rax,-0x30(%rbp)
mov    -0x20(%rbp),%eax
imul   -0x24(%rbp),%eax
movslq %eax,%rdi
shl    $0x1,%rdi
call   1050 <malloc@plt>
mov    %rax,-0x38(%rbp)
movl   $0x0,-0x1c(%rbp)
movl   $0x0,-0x10(%rbp)
cmpl   $0x1000,-0x10(%rbp)
jge    123b <draw_hist+0x10b>
movl   $0x0,-0x18(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x3c(%rbp)
mov    $0x1000,%eax
cltd
idivl  -0x20(%rbp)
mov    %eax,%ecx
mov    -0x3c(%rbp),%eax
cmp    %ecx,%eax
jge    11e4 <draw_hist+0xb4>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
add    -0x18(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    119e <draw_hist+0x6e>
mov    -0x18(%rbp),%eax
mov    %eax,-0x4c(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x10(%rbp),%eax
imul   -0x20(%rbp),%eax
mov    $0x1000,%ecx
cltd
idiv   %ecx
mov    -0x4c(%rbp),%edx
mov    %eax,%ecx
mov    -0x48(%rbp),%rax
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x18(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jle    1222 <draw_hist+0xf2>
mov    -0x18(%rbp),%eax
mov    %eax,-0x1c(%rbp)
jmp    1227 <draw_hist+0xf7>
mov    $0x1000,%eax
cltd
idivl  -0x20(%rbp)
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
jmp    1183 <draw_hist+0x53>
cmpl   $0x0,-0xc(%rbp)
je     124b <draw_hist+0x11b>
mov    -0xc(%rbp),%eax
mov    %eax,-0x1c(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1305 <draw_hist+0x1d5>
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    12f2 <draw_hist+0x1c2>
mov    -0x14(%rbp),%eax
mov    %eax,-0x50(%rbp)
mov    -0x30(%rbp),%rax
movslq -0x10(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    -0x24(%rbp),%ecx
sub    $0x1,%ecx
imul   %ecx,%eax
cltd
idivl  -0x1c(%rbp)
mov    %eax,%ecx
mov    -0x50(%rbp),%eax
cmp    %ecx,%eax
jg     12c0 <draw_hist+0x190>
mov    -0x38(%rbp),%rax
movslq -0x10(%rbp),%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    -0x20(%rbp),%ecx
imul   -0x14(%rbp),%ecx
movslq %ecx,%rcx
movw   $0xfff,(%rax,%rcx,2)
jmp    12df <draw_hist+0x1af>
mov    -0x38(%rbp),%rax
movslq -0x10(%rbp),%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    -0x20(%rbp),%ecx
imul   -0x14(%rbp),%ecx
movslq %ecx,%rcx
movw   $0x0,(%rax,%rcx,2)
jmp    12e4 <draw_hist+0x1b4>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1265 <draw_hist+0x135>
jmp    12f7 <draw_hist+0x1c7>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    1252 <draw_hist+0x122>
mov    -0x38(%rbp),%rdi
mov    -0x20(%rbp),%edx
shl    $0x1,%edx
imul   -0x24(%rbp),%edx
lea    0xce6(%rip),%rsi
mov    $0x0,%al
call   1040 <put_image@plt>
mov    -0x38(%rbp),%rdi
call   1030 <free@plt>
mov    -0x30(%rbp),%rdi
call   1030 <free@plt>
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<draw_hist>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %esi,%r15d
mov    %rdi,%rbp
mov    $0x400,%edi
call   1050 <malloc@plt>
mov    %rax,%r12
mov    $0x20000,%edi
call   1050 <malloc@plt>
mov    %rax,%r14
mov    %r12,%rax
add    $0x4,%rax
xor    %ecx,%ecx
mov    $0xfffffffffffffff0,%rdx
nopl   0x0(%rax,%rax,1)
movdqu 0x40(%rbp,%rdx,4),%xmm0
movdqu 0x50(%rbp,%rdx,4),%xmm1
movdqu 0x60(%rbp,%rdx,4),%xmm2
paddd  %xmm0,%xmm2
movdqu 0x70(%rbp,%rdx,4),%xmm0
paddd  %xmm1,%xmm0
paddd  %xmm2,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddd  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddd  %xmm1,%xmm0
movd   %xmm0,%esi
cmp    %ecx,%esi
cmovg  %esi,%ecx
movd   %xmm0,-0x4(%rax)
movdqu 0x80(%rbp,%rdx,4),%xmm0
movdqu 0x90(%rbp,%rdx,4),%xmm1
movdqu 0xa0(%rbp,%rdx,4),%xmm2
paddd  %xmm0,%xmm2
movdqu 0xb0(%rbp,%rdx,4),%xmm0
paddd  %xmm1,%xmm0
paddd  %xmm2,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddd  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddd  %xmm1,%xmm0
movd   %xmm0,%esi
cmp    %ecx,%esi
cmovg  %esi,%ecx
movd   %xmm0,(%rax)
add    $0x20,%rdx
add    $0x8,%rax
cmp    $0xff0,%rdx
jb     1170 <draw_hist+0x40>
test   %r15d,%r15d
cmovne %r15d,%ecx
mov    %r14,%r8
add    $0x600,%r8
xor    %edi,%edi
mov    $0xfff,%ebp
xor    %r9d,%r9d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    (%r12,%r9,4),%edx
mov    %edx,%eax
shl    $0x8,%eax
sub    %edx,%eax
cltd
idiv   %ecx
cltq
mov    %r8,%rdx
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nop
cmp    %rax,%rsi
mov    $0xfff,%ebx
cmovg  %edi,%ebx
mov    %bx,-0x600(%rdx)
mov    $0x0,%ebx
cmovl  %ebp,%ebx
mov    %bx,-0x400(%rdx)
lea    0x2(%rsi),%rbx
cmp    %rax,%rbx
mov    $0xfff,%ebx
cmovg  %edi,%ebx
mov    %bx,-0x200(%rdx)
lea    0x3(%rsi),%rbx
cmp    %rax,%rbx
mov    $0xfff,%ebx
cmovg  %edi,%ebx
mov    %bx,(%rdx)
add    $0x800,%rdx
add    $0x4,%rsi
cmp    $0x100,%rsi
jne    1260 <draw_hist+0x130>
add    $0x1,%r9
add    $0x2,%r8
cmp    $0x100,%r9
jne    1240 <draw_hist+0x110>
lea    0xd27(%rip),%rsi
mov    %r14,%rdi
mov    $0x20000,%edx
xor    %eax,%eax
call   1040 <put_image@plt>
mov    %r14,%rdi
call   1030 <free@plt>
mov    %r12,%rdi
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <free@plt>

LLVM IR (-O0):
@.str = [9 x i8] c"hist.img\00"
define void @draw_hist(i32* %0, i32 %1) {
%3 = alloca i32*
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32*
%12 = alloca i16*
store i32* %0, i32** %3
store i32 %1, i32* %4
store i32 256, i32* %9
store i32 256, i32* %10
%13 = load i32, i32* %9
%14 = sext i32 %13 to i64
%15 = mul i64 %14, 4
%16 = call i8* @malloc(i64 %15)
%17 = bitcast i8* %16 to i32*
store i32* %17, i32** %11
%18 = load i32, i32* %9
%19 = load i32, i32* %10
%20 = mul nsw i32 %18, %19
%21 = sext i32 %20 to i64
%22 = mul i64 %21, 2
%23 = call i8* @malloc(i64 %22)
%24 = bitcast i8* %23 to i16*
store i16* %24, i16** %12
store i32 0, i32* %8
store i32 0, i32* %5
br label %25
25: ; preds = %63, %2
%26 = load i32, i32* %5
%27 = icmp slt i32 %26, 4096
br i1 %27, label %28, label %68
28: ; preds = %25
store i32 0, i32* %7
store i32 0, i32* %6
br label %29
29: ; preds = %45, %28
%30 = load i32, i32* %6
%31 = load i32, i32* %9
%32 = sdiv i32 4096, %31
%33 = icmp slt i32 %30, %32
br i1 %33, label %34, label %48
34: ; preds = %29
%35 = load i32*, i32** %3
%36 = load i32, i32* %5
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds i32, i32* %35, i64 %37
%39 = load i32, i32* %6
%40 = sext i32 %39 to i64
%41 = getelementptr inbounds i32, i32* %38, i64 %40
%42 = load i32, i32* %41
%43 = load i32, i32* %7
%44 = add nsw i32 %43, %42
store i32 %44, i32* %7
br label %45
45: ; preds = %34
%46 = load i32, i32* %6
%47 = add nsw i32 %46, 1
store i32 %47, i32* %6
br label %29
48: ; preds = %29
%49 = load i32, i32* %7
%50 = load i32*, i32** %11
%51 = load i32, i32* %5
%52 = load i32, i32* %9
%53 = mul nsw i32 %51, %52
%54 = sdiv i32 %53, 4096
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds i32, i32* %50, i64 %55
store i32 %49, i32* %56
%57 = load i32, i32* %7
%58 = load i32, i32* %8
%59 = icmp sgt i32 %57, %58
br i1 %59, label %60, label %62
60: ; preds = %48
%61 = load i32, i32* %7
store i32 %61, i32* %8
br label %62
62: ; preds = %60, %48
br label %63
63: ; preds = %62
%64 = load i32, i32* %9
%65 = sdiv i32 4096, %64
%66 = load i32, i32* %5
%67 = add nsw i32 %66, %65
store i32 %67, i32* %5
br label %25
68: ; preds = %25
%69 = load i32, i32* %4
%70 = icmp ne i32 %69, 0
br i1 %70, label %71, label %73
71: ; preds = %68
%72 = load i32, i32* %4
store i32 %72, i32* %8
br label %73
73: ; preds = %71, %68
store i32 0, i32* %5
br label %74
74: ; preds = %121, %73
%75 = load i32, i32* %5
%76 = load i32, i32* %9
%77 = icmp slt i32 %75, %76
br i1 %77, label %78, label %124
78: ; preds = %74
store i32 0, i32* %6
br label %79
79: ; preds = %117, %78
%80 = load i32, i32* %6
%81 = load i32, i32* %10
%82 = icmp slt i32 %80, %81
br i1 %82, label %83, label %120
83: ; preds = %79
%84 = load i32, i32* %6
%85 = load i32*, i32** %11
%86 = load i32, i32* %5
%87 = sext i32 %86 to i64
%88 = getelementptr inbounds i32, i32* %85, i64 %87
%89 = load i32, i32* %88
%90 = load i32, i32* %10
%91 = sub nsw i32 %90, 1
%92 = mul nsw i32 %89, %91
%93 = load i32, i32* %8
%94 = sdiv i32 %92, %93
%95 = icmp sle i32 %84, %94
br i1 %95, label %96, label %106
96: ; preds = %83
%97 = load i16*, i16** %12
%98 = load i32, i32* %5
%99 = sext i32 %98 to i64
%100 = getelementptr inbounds i16, i16* %97, i64 %99
%101 = load i32, i32* %9
%102 = load i32, i32* %6
%103 = mul nsw i32 %101, %102
%104 = sext i32 %103 to i64
%105 = getelementptr inbounds i16, i16* %100, i64 %104
store i16 4095, i16* %105
br label %116
106: ; preds = %83
%107 = load i16*, i16** %12
%108 = load i32, i32* %5
%109 = sext i32 %108 to i64
%110 = getelementptr inbounds i16, i16* %107, i64 %109
%111 = load i32, i32* %9
%112 = load i32, i32* %6
%113 = mul nsw i32 %111, %112
%114 = sext i32 %113 to i64
%115 = getelementptr inbounds i16, i16* %110, i64 %114
store i16 0, i16* %115
br label %116
116: ; preds = %106, %96
br label %117
117: ; preds = %116
%118 = load i32, i32* %6
%119 = add nsw i32 %118, 1
store i32 %119, i32* %6
br label %79
120: ; preds = %79
br label %121
121: ; preds = %120
%122 = load i32, i32* %5
%123 = add nsw i32 %122, 1
store i32 %123, i32* %5
br label %74
124: ; preds = %74
%125 = load i16*, i16** %12
%126 = bitcast i16* %125 to i8*
%127 = load i32, i32* %9
%128 = mul nsw i32 2, %127
%129 = load i32, i32* %10
%130 = mul nsw i32 %128, %129
%131 = call i32 (i8*, i8*, i32, ...) bitcast (i32 (...)* @put_image to i32 (i8*, i8*, i32, ...)*)(i8* %126, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i32 %130)
%132 = load i16*, i16** %12
%133 = bitcast i16* %132 to i8*
%134 = load i32*, i32** %11
%135 = bitcast i32* %134 to i8*
ret void
}

LLVM IR (-O2):
@.str = [9 x i8] c"hist.img\00"
define void @draw_hist(i32* nocapture %0, i32 %1) {
%3 = tail call dereferenceable_or_null(1024) i8* @malloc(i64 1024)
%4 = bitcast i8* %3 to i32*
%5 = tail call dereferenceable_or_null(131072) i8* @malloc(i64 131072)
br label %6
6: ; preds = %6, %2
%7 = phi i64 [ 0, %2 ], [ %26, %6 ]
%8 = phi i32 [ 0, %2 ], [ %25, %6 ]
%9 = getelementptr inbounds i32, i32* %0, i64 %7
%10 = bitcast i32* %9 to <16 x i32>*
%11 = load <16 x i32>, <16 x i32>* %10
%12 = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %11)
%13 = lshr exact i64 %7, 4
%14 = getelementptr inbounds i32, i32* %4, i64 %13
store i32 %12, i32* %14
%15 = icmp sgt i32 %12, %8
%16 = select i1 %15, i32 %12, i32 %8
%17 = or i64 %7, 16
%18 = getelementptr inbounds i32, i32* %0, i64 %17
%19 = bitcast i32* %18 to <16 x i32>*
%20 = load <16 x i32>, <16 x i32>* %19
%21 = call i32 @llvm.vector.reduce.add.v16i32(<16 x i32> %20)
%22 = lshr exact i64 %17, 4
%23 = getelementptr inbounds i32, i32* %4, i64 %22
store i32 %21, i32* %23
%24 = icmp sgt i32 %21, %16
%25 = select i1 %24, i32 %21, i32 %16
%26 = add nuw nsw i64 %7, 32
%27 = icmp ult i64 %17, 4080
br i1 %27, label %6, label %28
28: ; preds = %6
%29 = bitcast i8* %5 to i16*
%30 = icmp eq i32 %1, 0
%31 = select i1 %30, i32 %25, i32 %1
br label %32
32: ; preds = %28, %63
%33 = phi i64 [ 0, %28 ], [ %64, %63 ]
%34 = getelementptr inbounds i32, i32* %4, i64 %33
%35 = load i32, i32* %34
%36 = mul nsw i32 %35, 255
%37 = sdiv i32 %36, %31
%38 = getelementptr inbounds i16, i16* %29, i64 %33
%39 = sext i32 %37 to i64
br label %40
40: ; preds = %40, %32
%41 = phi i64 [ 0, %32 ], [ %61, %40 ]
%42 = icmp sgt i64 %41, %39
%43 = shl nuw nsw i64 %41, 8
%44 = getelementptr inbounds i16, i16* %38, i64 %43
%45 = select i1 %42, i16 0, i16 4095
store i16 %45, i16* %44
%46 = icmp slt i64 %41, %39
%47 = shl i64 %41, 8
%48 = or i64 %47, 256
%49 = getelementptr inbounds i16, i16* %38, i64 %48
%50 = select i1 %46, i16 4095, i16 0
store i16 %50, i16* %49
%51 = or i64 %41, 2
%52 = icmp sgt i64 %51, %39
%53 = shl nuw nsw i64 %51, 8
%54 = getelementptr inbounds i16, i16* %38, i64 %53
%55 = select i1 %52, i16 0, i16 4095
store i16 %55, i16* %54
%56 = or i64 %41, 3
%57 = icmp sgt i64 %56, %39
%58 = shl nuw nsw i64 %56, 8
%59 = getelementptr inbounds i16, i16* %38, i64 %58
%60 = select i1 %57, i16 0, i16 4095
store i16 %60, i16* %59
%61 = add nuw nsw i64 %41, 4
%62 = icmp eq i64 %61, 256
br i1 %62, label %63, label %40
63: ; preds = %40
%64 = add nuw nsw i64 %33, 1
%65 = icmp eq i64 %64, 256
br i1 %65, label %66, label %32
66: ; preds = %63
%67 = tail call i32 (i8*, i8*, i32, ...) bitcast (i32 (...)* @put_image to i32 (i8*, i8*, i32, ...)*)(i8* %5, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str, i64 0, i64 0), i32 131072)
tail call void @free(i8* %5)
tail call void @free(i8* %3)
ret void
}