void v_dblshfl(double *vec, int n, double randfn(void)) {
  int i;
  double t;
  while (--n > 0) {
    i = (int)((n + 1) * randfn());
    if (i > n)
      i = n;
    if (i < 0)
      i = 0;
    t = vec[i];
    vec[i] = vec[n];
    vec[n] = t;
  }
}


x86 assembly (clang, -O0):
<v_dblshfl>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
cmp    $0x0,%eax
jle    11b0 <v_dblshfl+0xb0>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %eax,%xmm0
movsd  %xmm0,-0x30(%rbp)
call   *-0x18(%rbp)
movaps %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
mulsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jle    115c <v_dblshfl+0x5c>
mov    -0xc(%rbp),%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jge    116d <v_dblshfl+0x6d>
movl   $0x0,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
movsd  -0x28(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
jmp    1113 <v_dblshfl+0x13>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<v_dblshfl>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x10,%rsp
cmp    $0x2,%esi
jl     1173 <v_dblshfl+0x73>
mov    %rdx,%r14
mov    %rdi,%r15
mov    %esi,%ebx
xor    %r12d,%r12d
jmp    1149 <v_dblshfl+0x49>
xchg   %ax,%ax
test   %eax,%eax
cmovs  %r12d,%eax
movsd  (%r15,%rax,8),%xmm0
mov    %ebp,%ecx
movsd  (%r15,%rcx,8),%xmm1
movsd  %xmm1,(%r15,%rax,8)
movsd  %xmm0,(%r15,%rcx,8)
cmp    $0x2,%rbx
mov    %rbp,%rbx
jbe    1173 <v_dblshfl+0x73>
lea    -0x1(%rbx),%rbp
xorps  %xmm0,%xmm0
cvtsi2sd %ebx,%xmm0
movsd  %xmm0,0x8(%rsp)
call   *%r14
mulsd  0x8(%rsp),%xmm0
cvttsd2si %xmm0,%eax
movslq %eax,%rcx
cmp    %rcx,%rbx
jg     1120 <v_dblshfl+0x20>
mov    %ebp,%eax
jmp    1120 <v_dblshfl+0x20>
add    $0x10,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @v_dblshfl(double* %0, i32 %1, double ()* %2) {
%4 = alloca double*
%5 = alloca i32
%6 = alloca double ()*
%7 = alloca i32
%8 = alloca double
store double* %0, double** %4
store i32 %1, i32* %5
store double ()* %2, double ()** %6
br label %9
9: ; preds = %30, %3
%10 = load i32, i32* %5
%11 = add nsw i32 %10, -1
store i32 %11, i32* %5
%12 = icmp sgt i32 %11, 0
br i1 %12, label %13, label %50
13: ; preds = %9
%14 = load i32, i32* %5
%15 = add nsw i32 %14, 1
%16 = sitofp i32 %15 to double
%17 = load double ()*, double ()** %6
%18 = call double %17()
%19 = fmul double %16, %18
%20 = fptosi double %19 to i32
store i32 %20, i32* %7
%21 = load i32, i32* %7
%22 = load i32, i32* %5
%23 = icmp sgt i32 %21, %22
br i1 %23, label %24, label %26
24: ; preds = %13
%25 = load i32, i32* %5
store i32 %25, i32* %7
br label %26
26: ; preds = %24, %13
%27 = load i32, i32* %7
%28 = icmp slt i32 %27, 0
br i1 %28, label %29, label %30
29: ; preds = %26
store i32 0, i32* %7
br label %30
30: ; preds = %29, %26
%31 = load double*, double** %4
%32 = load i32, i32* %7
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds double, double* %31, i64 %33
%35 = load double, double* %34
store double %35, double* %8
%36 = load double*, double** %4
%37 = load i32, i32* %5
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds double, double* %36, i64 %38
%40 = load double, double* %39
%41 = load double*, double** %4
%42 = load i32, i32* %7
%43 = sext i32 %42 to i64
%44 = getelementptr inbounds double, double* %41, i64 %43
store double %40, double* %44
%45 = load double, double* %8
%46 = load double*, double** %4
%47 = load i32, i32* %5
%48 = sext i32 %47 to i64
%49 = getelementptr inbounds double, double* %46, i64 %48
store double %45, double* %49
br label %9
50: ; preds = %9
ret void
}

LLVM IR (-O2):
define void @v_dblshfl(double* nocapture %0, i32 %1, double ()* nocapture %2) {
%4 = icmp sgt i32 %1, 1
br i1 %4, label %5, label %28
5: ; preds = %3
%6 = zext i32 %1 to i64
br label %7
7: ; preds = %5, %7
%8 = phi i64 [ %6, %5 ], [ %9, %7 ]
%9 = add nsw i64 %8, -1
%10 = trunc i64 %9 to i32
%11 = trunc i64 %8 to i32
%12 = sitofp i32 %11 to double
%13 = tail call double %2()
%14 = fmul double %13, %12
%15 = fptosi double %14 to i32
%16 = sext i32 %15 to i64
%17 = icmp sgt i64 %8, %16
%18 = select i1 %17, i32 %15, i32 %10
%19 = icmp sgt i32 %18, 0
%20 = select i1 %19, i32 %18, i32 0
%21 = zext i32 %20 to i64
%22 = getelementptr inbounds double, double* %0, i64 %21
%23 = load double, double* %22
%24 = and i64 %9, 4294967295
%25 = getelementptr inbounds double, double* %0, i64 %24
%26 = load double, double* %25
store double %26, double* %22
store double %23, double* %25
%27 = icmp ugt i64 %8, 2
br i1 %27, label %7, label %28
28: ; preds = %7, %3
ret void
}