int arotate(the_image, out_image, angle, m, n, bilinear, rows, cols)
float angle;
int bilinear;
long cols, rows;
short **the_image, **out_image, m, n;
{
  double cosa, sina, radian_angle, tmpx, tmpy;
  int i, j, new_i, new_j;
  radian_angle = angle / 57.29577951;
  cosa = cos(radian_angle);
  sina = sin(radian_angle);
  printf("\n");
  for (i = 0; i < rows; i++) {
    if ((i % 10) == 0)
      printf("%d ", i);
    for (j = 0; j < cols; j++) {
      tmpx = (double)(j)*cosa - (double)(i)*sina - (double)(m)*cosa +
             (double)(m) + (double)(n)*sina;
      tmpy = (double)(i)*cosa + (double)(j)*sina - (double)(m)*sina -
             (double)(n)*cosa + (double)(n);
      new_j = tmpx;
      new_i = tmpy;
      if (bilinear == 0) {
        if (new_j < 0 || new_j >= cols || new_i < 0 || new_i >= rows)
          out_image[i][j] = 150;
        else
          out_image[i][j] = the_image[new_i][new_j];
      } else {
        out_image[i][j] =
            bilinear_interpolate(the_image, tmpx, tmpy, rows, cols);
      }
    }
  }
  return (1);
}


