void edtaa3(int width, int height, const float *input, float *output) {
  const int pixels = width * height;
  short *xdist = (short *)malloc(pixels * sizeof(short));
  short *ydist = (short *)malloc(pixels * sizeof(short));
  float *gx = (float *)malloc(pixels * sizeof(float));
  float *gy = (float *)malloc(pixels * sizeof(float));
  computegradient(input, width, height, gx, gy);
  edtaa3_transform(input, gx, gy, width, height, xdist, ydist, output);
  for (int i = 0; i < pixels; i++)
    if (output[i] < 0)
      output[i] = 0;
  free(xdist);
  free(ydist);
  free(gx);
  free(gy);
}


x86 assembly (clang, -O0):
<edtaa3>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %rdx,-0x10(%rbp)
mov    %rcx,-0x18(%rbp)
mov    -0x4(%rbp),%eax
imul   -0x8(%rbp),%eax
mov    %eax,-0x1c(%rbp)
movslq -0x1c(%rbp),%rdi
shl    $0x1,%rdi
call   1060 <malloc@plt>
mov    %rax,-0x28(%rbp)
movslq -0x1c(%rbp),%rdi
shl    $0x1,%rdi
call   1060 <malloc@plt>
mov    %rax,-0x30(%rbp)
movslq -0x1c(%rbp),%rdi
shl    $0x2,%rdi
call   1060 <malloc@plt>
mov    %rax,-0x38(%rbp)
movslq -0x1c(%rbp),%rdi
shl    $0x2,%rdi
call   1060 <malloc@plt>
mov    %rax,-0x40(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x4(%rbp),%esi
mov    -0x8(%rbp),%edx
mov    -0x38(%rbp),%rcx
mov    -0x40(%rbp),%r8
mov    $0x0,%al
call   1030 <computegradient@plt>
mov    -0x10(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    -0x40(%rbp),%rdx
mov    -0x4(%rbp),%ecx
mov    -0x8(%rbp),%r8d
mov    -0x28(%rbp),%r9
mov    -0x30(%rbp),%r10
mov    -0x18(%rbp),%rax
mov    %r10,(%rsp)
mov    %rax,0x8(%rsp)
mov    $0x0,%al
call   1050 <edtaa3_transform@plt>
movl   $0x0,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jge    1237 <edtaa3+0xf7>
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
xorps  %xmm0,%xmm0
ucomiss (%rax,%rcx,4),%xmm0
jbe    1224 <edtaa3+0xe4>
mov    -0x18(%rbp),%rax
movslq -0x44(%rbp),%rcx
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax,%rcx,4)
jmp    1229 <edtaa3+0xe9>
mov    -0x44(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
jmp    11f3 <edtaa3+0xb3>
mov    -0x28(%rbp),%rdi
call   1040 <free@plt>
mov    -0x30(%rbp),%rdi
call   1040 <free@plt>
mov    -0x38(%rbp),%rdi
call   1040 <free@plt>
mov    -0x40(%rbp),%rdi
call   1040 <free@plt>
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<edtaa3>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %rcx,%rbx
mov    %rdx,(%rsp)
mov    %esi,%r12d
mov    %esi,0xc(%rsp)
mov    %edi,%r14d
imul   %edi,%r12d
mov    %edi,0x8(%rsp)
movslq %r12d,%rax
lea    (%rax,%rax,1),%rbp
mov    %rax,%r15
mov    %rax,0x20(%rsp)
mov    %rbp,%rdi
call   1060 <malloc@plt>
mov    %rax,0x18(%rsp)
mov    %rbp,%rdi
call   1060 <malloc@plt>
mov    %rax,0x10(%rsp)
lea    0x0(,%r15,4),%rbp
mov    %rbp,%rdi
call   1060 <malloc@plt>
mov    %rax,%r15
mov    %rbp,%rdi
call   1060 <malloc@plt>
mov    %rax,%r13
mov    (%rsp),%rbp
mov    %rbp,%rdi
mov    %r14d,%esi
mov    0xc(%rsp),%r14d
mov    %r14d,%edx
mov    %r15,%rcx
mov    %rax,%r8
xor    %eax,%eax
call   1030 <computegradient@plt>
mov    %rbp,%rdi
mov    %r15,(%rsp)
mov    %r15,%rsi
mov    %r13,%r15
mov    %r13,%rdx
mov    0x8(%rsp),%ecx
mov    0x18(%rsp),%rbp
mov    %r14d,%r8d
mov    0x10(%rsp),%r13
mov    %rbp,%r9
xor    %eax,%eax
push   %rbx
push   %r13
call   1050 <edtaa3_transform@plt>
add    $0x10,%rsp
cmpl   $0x0,0x20(%rsp)
jle    12e7 <edtaa3+0x1a7>
mov    %r12d,%eax
cmp    $0x8,%r12d
jae    121a <edtaa3+0xda>
xor    %ecx,%ecx
jmp    1316 <edtaa3+0x1d6>
mov    %eax,%ecx
and    $0xfffffff8,%ecx
xor    %edx,%edx
xorps  %xmm0,%xmm0
xorps  %xmm1,%xmm1
jmp    123d <edtaa3+0xfd>
nopl   0x0(%rax)
add    $0x8,%rdx
cmp    %rdx,%rcx
je     12e2 <edtaa3+0x1a2>
movups (%rbx,%rdx,4),%xmm2
ucomiss %xmm2,%xmm0
jbe    124d <edtaa3+0x10d>
movl   $0x0,(%rbx,%rdx,4)
cmpltps %xmm1,%xmm2
pextrw $0x2,%xmm2,%esi
test   $0x1,%sil
je     1264 <edtaa3+0x124>
movl   $0x0,0x4(%rbx,%rdx,4)
pextrw $0x4,%xmm2,%esi
test   $0x1,%sil
je     1277 <edtaa3+0x137>
movl   $0x0,0x8(%rbx,%rdx,4)
pextrw $0x6,%xmm2,%esi
test   $0x1,%sil
je     128a <edtaa3+0x14a>
movl   $0x0,0xc(%rbx,%rdx,4)
movups 0x10(%rbx,%rdx,4),%xmm2
ucomiss %xmm2,%xmm0
jbe    129c <edtaa3+0x15c>
movl   $0x0,0x10(%rbx,%rdx,4)
cmpltps %xmm1,%xmm2
pextrw $0x2,%xmm2,%esi
test   $0x1,%sil
je     12b3 <edtaa3+0x173>
movl   $0x0,0x14(%rbx,%rdx,4)
pextrw $0x4,%xmm2,%esi
test   $0x1,%sil
je     12c6 <edtaa3+0x186>
movl   $0x0,0x18(%rbx,%rdx,4)
pextrw $0x6,%xmm2,%esi
test   $0x1,%sil
je     1230 <edtaa3+0xf0>
movl   $0x0,0x1c(%rbx,%rdx,4)
jmp    1230 <edtaa3+0xf0>
cmp    %rax,%rcx
jne    1316 <edtaa3+0x1d6>
mov    %rbp,%rdi
call   1040 <free@plt>
mov    %r13,%rdi
call   1040 <free@plt>
mov    (%rsp),%rdi
call   1040 <free@plt>
mov    %r15,%rdi
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1040 <free@plt>
xorps  %xmm0,%xmm0
jmp    1329 <edtaa3+0x1e9>
nopl   0x0(%rax,%rax,1)
add    $0x1,%rcx
cmp    %rcx,%rax
je     12e7 <edtaa3+0x1a7>
ucomiss (%rbx,%rcx,4),%xmm0
jbe    1320 <edtaa3+0x1e0>
movl   $0x0,(%rbx,%rcx,4)
jmp    1320 <edtaa3+0x1e0>

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

LLVM IR (-O2):
define void @edtaa3(i32 %0, i32 %1, float* %2, float* %3) {
%5 = mul nsw i32 %1, %0
%6 = sext i32 %5 to i64
%7 = shl nsw i64 %6, 1
%8 = tail call i8* @malloc(i64 %7)
%9 = bitcast i8* %8 to i16*
%10 = tail call i8* @malloc(i64 %7)
%11 = bitcast i8* %10 to i16*
%12 = shl nsw i64 %6, 2
%13 = tail call i8* @malloc(i64 %12)
%14 = bitcast i8* %13 to float*
%15 = tail call i8* @malloc(i64 %12)
%16 = bitcast i8* %15 to float*
%17 = tail call i32 (float*, i32, i32, float*, float*, ...) bitcast (i32 (...)* @computegradient to i32 (float*, i32, i32, float*, float*, ...)*)(float* %2, i32 %0, i32 %1, float* %14, float* %16)
%18 = tail call i32 (float*, float*, float*, i32, i32, i16*, i16*, float*, ...) bitcast (i32 (...)* @edtaa3_transform to i32 (float*, float*, float*, i32, i32, i16*, i16*, float*, ...)*)(float* %2, float* %14, float* %16, i32 %0, i32 %1, i16* %9, i16* %11, float* %3)
%19 = icmp sgt i32 %5, 0
br i1 %19, label %20, label %80
20: ; preds = %4
%21 = zext i32 %5 to i64
%22 = icmp ult i32 %5, 8
br i1 %22, label %78, label %23
23: ; preds = %20
%24 = and i64 %21, 4294967288
br label %25
25: ; preds = %73, %23
%26 = phi i64 [ 0, %23 ], [ %74, %73 ]
%27 = or i64 %26, 4
%28 = getelementptr inbounds float, float* %3, i64 %26
%29 = bitcast float* %28 to <4 x float>*
%30 = load <4 x float>, <4 x float>* %29
%31 = getelementptr inbounds float, float* %28, i64 4
%32 = bitcast float* %31 to <4 x float>*
%33 = load <4 x float>, <4 x float>* %32
%34 = fcmp olt <4 x float> %30, zeroinitializer
%35 = fcmp olt <4 x float> %33, zeroinitializer
%36 = extractelement <4 x i1> %34, i64 0
br i1 %36, label %37, label %39
37: ; preds = %25
%38 = getelementptr inbounds float, float* %3, i64 %26
store float 0.000000e+00, float* %38
br label %39
39: ; preds = %37, %25
%40 = extractelement <4 x i1> %34, i64 1
br i1 %40, label %41, label %44
41: ; preds = %39
%42 = or i64 %26, 1
%43 = getelementptr inbounds float, float* %3, i64 %42
store float 0.000000e+00, float* %43
br label %44
44: ; preds = %41, %39
%45 = extractelement <4 x i1> %34, i64 2
br i1 %45, label %46, label %49
46: ; preds = %44
%47 = or i64 %26, 2
%48 = getelementptr inbounds float, float* %3, i64 %47
store float 0.000000e+00, float* %48
br label %49
49: ; preds = %46, %44
%50 = extractelement <4 x i1> %34, i64 3
br i1 %50, label %51, label %54
51: ; preds = %49
%52 = or i64 %26, 3
%53 = getelementptr inbounds float, float* %3, i64 %52
store float 0.000000e+00, float* %53
br label %54
54: ; preds = %51, %49
%55 = extractelement <4 x i1> %35, i64 0
br i1 %55, label %56, label %58
56: ; preds = %54
%57 = getelementptr inbounds float, float* %3, i64 %27
store float 0.000000e+00, float* %57
br label %58
58: ; preds = %56, %54
%59 = extractelement <4 x i1> %35, i64 1
br i1 %59, label %60, label %63
60: ; preds = %58
%61 = or i64 %26, 5
%62 = getelementptr inbounds float, float* %3, i64 %61
store float 0.000000e+00, float* %62
br label %63
63: ; preds = %60, %58
%64 = extractelement <4 x i1> %35, i64 2
br i1 %64, label %65, label %68
65: ; preds = %63
%66 = or i64 %26, 6
%67 = getelementptr inbounds float, float* %3, i64 %66
store float 0.000000e+00, float* %67
br label %68
68: ; preds = %65, %63
%69 = extractelement <4 x i1> %35, i64 3
br i1 %69, label %70, label %73
70: ; preds = %68
%71 = or i64 %26, 7
%72 = getelementptr inbounds float, float* %3, i64 %71
store float 0.000000e+00, float* %72
br label %73
73: ; preds = %70, %68
%74 = add nuw i64 %26, 8
%75 = icmp eq i64 %74, %24
br i1 %75, label %76, label %25
76: ; preds = %73
%77 = icmp eq i64 %24, %21
br i1 %77, label %80, label %78
78: ; preds = %20, %76
%79 = phi i64 [ 0, %20 ], [ %24, %76 ]
br label %81
80: ; preds = %87, %76, %4
tail call void @free(i8* %8)
tail call void @free(i8* %10)
tail call void @free(i8* %13)
tail call void @free(i8* %15)
ret void
81: ; preds = %78, %87
%82 = phi i64 [ %88, %87 ], [ %79, %78 ]
%83 = getelementptr inbounds float, float* %3, i64 %82
%84 = load float, float* %83
%85 = fcmp olt float %84, 0.000000e+00
br i1 %85, label %86, label %87
86: ; preds = %81
store float 0.000000e+00, float* %83
br label %87
87: ; preds = %81, %86
%88 = add nuw nsw i64 %82, 1
%89 = icmp eq i64 %88, %21
br i1 %89, label %80, label %81
}