void diffrt(float *a, int n, float dt) {
  int i;
  for (i = n - 1; i > 0; i--) {
    a[i] = (a[i] - a[i - 1]) / dt;
  }
  a[0] = 0.;
}


x86 assembly (clang, -O0):
<diffrt>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movss  %xmm0,-0x10(%rbp)
mov    -0xc(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jle    1162 <diffrt+0x62>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
subss  (%rax,%rcx,4),%xmm0
divss  -0x10(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    1119 <diffrt+0x19>
mov    -0x8(%rbp),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<diffrt>:
push   %rbx
cmp    $0x2,%esi
jl     116c <diffrt+0x6c>
mov    $0xfffffffe,%eax
mov    %esi,%ebx
xor    %r10d,%r10d
mov    %rbx,%rdx
sub    $0x2,%rdx
mov    $0x0,%r9d
cmovae %rdx,%r9
add    $0x1,%r9
cmp    $0x4,%r9
jae    1174 <diffrt+0x74>
add    %rbx,%rax
add    $0xffffffffffffffff,%rbx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    %ebx,%ecx
movss  (%rdi,%rcx,4),%xmm1
mov    %eax,%edx
subss  (%rdi,%rdx,4),%xmm1
divss  %xmm0,%xmm1
movss  %xmm1,(%rdi,%rcx,4)
add    $0xffffffffffffffff,%rax
lea    -0x1(%rbx),%rcx
add    $0x1,%rbx
cmp    $0x2,%rbx
mov    %rcx,%rbx
ja     1140 <diffrt+0x40>
movl   $0x0,(%rdi)
pop    %rbx
ret
mov    %ebx,%edx
sub    $0x2,%edx
cmovb  %r10d,%edx
mov    %rbx,%rcx
sub    $0x2,%rcx
cmovae %rcx,%r10
lea    -0x1(%rsi),%r8d
cmp    %edx,%r8d
jb     112b <diffrt+0x2b>
mov    %r10,%r11
shr    $0x20,%r11
jne    112b <diffrt+0x2b>
add    $0xfffffffe,%esi
cmp    %edx,%esi
jb     112b <diffrt+0x2b>
test   %r11,%r11
jne    112b <diffrt+0x2b>
lea    (%rdi,%r8,4),%rcx
shl    $0x2,%r10
mov    %rcx,%rdx
sub    %r10,%rdx
cmp    %rcx,%rdx
ja     112b <diffrt+0x2b>
xor    %ecx,%ecx
test   %cl,%cl
jne    112b <diffrt+0x2b>
lea    (%rdi,%rsi,4),%rcx
mov    %rcx,%rdx
sub    %r10,%rdx
cmp    %rcx,%rdx
ja     112b <diffrt+0x2b>
xor    %ecx,%ecx
test   %cl,%cl
jne    112b <diffrt+0x2b>
cmp    $0x2,%rbx
mov    $0x2,%edx
cmovb  %rbx,%rdx
lea    (%rdx,%r8,1),%rcx
sub    %rbx,%rcx
lea    (%rdi,%rcx,4),%r10
lea    (%rdi,%rsi,4),%rcx
add    $0x4,%rcx
cmp    %rcx,%r10
jae    1224 <diffrt+0x124>
lea    (%rdi,%r8,4),%rcx
add    $0x4,%rcx
add    %rsi,%rdx
sub    %rbx,%rdx
lea    (%rdi,%rdx,4),%rdx
cmp    %rcx,%rdx
jb     112b <diffrt+0x2b>
mov    %r9,%r8
and    $0xfffffffffffffffc,%r8
movaps %xmm0,%xmm1
shufps $0x0,%xmm0,%xmm1
lea    (%rax,%rbx,1),%rsi
add    $0x1,%rsi
sub    %r8,%rbx
shufps $0x1b,%xmm1,%xmm1
mov    %r8,%rdx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    %esi,%r10d
movups -0xc(%rdi,%r10,4),%xmm2
lea    -0x1(%rsi),%ecx
movups -0xc(%rdi,%rcx,4),%xmm3
subps  %xmm3,%xmm2
divps  %xmm1,%xmm2
movups %xmm2,-0xc(%rdi,%r10,4)
add    $0xfffffffffffffffc,%rsi
add    $0xfffffffffffffffc,%rdx
jne    1250 <diffrt+0x150>
cmp    %r8,%r9
jne    112b <diffrt+0x2b>
jmp    116c <diffrt+0x6c>

LLVM IR (-O0):
define void @diffrt(float* %0, i32 %1, float %2) {
%4 = alloca float*
%5 = alloca i32
%6 = alloca float
%7 = alloca i32
store float* %0, float** %4
store i32 %1, i32* %5
store float %2, float* %6
%8 = load i32, i32* %5
%9 = sub nsw i32 %8, 1
store i32 %9, i32* %7
br label %10
10: ; preds = %32, %3
%11 = load i32, i32* %7
%12 = icmp sgt i32 %11, 0
br i1 %12, label %13, label %35
13: ; preds = %10
%14 = load float*, float** %4
%15 = load i32, i32* %7
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds float, float* %14, i64 %16
%18 = load float, float* %17
%19 = load float*, float** %4
%20 = load i32, i32* %7
%21 = sub nsw i32 %20, 1
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds float, float* %19, i64 %22
%24 = load float, float* %23
%25 = fsub float %18, %24
%26 = load float, float* %6
%27 = fdiv float %25, %26
%28 = load float*, float** %4
%29 = load i32, i32* %7
%30 = sext i32 %29 to i64
%31 = getelementptr inbounds float, float* %28, i64 %30
store float %27, float* %31
br label %32
32: ; preds = %13
%33 = load i32, i32* %7
%34 = add nsw i32 %33, -1
store i32 %34, i32* %7
br label %10
35: ; preds = %10
%36 = load float*, float** %4
%37 = getelementptr inbounds float, float* %36, i64 0
store float 0.000000e+00, float* %37
ret void
}

LLVM IR (-O2):
define void @diffrt(float* nocapture %0, i32 %1, float %2) {
%4 = icmp sgt i32 %1, 1
br i1 %4, label %5, label %110
5: ; preds = %3
%6 = zext i32 %1 to i64
%7 = add nuw nsw i64 %6, 1
%8 = call i64 @llvm.umin.i64(i64 %6, i64 2)
%9 = sub nsw i64 %7, %8
%10 = icmp ult i64 %9, 4
br i1 %10, label %95, label %11
11: ; preds = %5
%12 = call i64 @llvm.umin.i64(i64 %6, i64 2)
%13 = sub nsw i64 %6, %12
%14 = add i32 %1, -1
%15 = trunc i64 %13 to i32
%16 = icmp ult i32 %14, %15
%17 = icmp ugt i64 %13, 4294967295
%18 = or i1 %16, %17
%19 = add i32 %1, -2
%20 = trunc i64 %13 to i32
%21 = icmp ult i32 %19, %20
%22 = icmp ugt i64 %13, 4294967295
%23 = or i1 %21, %22
%24 = zext i32 %14 to i64
%25 = getelementptr float, float* %0, i64 %24
%26 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %13, i64 4)
%27 = extractvalue { i64, i1 } %26, 0
%28 = extractvalue { i64, i1 } %26, 1
%29 = bitcast float* %25 to i8*
%30 = sub i64 0, %27
%31 = getelementptr i8, i8* %29, i64 %30
%32 = icmp ugt i8* %31, %29
%33 = or i1 %32, %28
%34 = zext i32 %19 to i64
%35 = getelementptr float, float* %0, i64 %34
%36 = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 %13, i64 4)
%37 = extractvalue { i64, i1 } %36, 0
%38 = extractvalue { i64, i1 } %36, 1
%39 = bitcast float* %35 to i8*
%40 = sub i64 0, %37
%41 = getelementptr i8, i8* %39, i64 %40
%42 = icmp ugt i8* %41, %39
%43 = or i1 %42, %38
%44 = or i1 %18, %23
%45 = or i1 %44, %33
%46 = or i1 %45, %43
br i1 %46, label %95, label %47
47: ; preds = %11
%48 = call i64 @llvm.umin.i64(i64 %6, i64 2)
%49 = add i32 %1, -1
%50 = zext i32 %49 to i64
%51 = add nuw nsw i64 %48, %50
%52 = sub nsw i64 %51, %6
%53 = getelementptr float, float* %0, i64 %52
%54 = add nuw nsw i64 %50, 1
%55 = getelementptr float, float* %0, i64 %54
%56 = add i32 %1, -2
%57 = zext i32 %56 to i64
%58 = add nuw nsw i64 %48, %57
%59 = sub nsw i64 %58, %6
%60 = getelementptr float, float* %0, i64 %59
%61 = add nuw nsw i64 %57, 1
%62 = getelementptr float, float* %0, i64 %61
%63 = icmp ult float* %53, %62
%64 = icmp ult float* %60, %55
%65 = and i1 %63, %64
br i1 %65, label %95, label %66
66: ; preds = %47
%67 = and i64 %9, -4
%68 = sub nsw i64 %6, %67
%69 = insertelement <4 x float> poison, float %2, i64 0
%70 = shufflevector <4 x float> %69, <4 x float> poison, <4 x i32> zeroinitializer
%71 = getelementptr inbounds float, float* %0, i64 -3
%72 = getelementptr inbounds float, float* %0, i64 -3
br label %73
73: ; preds = %73, %66
%74 = phi i64 [ 0, %66 ], [ %91, %73 ]
%75 = sub i64 %6, %74
%76 = add i64 %75, 4294967295
%77 = and i64 %76, 4294967295
%78 = getelementptr inbounds float, float* %71, i64 %77
%79 = bitcast float* %78 to <4 x float>*
%80 = load <4 x float>, <4 x float>* %79
%81 = add nuw i64 %75, 4294967294
%82 = and i64 %81, 4294967295
%83 = getelementptr inbounds float, float* %72, i64 %82
%84 = bitcast float* %83 to <4 x float>*
%85 = load <4 x float>, <4 x float>* %84
%86 = fsub <4 x float> %80, %85
%87 = shufflevector <4 x float> %86, <4 x float> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%88 = fdiv <4 x float> %87, %70
%89 = shufflevector <4 x float> %88, <4 x float> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%90 = bitcast float* %78 to <4 x float>*
store <4 x float> %89, <4 x float>* %90
%91 = add nuw i64 %74, 4
%92 = icmp eq i64 %91, %67
br i1 %92, label %93, label %73
93: ; preds = %73
%94 = icmp eq i64 %9, %67
br i1 %94, label %110, label %95
95: ; preds = %47, %11, %5, %93
%96 = phi i64 [ %6, %47 ], [ %6, %11 ], [ %6, %5 ], [ %68, %93 ]
br label %97
97: ; preds = %95, %97
%98 = phi i64 [ %99, %97 ], [ %96, %95 ]
%99 = add nsw i64 %98, -1
%100 = and i64 %99, 4294967295
%101 = getelementptr inbounds float, float* %0, i64 %100
%102 = load float, float* %101
%103 = add nuw i64 %98, 4294967294
%104 = and i64 %103, 4294967295
%105 = getelementptr inbounds float, float* %0, i64 %104
%106 = load float, float* %105
%107 = fsub float %102, %106
%108 = fdiv float %107, %2
store float %108, float* %101
%109 = icmp ugt i64 %98, 2
br i1 %109, label %97, label %110
110: ; preds = %97, %93, %3
store float 0.000000e+00, float* %0
ret void
}