x86 assembly (clang, -O0):
<arotate>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %ecx,%eax
mov    0x10(%rbp),%rcx
cvtsd2ss %xmm0,%xmm0
mov    %dx,%cx
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movss  %xmm0,-0x14(%rbp)
mov    %cx,-0x16(%rbp)
mov    %ax,-0x18(%rbp)
mov    %r8d,-0x1c(%rbp)
mov    %r9,-0x28(%rbp)
movss  -0x14(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe7d(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
call   1060 <cos@plt>
movsd  %xmm0,-0x30(%rbp)
movsd  -0x40(%rbp),%xmm0
call   1050 <sin@plt>
movsd  %xmm0,-0x38(%rbp)
lea    0xe57(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
movl   $0x0,-0x54(%rbp)
movslq -0x54(%rbp),%rax
cmp    -0x28(%rbp),%rax
jge    138b <arotate+0x24b>
mov    -0x54(%rbp),%eax
mov    $0xa,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    11f2 <arotate+0xb2>
mov    -0x54(%rbp),%esi
lea    0xe1f(%rip),%rdi
mov    $0x0,%al
call   1040 <printf@plt>
movl   $0x0,-0x58(%rbp)
movslq -0x58(%rbp),%rax
cmp    0x10(%rbp),%rax
jge    1378 <arotate+0x238>
cvtsi2sdl -0x58(%rbp),%xmm1
movsd  -0x30(%rbp),%xmm4
cvtsi2sdl -0x54(%rbp),%xmm0
movsd  -0x38(%rbp),%xmm2
mulsd  %xmm2,%xmm0
mulsd  %xmm4,%xmm1
subsd  %xmm0,%xmm1
movswl -0x16(%rbp),%eax
cvtsi2sd %eax,%xmm0
movaps %xmm0,%xmm3
mulsd  %xmm4,%xmm3
subsd  %xmm3,%xmm1
addsd  %xmm0,%xmm1
movswl -0x18(%rbp),%eax
cvtsi2sd %eax,%xmm0
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
cvtsi2sdl -0x54(%rbp),%xmm0
movsd  -0x30(%rbp),%xmm3
cvtsi2sdl -0x58(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm2
mulsd  %xmm2,%xmm1
mulsd  %xmm3,%xmm0
addsd  %xmm1,%xmm0
movswl -0x16(%rbp),%eax
cvtsi2sd %eax,%xmm1
mulsd  %xmm2,%xmm1
subsd  %xmm1,%xmm0
movswl -0x18(%rbp),%eax
cvtsi2sd %eax,%xmm1
movaps %xmm1,%xmm2
mulsd  %xmm3,%xmm2
subsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
cvttsd2si -0x48(%rbp),%eax
mov    %eax,-0x60(%rbp)
cvttsd2si -0x50(%rbp),%eax
mov    %eax,-0x5c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jne    1331 <arotate+0x1f1>
cmpl   $0x0,-0x60(%rbp)
jl     12e9 <arotate+0x1a9>
movslq -0x60(%rbp),%rax
cmp    0x10(%rbp),%rax
jge    12e9 <arotate+0x1a9>
cmpl   $0x0,-0x5c(%rbp)
jl     12e9 <arotate+0x1a9>
movslq -0x5c(%rbp),%rax
cmp    -0x28(%rbp),%rax
jl     1304 <arotate+0x1c4>
mov    -0x10(%rbp),%rax
movslq -0x54(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x58(%rbp),%rcx
movw   $0x96,(%rax,%rcx,2)
jmp    132c <arotate+0x1ec>
mov    -0x8(%rbp),%rax
movslq -0x5c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x60(%rbp),%rcx
mov    (%rax,%rcx,2),%dx
mov    -0x10(%rbp),%rax
movslq -0x54(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x58(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
jmp    1365 <arotate+0x225>
mov    -0x8(%rbp),%rdi
movsd  -0x48(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm1
mov    -0x28(%rbp),%rsi
mov    0x10(%rbp),%rdx
mov    $0x2,%al
call   1030 <bilinear_interpolate@plt>
mov    %ax,%dx
mov    -0x10(%rbp),%rax
movslq -0x54(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x58(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
jmp    136a <arotate+0x22a>
mov    -0x58(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x58(%rbp)
jmp    11f9 <arotate+0xb9>
jmp    137d <arotate+0x23d>
mov    -0x54(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x54(%rbp)
jmp    11bf <arotate+0x7f>
mov    $0x1,%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<arotate>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0xa8,%rsp
cvtsd2ss %xmm0,%xmm0
mov    %r9,%r14
mov    %r8d,%r12d
mov    %ecx,%r15d
mov    %edx,%r13d
mov    %rsi,%rbx
mov    %rdi,0x10(%rsp)
cvtss2sd %xmm0,%xmm0
divsd  0xe7b(%rip),%xmm0
movsd  %xmm0,0x8(%rsp)
call   1070 <cos@plt>
movsd  %xmm0,0x18(%rsp)
movsd  0x8(%rsp),%xmm0
call   1060 <sin@plt>
movapd %xmm0,0x30(%rsp)
mov    $0xa,%edi
call   1030 <putchar@plt>
test   %r14,%r14
jle    137f <arotate+0x22f>
mov    0xe0(%rsp),%rbp
movapd 0xe46(%rip),%xmm2
movapd 0x30(%rsp),%xmm1
movapd %xmm1,%xmm0
movswl %r13w,%eax
cvtsi2sd %eax,%xmm3
xorpd  %xmm2,%xmm0
movapd %xmm0,0x40(%rsp)
movapd %xmm3,0x80(%rsp)
movswl %r15w,%eax
cvtsi2sd %eax,%xmm4
xorpd  %xmm2,%xmm3
xorpd  %xmm4,%xmm2
movapd %xmm3,%xmm5
movsd  0x18(%rsp),%xmm0
mulsd  %xmm0,%xmm5
movsd  %xmm5,0x20(%rsp)
movapd %xmm4,0x60(%rsp)
mulsd  %xmm1,%xmm4
movapd %xmm4,0x50(%rsp)
mulsd  %xmm1,%xmm3
movapd %xmm3,0x70(%rsp)
mulsd  %xmm0,%xmm2
movapd %xmm2,0x90(%rsp)
xor    %r13d,%r13d
jmp    124d <arotate+0xfd>
nop
add    $0x1,%r13
cmp    %r14,%r13
je     137f <arotate+0x22f>
imul   $0xcccccccd,%r13d,%eax
ror    %eax
cmp    $0x19999999,%eax
jbe    1270 <arotate+0x120>
test   %rbp,%rbp
jg     1286 <arotate+0x136>
jmp    1240 <arotate+0xf0>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
lea    0xda9(%rip),%rdi
mov    %r13d,%esi
xor    %eax,%eax
call   1050 <printf@plt>
test   %rbp,%rbp
jle    1240 <arotate+0xf0>
xorps  %xmm1,%xmm1
cvtsi2sd %r13d,%xmm1
movapd 0x40(%rsp),%xmm0
movsd  %xmm1,0x8(%rsp)
mulsd  %xmm1,%xmm0
movsd  %xmm0,0x28(%rsp)
xor    %r15d,%r15d
jmp    12d8 <arotate+0x188>
nopl   0x0(%rax)
mov    0x10(%rsp),%rdi
mov    %r14,%rsi
mov    %rbp,%rdx
mov    $0x2,%al
call   1040 <bilinear_interpolate@plt>
mov    (%rbx,%r13,8),%rcx
mov    %ax,(%rcx,%r15,2)
add    $0x1,%r15
cmp    %r15,%rbp
je     1240 <arotate+0xf0>
xorps  %xmm0,%xmm0
cvtsi2sd %r15d,%xmm0
movapd 0x30(%rsp),%xmm2
mulsd  %xmm0,%xmm2
movsd  0x18(%rsp),%xmm3
mulsd  %xmm3,%xmm0
addsd  0x28(%rsp),%xmm0
addsd  0x20(%rsp),%xmm0
addsd  0x80(%rsp),%xmm0
addsd  0x50(%rsp),%xmm0
movsd  0x8(%rsp),%xmm1
mulsd  %xmm3,%xmm1
addsd  %xmm2,%xmm1
addsd  0x70(%rsp),%xmm1
addsd  0x90(%rsp),%xmm1
addsd  0x60(%rsp),%xmm1
test   %r12d,%r12d
jne    12b0 <arotate+0x160>
cvttsd2si %xmm0,%ecx
mov    $0x96,%ax
test   %ecx,%ecx
js     12c2 <arotate+0x172>
mov    %ecx,%ecx
cmp    %rbp,%rcx
jge    12c2 <arotate+0x172>
cvttsd2si %xmm1,%edx
test   %edx,%edx
js     12c2 <arotate+0x172>
mov    %edx,%edx
cmp    %r14,%rdx
jge    12c2 <arotate+0x172>
mov    0x10(%rsp),%rax
mov    (%rax,%rdx,8),%rax
movzwl (%rax,%rcx,2),%eax
jmp    12c2 <arotate+0x172>
mov    $0x1,%eax
add    $0xa8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [2 x i8] c"\0A\00"
@.str.1 = [4 x i8] c"%d \00"
define i32 @arotate(i16** %0, i16** %1, double %2, i32 %3, i32 %4, i32 %5, i64 %6, i64 %7) {
%9 = alloca i16**
%10 = alloca i16**
%11 = alloca float
%12 = alloca i16
%13 = alloca i16
%14 = alloca i32
%15 = alloca i64
%16 = alloca i64
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca double
%21 = alloca double
%22 = alloca i32
%23 = alloca i32
%24 = alloca i32
%25 = alloca i32
%26 = fptrunc double %2 to float
%27 = trunc i32 %3 to i16
%28 = trunc i32 %4 to i16
store i16** %0, i16*** %9
store i16** %1, i16*** %10
store float %26, float* %11
store i16 %27, i16* %12
store i16 %28, i16* %13
store i32 %5, i32* %14
store i64 %6, i64* %15
store i64 %7, i64* %16
%29 = load float, float* %11
%30 = fpext float %29 to double
%31 = fdiv double %30, 0x404CA5DC1A5D2372
store double %31, double* %19
%32 = load double, double* %19
%33 = call double @cos(double %32)
store double %33, double* %17
%34 = load double, double* %19
%35 = call double @sin(double %34)
store double %35, double* %18
%36 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str, i64 0, i64 0))
store i32 0, i32* %22
br label %37
37: ; preds = %169, %8
%38 = load i32, i32* %22
%39 = sext i32 %38 to i64
%40 = load i64, i64* %15
%41 = icmp slt i64 %39, %40
br i1 %41, label %42, label %172
42: ; preds = %37
%43 = load i32, i32* %22
%44 = srem i32 %43, 10
%45 = icmp eq i32 %44, 0
br i1 %45, label %46, label %49
46: ; preds = %42
%47 = load i32, i32* %22
%48 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i32 %47)
br label %49
49: ; preds = %46, %42
store i32 0, i32* %23
br label %50
50: ; preds = %165, %49
%51 = load i32, i32* %23
%52 = sext i32 %51 to i64
%53 = load i64, i64* %16
%54 = icmp slt i64 %52, %53
br i1 %54, label %55, label %168
55: ; preds = %50
%56 = load i32, i32* %23
%57 = sitofp i32 %56 to double
%58 = load double, double* %17
%59 = load i32, i32* %22
%60 = sitofp i32 %59 to double
%61 = load double, double* %18
%62 = fmul double %60, %61
%63 = fneg double %62
%64 = call double @llvm.fmuladd.f64(double %57, double %58, double %63)
%65 = load i16, i16* %12
%66 = sitofp i16 %65 to double
%67 = load double, double* %17
%68 = fneg double %66
%69 = call double @llvm.fmuladd.f64(double %68, double %67, double %64)
%70 = load i16, i16* %12
%71 = sitofp i16 %70 to double
%72 = fadd double %69, %71
%73 = load i16, i16* %13
%74 = sitofp i16 %73 to double
%75 = load double, double* %18
%76 = call double @llvm.fmuladd.f64(double %74, double %75, double %72)
store double %76, double* %20
%77 = load i32, i32* %22
%78 = sitofp i32 %77 to double
%79 = load double, double* %17
%80 = load i32, i32* %23
%81 = sitofp i32 %80 to double
%82 = load double, double* %18
%83 = fmul double %81, %82
%84 = call double @llvm.fmuladd.f64(double %78, double %79, double %83)
%85 = load i16, i16* %12
%86 = sitofp i16 %85 to double
%87 = load double, double* %18
%88 = fneg double %86
%89 = call double @llvm.fmuladd.f64(double %88, double %87, double %84)
%90 = load i16, i16* %13
%91 = sitofp i16 %90 to double
%92 = load double, double* %17
%93 = fneg double %91
%94 = call double @llvm.fmuladd.f64(double %93, double %92, double %89)
%95 = load i16, i16* %13
%96 = sitofp i16 %95 to double
%97 = fadd double %94, %96
store double %97, double* %21
%98 = load double, double* %20
%99 = fptosi double %98 to i32
store i32 %99, i32* %25
%100 = load double, double* %21
%101 = fptosi double %100 to i32
store i32 %101, i32* %24
%102 = load i32, i32* %14
%103 = icmp eq i32 %102, 0
br i1 %103, label %104, label %148
104: ; preds = %55
%105 = load i32, i32* %25
%106 = icmp slt i32 %105, 0
br i1 %106, label %120, label %107
107: ; preds = %104
%108 = load i32, i32* %25
%109 = sext i32 %108 to i64
%110 = load i64, i64* %16
%111 = icmp sge i64 %109, %110
br i1 %111, label %120, label %112
112: ; preds = %107
%113 = load i32, i32* %24
%114 = icmp slt i32 %113, 0
br i1 %114, label %120, label %115
115: ; preds = %112
%116 = load i32, i32* %24
%117 = sext i32 %116 to i64
%118 = load i64, i64* %15
%119 = icmp sge i64 %117, %118
br i1 %119, label %120, label %129
120: ; preds = %115, %112, %107, %104
%121 = load i16**, i16*** %10
%122 = load i32, i32* %22
%123 = sext i32 %122 to i64
%124 = getelementptr inbounds i16*, i16** %121, i64 %123
%125 = load i16*, i16** %124
%126 = load i32, i32* %23
%127 = sext i32 %126 to i64
%128 = getelementptr inbounds i16, i16* %125, i64 %127
store i16 150, i16* %128
br label %147
129: ; preds = %115
%130 = load i16**, i16*** %9
%131 = load i32, i32* %24
%132 = sext i32 %131 to i64
%133 = getelementptr inbounds i16*, i16** %130, i64 %132
%134 = load i16*, i16** %133
%135 = load i32, i32* %25
%136 = sext i32 %135 to i64
%137 = getelementptr inbounds i16, i16* %134, i64 %136
%138 = load i16, i16* %137
%139 = load i16**, i16*** %10
%140 = load i32, i32* %22
%141 = sext i32 %140 to i64
%142 = getelementptr inbounds i16*, i16** %139, i64 %141
%143 = load i16*, i16** %142
%144 = load i32, i32* %23
%145 = sext i32 %144 to i64
%146 = getelementptr inbounds i16, i16* %143, i64 %145
store i16 %138, i16* %146
br label %147
147: ; preds = %129, %120
br label %164
148: ; preds = %55
%149 = load i16**, i16*** %9
%150 = load double, double* %20
%151 = load double, double* %21
%152 = load i64, i64* %15
%153 = load i64, i64* %16
%154 = call i32 (i16**, double, double, i64, i64, ...) bitcast (i32 (...)* @bilinear_interpolate to i32 (i16**, double, double, i64, i64, ...)*)(i16** %149, double %150, double %151, i64 %152, i64 %153)
%155 = trunc i32 %154 to i16
%156 = load i16**, i16*** %10
%157 = load i32, i32* %22
%158 = sext i32 %157 to i64
%159 = getelementptr inbounds i16*, i16** %156, i64 %158
%160 = load i16*, i16** %159
%161 = load i32, i32* %23
%162 = sext i32 %161 to i64
%163 = getelementptr inbounds i16, i16* %160, i64 %162
store i16 %155, i16* %163
br label %164
164: ; preds = %148, %147
br label %165
165: ; preds = %164
%166 = load i32, i32* %23
%167 = add nsw i32 %166, 1
store i32 %167, i32* %23
br label %50
168: ; preds = %50
br label %169
169: ; preds = %168
%170 = load i32, i32* %22
%171 = add nsw i32 %170, 1
store i32 %171, i32* %22
br label %37
172: ; preds = %37
ret i32 1
}

LLVM IR (-O2):
@.str.1 = [4 x i8] c"%d \00"
define i32 @arotate(i16** %0, i16** nocapture %1, double %2, i32 %3, i32 %4, i32 %5, i64 %6, i64 %7) {
%9 = fptrunc double %2 to float
%10 = fpext float %9 to double
%11 = fdiv double %10, 0x404CA5DC1A5D2372
%12 = tail call double @cos(double %11)
%13 = tail call double @sin(double %11)
%14 = tail call i32 @putchar(i32 10)
%15 = icmp sgt i64 %6, 0
br i1 %15, label %16, label %80
16: ; preds = %8
%17 = trunc i32 %4 to i16
%18 = trunc i32 %3 to i16
%19 = icmp sgt i64 %7, 0
%20 = fneg double %13
%21 = sitofp i16 %18 to double
%22 = fneg double %21
%23 = sitofp i16 %17 to double
%24 = fneg double %23
%25 = icmp eq i32 %5, 0
br label %26
26: ; preds = %16, %77
%27 = phi i64 [ 0, %16 ], [ %78, %77 ]
%28 = trunc i64 %27 to i32
%29 = urem i32 %28, 10
%30 = icmp eq i32 %29, 0
br i1 %30, label %31, label %33
31: ; preds = %26
%32 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i64 0, i64 0), i32 %28)
br label %33
33: ; preds = %31, %26
br i1 %19, label %34, label %77
34: ; preds = %33
%35 = sitofp i32 %28 to double
%36 = fmul double %20, %35
%37 = getelementptr inbounds i16*, i16** %1, i64 %27
br label %38
38: ; preds = %34, %71
%39 = phi i64 [ 0, %34 ], [ %75, %71 ]
%40 = trunc i64 %39 to i32
%41 = sitofp i32 %40 to double
%42 = tail call double @llvm.fmuladd.f64(double %41, double %12, double %36)
%43 = tail call double @llvm.fmuladd.f64(double %22, double %12, double %42)
%44 = fadd double %43, %21
%45 = tail call double @llvm.fmuladd.f64(double %23, double %13, double %44)
%46 = fmul double %13, %41
%47 = tail call double @llvm.fmuladd.f64(double %35, double %12, double %46)
%48 = tail call double @llvm.fmuladd.f64(double %22, double %13, double %47)
%49 = tail call double @llvm.fmuladd.f64(double %24, double %12, double %48)
%50 = fadd double %49, %23
%51 = fptosi double %45 to i32
%52 = fptosi double %50 to i32
br i1 %25, label %53, label %68
53: ; preds = %38
%54 = icmp slt i32 %51, 0
br i1 %54, label %71, label %55
55: ; preds = %53
%56 = zext i32 %51 to i64
%57 = icmp sge i64 %56, %7
%58 = icmp slt i32 %52, 0
%59 = select i1 %57, i1 true, i1 %58
br i1 %59, label %71, label %60
60: ; preds = %55
%61 = zext i32 %52 to i64
%62 = icmp slt i64 %61, %6
br i1 %62, label %63, label %71
63: ; preds = %60
%64 = getelementptr inbounds i16*, i16** %0, i64 %61
%65 = load i16*, i16** %64
%66 = getelementptr inbounds i16, i16* %65, i64 %56
%67 = load i16, i16* %66
br label %71
68: ; preds = %38
%69 = tail call i32 (i16**, double, double, i64, i64, ...) bitcast (i32 (...)* @bilinear_interpolate to i32 (i16**, double, double, i64, i64, ...)*)(i16** %0, double %45, double %50, i64 %6, i64 %7)
%70 = trunc i32 %69 to i16
br label %71
71: ; preds = %53, %55, %60, %68, %63
%72 = phi i16 [ %70, %68 ], [ %67, %63 ], [ 150, %60 ], [ 150, %55 ], [ 150, %53 ]
%73 = load i16*, i16** %37
%74 = getelementptr inbounds i16, i16* %73, i64 %39
store i16 %72, i16* %74
%75 = add nuw nsw i64 %39, 1
%76 = icmp eq i64 %75, %7
br i1 %76, label %77, label %38
77: ; preds = %71, %33
%78 = add nuw nsw i64 %27, 1
%79 = icmp eq i64 %78, %6
br i1 %79, label %80, label %26
80: ; preds = %77, %8
ret i32 1
}