#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ uint64_t;

/* Variables and functions */
int /*<<< orphan*/ memcpy(int /*<<< orphan*/ *, int /*<<< orphan*/ *, int);
void rotate(uint64_t *k) {
  uint64_t temp[80];
  memcpy(temp, k, 80 * sizeof(uint64_t));
  for (size_t i = 0; i < 80; i++) {
    k[i] = temp[(i + 61) % 80];
  }
}


x86 assembly (clang, -O0):
<rotate>:
push   %rbp
mov    %rsp,%rbp
sub    $0x160,%rsp
mov    %rdi,-0x8(%rbp)
lea    -0x150(%rbp),%rdi
mov    -0x8(%rbp),%rsi
mov    $0x140,%edx
call   1030 <memcpy@plt>
movq   $0x0,-0x158(%rbp)
cmpq   $0x50,-0x158(%rbp)
50
jae    118e <rotate+0x7e>
mov    -0x158(%rbp),%rax
add    $0x3d,%rax
mov    $0x50,%ecx
xor    %edx,%edx
div    %rcx
mov    -0x150(%rbp,%rdx,4),%edx
mov    -0x8(%rbp),%rax
mov    -0x158(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x158(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x158(%rbp)
jmp    113f <rotate+0x2f>
add    $0x160,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<rotate>:
push   %r14
push   %rbx
sub    $0x148,%rsp
mov    %rdi,%r14
mov    %rsp,%rdi
mov    %r14,%rsi
mov    $0x140,%edx
call   1030 <memcpy@plt>
lea    0xf8(%rsp),%r8
lea    0xf4(%rsp),%r10
mov    $0x3e,%ecx
mov    $0xf8,%edi
mov    $0x3c,%esi
movabs $0xcccccccccccccccd,%r9
cc cc cc
cs nopw 0x0(%rax,%rax,1)
mov    %rcx,%rax
mul    %r9
and    $0xffffffffffffffc0,%rdx
lea    (%rdx,%rdx,4),%rbx
neg    %rbx
mov    %rsi,%rax
mul    %r9
and    $0xffffffffffffffc0,%rdx
lea    (%rdx,%rdx,4),%rax
neg    %rax
mov    (%r10,%rax,1),%eax
mov    %eax,-0xf8(%r14,%rdi,1)
ff
mov    (%r8,%rbx,1),%eax
mov    %eax,-0xf4(%r14,%rdi,1)
ff
add    $0x8,%r8
add    $0x2,%rcx
add    $0x8,%rdi
add    $0x8,%r10
add    $0x2,%rsi
cmp    $0x238,%rdi
jne    1160 <rotate+0x50>
add    $0x148,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define void @rotate(i32* %0) {
%2 = alloca i32*
%3 = alloca [80 x i32]
%4 = alloca i64
store i32* %0, i32** %2
%5 = getelementptr inbounds [80 x i32], [80 x i32]* %3, i64 0, i64 0
%6 = load i32*, i32** %2
%7 = call i32 @memcpy(i32* %5, i32* %6, i32 320)
store i64 0, i64* %4
br label %8
8: ; preds = %20, %1
%9 = load i64, i64* %4
%10 = icmp ult i64 %9, 80
br i1 %10, label %11, label %23
11: ; preds = %8
%12 = load i64, i64* %4
%13 = add i64 %12, 61
%14 = urem i64 %13, 80
%15 = getelementptr inbounds [80 x i32], [80 x i32]* %3, i64 0, i64 %14
%16 = load i32, i32* %15
%17 = load i32*, i32** %2
%18 = load i64, i64* %4
%19 = getelementptr inbounds i32, i32* %17, i64 %18
store i32 %16, i32* %19
br label %20
20: ; preds = %11
%21 = load i64, i64* %4
%22 = add i64 %21, 1
store i64 %22, i64* %4
br label %8
23: ; preds = %8
ret void
}

LLVM IR (-O2):
define void @rotate(i32* %0) {
%2 = alloca [80 x i32]
%3 = bitcast [80 x i32]* %2 to i8*
%4 = getelementptr inbounds [80 x i32], [80 x i32]* %2, i64 0, i64 0
%5 = call i32 @memcpy(i32* %4, i32* %0, i32 320)
br label %7
6: ; preds = %7
ret void
7: ; preds = %7, %1
%8 = phi i64 [ 0, %1 ], [ %24, %7 ]
%9 = trunc i64 %8 to i8
%10 = add nuw i8 %9, 61
%11 = urem i8 %10, 80
%12 = zext i8 %11 to i64
%13 = getelementptr inbounds [80 x i32], [80 x i32]* %2, i64 0, i64 %12
%14 = load i32, i32* %13
%15 = getelementptr inbounds i32, i32* %0, i64 %8
store i32 %14, i32* %15
%16 = or i64 %8, 1
%17 = trunc i64 %16 to i8
%18 = add nuw i8 %17, 61
%19 = urem i8 %18, 80
%20 = zext i8 %19 to i64
%21 = getelementptr inbounds [80 x i32], [80 x i32]* %2, i64 0, i64 %20
%22 = load i32, i32* %21
%23 = getelementptr inbounds i32, i32* %0, i64 %16
store i32 %22, i32* %23
%24 = add nuw nsw i64 %8, 2
%25 = icmp eq i64 %24, 80
br i1 %25, label %6, label %7
}