#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 */

/* Variables and functions */
int mul23(int const, int const);
void mod64_c(const int *restrict input, int *restrict output) {
  static const int cos_mod[64] = {
      741511,   741958,   742853,   744199,   746001,   748262,    750992,
      754197,   757888,   762077,   766777,   772003,   777772,    784105,
      791021,   798546,   806707,   815532,   825054,   835311,    846342,
      858193,   870912,   884554,   899181,   914860,   931667,    949686,
      969011,   989747,   1012012,  1035941,  -1061684, -1089412,  -1119320,
      -1151629, -1186595, -1224511, -1265719, -1310613, -1359657,  -1413400,
      -1472490, -1537703, -1609974, -1690442, -1780506, -1881904,  -1996824,
      -2128058, -2279225, -2455101, -2662128, -2909200, -3208956,  -3579983,
      -4050785, -4667404, -5509372, -6726913, -8641940, -12091426, -20144284,
      -60420720};
  for (int i = 0; i < 32; i++)
    output[i] = mul23(cos_mod[i], input[i] + input[32 + i]);
  for (int i = 32, k = 31; i < 64; i++, k--)
    output[i] = mul23(cos_mod[i], input[k] - input[32 + k]);
}


x86 assembly (clang, -O0):
<mod64_c>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
cmpl   $0x20,-0x14(%rbp)
jge    117a <mod64_c+0x6a>
movslq -0x14(%rbp),%rcx
lea    0xec4(%rip),%rax
mov    (%rax,%rcx,4),%edi
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,4),%esi
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x20,%ecx
movslq %ecx,%rcx
add    (%rax,%rcx,4),%esi
call   1030 <mul23@plt>
mov    %eax,%edx
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1127 <mod64_c+0x17>
movl   $0x20,-0x18(%rbp)
movl   $0x1f,-0x1c(%rbp)
cmpl   $0x40,-0x18(%rbp)
jge    11e4 <mod64_c+0xd4>
movslq -0x18(%rbp),%rcx
lea    0xe63(%rip),%rax
mov    (%rax,%rcx,4),%edi
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,4),%esi
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x20,%ecx
movslq %ecx,%rcx
sub    (%rax,%rcx,4),%esi
call   1030 <mul23@plt>
mov    %eax,%edx
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    1188 <mod64_c+0x78>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mod64_c>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    %rsi,%r14
mov    %rdi,%r12
xor    %ebx,%ebx
lea    0xed9(%rip),%r15
nopw   0x0(%rax,%rax,1)
mov    (%rbx,%r15,1),%edi
mov    0x80(%r12,%rbx,1),%esi
add    (%r12,%rbx,1),%esi
call   1030 <mul23@plt>
mov    %eax,(%r14,%rbx,1)
add    $0x4,%rbx
cmp    $0x80,%rbx
jne    1130 <mod64_c+0x20>
add    $0xfc,%r12
xor    %ebx,%ebx
nop
mov    0x80(%r15,%rbx,4),%edi
mov    -0x80(%r12),%esi
sub    (%r12),%esi
call   1030 <mul23@plt>
mov    %eax,0x80(%r14,%rbx,4)
add    $0x1,%rbx
add    $0xfffffffffffffffc,%r12
cmp    $0x20,%rbx
jne    1160 <mod64_c+0x50>
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@mod64_c.cos_mod = internal constant [64 x i32] [i32 741511, i32 741958, i32 742853, i32 744199, i32 746001, i32 748262, i32 750992, i32 754197, i32 757888, i32 762077, i32 766777, i32 772003, i32 777772, i32 784105, i32 791021, i32 798546, i32 806707, i32 815532, i32 825054, i32 835311, i32 846342, i32 858193, i32 870912, i32 884554, i32 899181, i32 914860, i32 931667, i32 949686, i32 969011, i32 989747, i32 1012012, i32 1035941, i32 -1061684, i32 -1089412, i32 -1119320, i32 -1151629, i32 -1186595, i32 -1224511, i32 -1265719, i32 -1310613, i32 -1359657, i32 -1413400, i32 -1472490, i32 -1537703, i32 -1609974, i32 -1690442, i32 -1780506, i32 -1881904, i32 -1996824, i32 -2128058, i32 -2279225, i32 -2455101, i32 -2662128, i32 -2909200, i32 -3208956, i32 -3579983, i32 -4050785, i32 -4667404, i32 -5509372, i32 -6726913, i32 -8641940, i32 -12091426, i32 -20144284, i32 -60420720]
define void @mod64_c(i32* noalias %0, i32* noalias %1) {
%3 = alloca i32*
%4 = alloca i32*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
store i32* %0, i32** %3
store i32* %1, i32** %4
store i32 0, i32* %5
br label %8
8: ; preds = %33, %2
%9 = load i32, i32* %5
%10 = icmp slt i32 %9, 32
br i1 %10, label %11, label %36
11: ; preds = %8
%12 = load i32, i32* %5
%13 = sext i32 %12 to i64
%14 = getelementptr inbounds [64 x i32], [64 x i32]* @mod64_c.cos_mod, i64 0, i64 %13
%15 = load i32, i32* %14
%16 = load i32*, i32** %3
%17 = load i32, i32* %5
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds i32, i32* %16, i64 %18
%20 = load i32, i32* %19
%21 = load i32*, i32** %3
%22 = load i32, i32* %5
%23 = add nsw i32 32, %22
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds i32, i32* %21, i64 %24
%26 = load i32, i32* %25
%27 = add nsw i32 %20, %26
%28 = call i32 @mul23(i32 %15, i32 %27)
%29 = load i32*, i32** %4
%30 = load i32, i32* %5
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds i32, i32* %29, i64 %31
store i32 %28, i32* %32
br label %33
33: ; preds = %11
%34 = load i32, i32* %5
%35 = add nsw i32 %34, 1
store i32 %35, i32* %5
br label %8
36: ; preds = %8
store i32 32, i32* %6
store i32 31, i32* %7
br label %37
37: ; preds = %62, %36
%38 = load i32, i32* %6
%39 = icmp slt i32 %38, 64
br i1 %39, label %40, label %67
40: ; preds = %37
%41 = load i32, i32* %6
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds [64 x i32], [64 x i32]* @mod64_c.cos_mod, i64 0, i64 %42
%44 = load i32, i32* %43
%45 = load i32*, i32** %3
%46 = load i32, i32* %7
%47 = sext i32 %46 to i64
%48 = getelementptr inbounds i32, i32* %45, i64 %47
%49 = load i32, i32* %48
%50 = load i32*, i32** %3
%51 = load i32, i32* %7
%52 = add nsw i32 32, %51
%53 = sext i32 %52 to i64
%54 = getelementptr inbounds i32, i32* %50, i64 %53
%55 = load i32, i32* %54
%56 = sub nsw i32 %49, %55
%57 = call i32 @mul23(i32 %44, i32 %56)
%58 = load i32*, i32** %4
%59 = load i32, i32* %6
%60 = sext i32 %59 to i64
%61 = getelementptr inbounds i32, i32* %58, i64 %60
store i32 %57, i32* %61
br label %62
62: ; preds = %40
%63 = load i32, i32* %6
%64 = add nsw i32 %63, 1
store i32 %64, i32* %6
%65 = load i32, i32* %7
%66 = add nsw i32 %65, -1
store i32 %66, i32* %7
br label %37
67: ; preds = %37
ret void
}

