int *rrotate(int *input, unsigned int bits, int n) {
  int lsb = 0;
  for (int i = 0; i < n; i++) {
    lsb = (input[i]) & 1;
    lsb <<= (bits - 1);
    input[i] = lsb | ((input[i]) >> 1);
  }
  return input;
}


x86 assembly (clang, -O0):
<rrotate>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    1173 <rrotate+0x73>
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
and    $0x1,%eax
mov    %eax,-0x14(%rbp)
mov    -0xc(%rbp),%ecx
sub    $0x1,%ecx
mov    -0x14(%rbp),%eax
shl    %cl,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%edx
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
sar    $0x1,%eax
or     %eax,%edx
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    111c <rrotate+0x1c>
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<rrotate>:
mov    %rdi,%rax
test   %edx,%edx
jle    126a <rrotate+0x16a>
mov    %esi,%ecx
add    $0xffffffff,%ecx
mov    %edx,%r9d
cmp    $0x8,%edx
jae    111f <rrotate+0x1f>
xor    %edx,%edx
jmp    1250 <rrotate+0x150>
mov    %r9d,%edx
and    $0xfffffff8,%edx
movd   %ecx,%xmm8
lea    -0x8(%rdx),%rsi
mov    %rsi,%r8
shr    $0x3,%r8
add    $0x1,%r8
test   %rsi,%rsi
je     126b <rrotate+0x16b>
mov    %r8,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %edi,%edi
movdqa 0xead(%rip),%xmm1
xorps  %xmm2,%xmm2
movss  %xmm8,%xmm2
nopl   0x0(%rax,%rax,1)
movdqu (%rax,%rdi,4),%xmm5
movdqu 0x10(%rax,%rdi,4),%xmm0
movdqu 0x20(%rax,%rdi,4),%xmm3
movdqu 0x30(%rax,%rdi,4),%xmm4
movdqa %xmm5,%xmm7
pand   %xmm1,%xmm7
movdqa %xmm0,%xmm6
pand   %xmm1,%xmm6
pslld  %xmm2,%xmm7
pslld  %xmm2,%xmm6
psrad  $0x1,%xmm5
por    %xmm7,%xmm5
psrad  $0x1,%xmm0
por    %xmm6,%xmm0
movdqu %xmm5,(%rax,%rdi,4)
movdqu %xmm0,0x10(%rax,%rdi,4)
movdqa %xmm3,%xmm0
pand   %xmm1,%xmm0
movdqa %xmm4,%xmm5
pand   %xmm1,%xmm5
pslld  %xmm2,%xmm0
pslld  %xmm2,%xmm5
psrad  $0x1,%xmm3
por    %xmm0,%xmm3
psrad  $0x1,%xmm4
por    %xmm5,%xmm4
movdqu %xmm3,0x20(%rax,%rdi,4)
movdqu %xmm4,0x30(%rax,%rdi,4)
add    $0x10,%rdi
add    $0xfffffffffffffffe,%rsi
jne    1160 <rrotate+0x60>
test   $0x1,%r8b
je     1243 <rrotate+0x143>
movdqu (%rax,%rdi,4),%xmm0
movdqu 0x10(%rax,%rdi,4),%xmm1
movdqa 0xdf7(%rip),%xmm2
movdqa %xmm0,%xmm3
pand   %xmm2,%xmm3
pand   %xmm1,%xmm2
pxor   %xmm4,%xmm4
movss  %xmm8,%xmm4
pslld  %xmm4,%xmm3
pslld  %xmm4,%xmm2
psrad  $0x1,%xmm0
por    %xmm3,%xmm0
psrad  $0x1,%xmm1
por    %xmm2,%xmm1
movdqu %xmm0,(%rax,%rdi,4)
movdqu %xmm1,0x10(%rax,%rdi,4)
cmp    %r9,%rdx
je     126a <rrotate+0x16a>
nopl   0x0(%rax,%rax,1)
mov    (%rax,%rdx,4),%esi
mov    %esi,%edi
and    $0x1,%edi
shl    %cl,%edi
sar    %esi
or     %edi,%esi
mov    %esi,(%rax,%rdx,4)
add    $0x1,%rdx
cmp    %rdx,%r9
jne    1250 <rrotate+0x150>
ret
xor    %edi,%edi
test   $0x1,%r8b
jne    11f6 <rrotate+0xf6>
jmp    1243 <rrotate+0x143>

