int dp_build_gamma(int *P, double *tv1, int ntv1, double *tv2, int ntv2,
                   double *G, double *T) {
  int sr, sc;
  int tr, tc;
  int p, i;
  int npts;
  npts = 1;
  tr = ntv2 - 1;
  tc = ntv1 - 1;
  while (tr > 0 && tc > 0) {
    p = P[tr * ntv1 + tc];
    tr = p / ntv1;
    tc = p % ntv1;
    ++npts;
  }
  G[npts - 1] = tv2[ntv2 - 1];
  T[npts - 1] = tv1[ntv1 - 1];
  tr = ntv2 - 1;
  tc = ntv1 - 1;
  i = npts - 2;
  while (tr > 0 && tc > 0) {
    p = P[tr * ntv1 + tc];
    sr = p / ntv1;
    sc = p % ntv1;
    G[i] = tv2[sr];
    T[i] = tv1[sc];
    tr = sr;
    tc = sc;
    --i;
  }
  return npts;
}


x86 assembly (clang, -O0):
<dp_build_gamma>:
push   %rbp
mov    %rsp,%rbp
mov    0x10(%rbp),%rax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8d,-0x24(%rbp)
mov    %r9,-0x30(%rbp)
movl   $0x1,-0x4c(%rbp)
mov    -0x24(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x40(%rbp)
xor    %eax,%eax
cmpl   $0x0,-0x3c(%rbp)
mov    %al,-0x4d(%rbp)
jle    1151 <dp_build_gamma+0x51>
cmpl   $0x0,-0x40(%rbp)
setg   %al
mov    %al,-0x4d(%rbp)
mov    -0x4d(%rbp),%al
test   $0x1,%al
jne    1161 <dp_build_gamma+0x61>
jmp    119a <dp_build_gamma+0x9a>
mov    -0x8(%rbp),%rax
mov    -0x3c(%rbp),%ecx
imul   -0x14(%rbp),%ecx
add    -0x40(%rbp),%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cltd
idivl  -0x14(%rbp)
mov    %eax,-0x3c(%rbp)
mov    -0x44(%rbp),%eax
cltd
idivl  -0x14(%rbp)
mov    %edx,-0x40(%rbp)
mov    -0x4c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4c(%rbp)
jmp    1138 <dp_build_gamma+0x38>
mov    -0x20(%rbp),%rax
mov    -0x24(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
mov    -0x4c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    0x10(%rbp),%rax
mov    -0x4c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x24(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x40(%rbp)
mov    -0x4c(%rbp),%eax
sub    $0x2,%eax
mov    %eax,-0x48(%rbp)
xor    %eax,%eax
cmpl   $0x0,-0x3c(%rbp)
mov    %al,-0x4e(%rbp)
jle    1216 <dp_build_gamma+0x116>
cmpl   $0x0,-0x40(%rbp)
setg   %al
mov    %al,-0x4e(%rbp)
mov    -0x4e(%rbp),%al
test   $0x1,%al
jne    1226 <dp_build_gamma+0x126>
jmp    129f <dp_build_gamma+0x19f>
mov    -0x8(%rbp),%rax
mov    -0x3c(%rbp),%ecx
imul   -0x14(%rbp),%ecx
add    -0x40(%rbp),%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cltd
idivl  -0x14(%rbp)
mov    %eax,-0x34(%rbp)
mov    -0x44(%rbp),%eax
cltd
idivl  -0x14(%rbp)
mov    %edx,-0x38(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x48(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x10(%rbp),%rax
movslq -0x38(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    0x10(%rbp),%rax
movslq -0x48(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x34(%rbp),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x38(%rbp),%eax
mov    %eax,-0x40(%rbp)
mov    -0x48(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x48(%rbp)
jmp    11fd <dp_build_gamma+0xfd>
mov    -0x4c(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<dp_build_gamma>:
push   %rbp
push   %r15
push   %r14
push   %rbx
mov    %edx,%r14d
mov    0x28(%rsp),%r15
lea    -0x1(%r8),%r10d
lea    -0x1(%r14),%ebp
cmp    $0x2,%r8d
setge  %al
cmp    $0x2,%edx
setge  %r8b
and    %al,%r8b
mov    $0x1,%r11d
cmp    $0x1,%r8b
jne    115b <dp_build_gamma+0x5b>
mov    $0x1,%r11d
mov    %ebp,%edx
mov    %r10d,%eax
xchg   %ax,%ax
imul   %r14d,%eax
add    %edx,%eax
cltq
mov    (%rdi,%rax,4),%eax
cltd
idiv   %r14d
add    $0x1,%r11d
test   %eax,%eax
jle    115b <dp_build_gamma+0x5b>
test   %edx,%edx
jg     1140 <dp_build_gamma+0x40>
movslq %r10d,%rax
movsd  (%rcx,%rax,8),%xmm0
movslq %r11d,%rax
movsd  %xmm0,-0x8(%r9,%rax,8)
movslq %ebp,%rdx
movsd  (%rsi,%rdx,8),%xmm0
movsd  %xmm0,-0x8(%r15,%rax,8)
test   %r8b,%r8b
je     11ce <dp_build_gamma+0xce>
lea    -0x2(%r11),%eax
movslq %eax,%rbx
shl    $0x3,%rbx
nopl   0x0(%rax)
imul   %r14d,%r10d
add    %ebp,%r10d
movslq %r10d,%rax
mov    (%rdi,%rax,4),%eax
cltd
idiv   %r14d
mov    %eax,%r10d
cltq
movsd  (%rcx,%rax,8),%xmm0
movsd  %xmm0,(%r9,%rbx,1)
movslq %edx,%rax
movsd  (%rsi,%rax,8),%xmm0
movsd  %xmm0,(%r15,%rbx,1)
test   %r10d,%r10d
jle    11ce <dp_build_gamma+0xce>
mov    %edx,%ebp
add    $0xfffffffffffffff8,%rbx
test   %edx,%edx
jg     1190 <dp_build_gamma+0x90>
mov    %r11d,%eax
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define i32 @dp_build_gamma(i32* nocapture %0, double* nocapture %1, i32 %2, double* nocapture %3, i32 %4, double* nocapture writeonly %5, double* nocapture writeonly %6) {
%8 = add nsw i32 %4, -1
%9 = add nsw i32 %2, -1
%10 = icmp sgt i32 %4, 1
%11 = icmp sgt i32 %2, 1
%12 = and i1 %10, %11
br i1 %12, label %13, label %28
13: ; preds = %7, %13
%14 = phi i32 [ %24, %13 ], [ 1, %7 ]
%15 = phi i32 [ %23, %13 ], [ %9, %7 ]
%16 = phi i32 [ %22, %13 ], [ %8, %7 ]
%17 = mul nsw i32 %16, %2
%18 = add nsw i32 %17, %15
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds i32, i32* %0, i64 %19
%21 = load i32, i32* %20
%22 = sdiv i32 %21, %2
%23 = srem i32 %21, %2
%24 = add nuw nsw i32 %14, 1
%25 = icmp sgt i32 %22, 0
%26 = icmp sgt i32 %23, 0
%27 = and i1 %25, %26
br i1 %27, label %13, label %28
28: ; preds = %13, %7
%29 = phi i32 [ 1, %7 ], [ %24, %13 ]
%30 = sext i32 %8 to i64
%31 = getelementptr inbounds double, double* %3, i64 %30
%32 = load double, double* %31
%33 = add nsw i32 %29, -1
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds double, double* %5, i64 %34
store double %32, double* %35
%36 = sext i32 %9 to i64
%37 = getelementptr inbounds double, double* %1, i64 %36
%38 = load double, double* %37
%39 = getelementptr inbounds double, double* %6, i64 %34
store double %38, double* %39
br i1 %12, label %40, label %66
40: ; preds = %28
%41 = add i32 %29, -2
%42 = sext i32 %41 to i64
br label %43
43: ; preds = %40, %43
%44 = phi i64 [ %42, %40 ], [ %62, %43 ]
%45 = phi i32 [ %9, %40 ], [ %53, %43 ]
%46 = phi i32 [ %8, %40 ], [ %52, %43 ]
%47 = mul nsw i32 %46, %2
%48 = add nsw i32 %47, %45
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds i32, i32* %0, i64 %49
%51 = load i32, i32* %50
%52 = sdiv i32 %51, %2
%53 = srem i32 %51, %2
%54 = sext i32 %52 to i64
%55 = getelementptr inbounds double, double* %3, i64 %54
%56 = load double, double* %55
%57 = getelementptr inbounds double, double* %5, i64 %44
store double %56, double* %57
%58 = sext i32 %53 to i64
%59 = getelementptr inbounds double, double* %1, i64 %58
%60 = load double, double* %59
%61 = getelementptr inbounds double, double* %6, i64 %44
store double %60, double* %61
%62 = add i64 %44, -1
%63 = icmp sgt i32 %52, 0
%64 = icmp sgt i32 %53, 0
%65 = and i1 %63, %64
br i1 %65, label %43, label %66
66: ; preds = %43, %28
ret i32 %29
}