LLVM IR (-O2):
@mod64_c.cos_mod = internal unnamed_addr constant [64 x i32] [i32 741511, i32 741958, i32 742853, i32 744199, i32 746001, i32 748262, i32 750992, i32 754197, i32 757888, i32 762077, i32 766777, i32 772003, i32 777772, i32 784105, i32 791021, i32 798546, i32 806707, i32 815532, i32 825054, i32 835311, i32 846342, i32 858193, i32 870912, i32 884554, i32 899181, i32 914860, i32 931667, i32 949686, i32 969011, i32 989747, i32 1012012, i32 1035941, i32 -1061684, i32 -1089412, i32 -1119320, i32 -1151629, i32 -1186595, i32 -1224511, i32 -1265719, i32 -1310613, i32 -1359657, i32 -1413400, i32 -1472490, i32 -1537703, i32 -1609974, i32 -1690442, i32 -1780506, i32 -1881904, i32 -1996824, i32 -2128058, i32 -2279225, i32 -2455101, i32 -2662128, i32 -2909200, i32 -3208956, i32 -3579983, i32 -4050785, i32 -4667404, i32 -5509372, i32 -6726913, i32 -8641940, i32 -12091426, i32 -20144284, i32 -60420720]
define void @mod64_c(i32* noalias nocapture %0, i32* noalias nocapture writeonly %1) {
br label %3
3: ; preds = %2, %3
%4 = phi i64 [ 0, %2 ], [ %15, %3 ]
%5 = getelementptr inbounds [64 x i32], [64 x i32]* @mod64_c.cos_mod, i64 0, i64 %4
%6 = load i32, i32* %5
%7 = getelementptr inbounds i32, i32* %0, i64 %4
%8 = load i32, i32* %7
%9 = add nuw nsw i64 %4, 32
%10 = getelementptr inbounds i32, i32* %0, i64 %9
%11 = load i32, i32* %10
%12 = add nsw i32 %11, %8
%13 = tail call i32 @mul23(i32 %6, i32 %12)
%14 = getelementptr inbounds i32, i32* %1, i64 %4
store i32 %13, i32* %14
%15 = add nuw nsw i64 %4, 1
%16 = icmp eq i64 %15, 32
br i1 %16, label %18, label %3
17: ; preds = %18
ret void
18: ; preds = %3, %18
%19 = phi i64 [ %31, %18 ], [ 32, %3 ]
%20 = phi i64 [ %32, %18 ], [ 31, %3 ]
%21 = getelementptr inbounds [64 x i32], [64 x i32]* @mod64_c.cos_mod, i64 0, i64 %19
%22 = load i32, i32* %21
%23 = getelementptr inbounds i32, i32* %0, i64 %20
%24 = load i32, i32* %23
%25 = add nuw nsw i64 %20, 32
%26 = getelementptr inbounds i32, i32* %0, i64 %25
%27 = load i32, i32* %26
%28 = sub nsw i32 %24, %27
%29 = tail call i32 @mul23(i32 %22, i32 %28)
%30 = getelementptr inbounds i32, i32* %1, i64 %19
store i32 %29, i32* %30
%31 = add nuw nsw i64 %19, 1
%32 = add nsw i64 %20, -1
%33 = icmp eq i64 %31, 64
br i1 %33, label %17, label %18
}