LLVM IR (-O0):
define i32* @rrotate(i32* %0, i32 %1, i32 %2) {
%4 = alloca i32*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i32* %0, i32** %4
store i32 %1, i32* %5
store i32 %2, i32* %6
store i32 0, i32* %7
store i32 0, i32* %8
br label %9
9: ; preds = %36, %3
%10 = load i32, i32* %8
%11 = load i32, i32* %6
%12 = icmp slt i32 %10, %11
br i1 %12, label %13, label %39
13: ; preds = %9
%14 = load i32*, i32** %4
%15 = load i32, i32* %8
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds i32, i32* %14, i64 %16
%18 = load i32, i32* %17
%19 = and i32 %18, 1
store i32 %19, i32* %7
%20 = load i32, i32* %5
%21 = sub i32 %20, 1
%22 = load i32, i32* %7
%23 = shl i32 %22, %21
store i32 %23, i32* %7
%24 = load i32, i32* %7
%25 = load i32*, i32** %4
%26 = load i32, i32* %8
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i32, i32* %25, i64 %27
%29 = load i32, i32* %28
%30 = ashr i32 %29, 1
%31 = or i32 %24, %30
%32 = load i32*, i32** %4
%33 = load i32, i32* %8
%34 = sext i32 %33 to i64
%35 = getelementptr inbounds i32, i32* %32, i64 %34
store i32 %31, i32* %35
br label %36
36: ; preds = %13
%37 = load i32, i32* %8
%38 = add nsw i32 %37, 1
store i32 %38, i32* %8
br label %9
39: ; preds = %9
%40 = load i32*, i32** %4
ret i32* %40
}

LLVM IR (-O2):
define i32* @rrotate(i32* returned %0, i32 %1, i32 %2) {
%4 = icmp sgt i32 %2, 0
br i1 %4, label %5, label %85
5: ; preds = %3
%6 = add i32 %1, -1
%7 = zext i32 %2 to i64
%8 = icmp ult i32 %2, 8
br i1 %8, label %83, label %9
9: ; preds = %5
%10 = and i64 %7, 4294967288
%11 = insertelement <4 x i32> poison, i32 %6, i64 0
%12 = shufflevector <4 x i32> %11, <4 x i32> poison, <4 x i32> zeroinitializer
%13 = insertelement <4 x i32> poison, i32 %6, i64 0
%14 = shufflevector <4 x i32> %13, <4 x i32> poison, <4 x i32> zeroinitializer
%15 = add nsw i64 %10, -8
%16 = lshr exact i64 %15, 3
%17 = add nuw nsw i64 %16, 1
%18 = and i64 %17, 1
%19 = icmp eq i64 %15, 0
br i1 %19, label %61, label %20
20: ; preds = %9
%21 = and i64 %17, 4611686018427387902
br label %22
22: ; preds = %22, %20
%23 = phi i64 [ 0, %20 ], [ %58, %22 ]
%24 = phi i64 [ 0, %20 ], [ %59, %22 ]
%25 = getelementptr inbounds i32, i32* %0, i64 %23
%26 = bitcast i32* %25 to <4 x i32>*
%27 = load <4 x i32>, <4 x i32>* %26
%28 = getelementptr inbounds i32, i32* %25, i64 4
%29 = bitcast i32* %28 to <4 x i32>*
%30 = load <4 x i32>, <4 x i32>* %29
%31 = and <4 x i32> %27, <i32 1, i32 1, i32 1, i32 1>
%32 = and <4 x i32> %30, <i32 1, i32 1, i32 1, i32 1>
%33 = shl nuw <4 x i32> %31, %12
%34 = shl nuw <4 x i32> %32, %14
%35 = ashr <4 x i32> %27, <i32 1, i32 1, i32 1, i32 1>
%36 = ashr <4 x i32> %30, <i32 1, i32 1, i32 1, i32 1>
%37 = or <4 x i32> %33, %35
%38 = or <4 x i32> %34, %36
%39 = bitcast i32* %25 to <4 x i32>*
store <4 x i32> %37, <4 x i32>* %39
%40 = bitcast i32* %28 to <4 x i32>*
store <4 x i32> %38, <4 x i32>* %40
%41 = or i64 %23, 8
%42 = getelementptr inbounds i32, i32* %0, i64 %41
%43 = bitcast i32* %42 to <4 x i32>*
%44 = load <4 x i32>, <4 x i32>* %43
%45 = getelementptr inbounds i32, i32* %42, i64 4
%46 = bitcast i32* %45 to <4 x i32>*
%47 = load <4 x i32>, <4 x i32>* %46
%48 = and <4 x i32> %44, <i32 1, i32 1, i32 1, i32 1>
%49 = and <4 x i32> %47, <i32 1, i32 1, i32 1, i32 1>
%50 = shl nuw <4 x i32> %48, %12
%51 = shl nuw <4 x i32> %49, %14
%52 = ashr <4 x i32> %44, <i32 1, i32 1, i32 1, i32 1>
%53 = ashr <4 x i32> %47, <i32 1, i32 1, i32 1, i32 1>
%54 = or <4 x i32> %50, %52
%55 = or <4 x i32> %51, %53
%56 = bitcast i32* %42 to <4 x i32>*
store <4 x i32> %54, <4 x i32>* %56
%57 = bitcast i32* %45 to <4 x i32>*
store <4 x i32> %55, <4 x i32>* %57
%58 = add nuw i64 %23, 16
%59 = add i64 %24, 2
%60 = icmp eq i64 %59, %21
br i1 %60, label %61, label %22
61: ; preds = %22, %9
%62 = phi i64 [ 0, %9 ], [ %58, %22 ]
%63 = icmp eq i64 %18, 0
br i1 %63, label %81, label %64
64: ; preds = %61
%65 = getelementptr inbounds i32, i32* %0, i64 %62
%66 = bitcast i32* %65 to <4 x i32>*
%67 = load <4 x i32>, <4 x i32>* %66
%68 = getelementptr inbounds i32, i32* %65, i64 4
%69 = bitcast i32* %68 to <4 x i32>*
%70 = load <4 x i32>, <4 x i32>* %69
%71 = and <4 x i32> %67, <i32 1, i32 1, i32 1, i32 1>
%72 = and <4 x i32> %70, <i32 1, i32 1, i32 1, i32 1>
%73 = shl nuw <4 x i32> %71, %12
%74 = shl nuw <4 x i32> %72, %14
%75 = ashr <4 x i32> %67, <i32 1, i32 1, i32 1, i32 1>
%76 = ashr <4 x i32> %70, <i32 1, i32 1, i32 1, i32 1>
%77 = or <4 x i32> %73, %75
%78 = or <4 x i32> %74, %76
%79 = bitcast i32* %65 to <4 x i32>*
store <4 x i32> %77, <4 x i32>* %79
%80 = bitcast i32* %68 to <4 x i32>*
store <4 x i32> %78, <4 x i32>* %80
br label %81
81: ; preds = %61, %64
%82 = icmp eq i64 %10, %7
br i1 %82, label %85, label %83
83: ; preds = %5, %81
%84 = phi i64 [ 0, %5 ], [ %10, %81 ]
br label %86
85: ; preds = %86, %81, %3
ret i32* %0
86: ; preds = %83, %86
%87 = phi i64 [ %94, %86 ], [ %84, %83 ]
%88 = getelementptr inbounds i32, i32* %0, i64 %87
%89 = load i32, i32* %88
%90 = and i32 %89, 1
%91 = shl nuw i32 %90, %6
%92 = ashr i32 %89, 1
%93 = or i32 %91, %92
store i32 %93, i32* %88
%94 = add nuw nsw i64 %87, 1
%95 = icmp eq i64 %94, %7
br i1 %95, label %85, label %86
}