#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);
void mod64_b(int *restrict input, int *restrict output) {
  static const int cos_mod[16] = {4199362,  4240198,  4323885,  4454708,
                                  4639772,  4890013,  5221943,  5660703,
                                  6245623,  7040975,  8158494,  9809974,
                                  12450076, 17261920, 28585092, 85479984};
  for (int i = 0; i < 16; i++)
    input[16 + i] = mul23(cos_mod[i], input[16 + i]);
  for (int i = 0; i < 16; i++)
    output[i] = input[i] + input[16 + i];
  for (int i = 16, k = 15; i < 32; i++, k--)
    output[i] = input[k] - input[16 + k];
}


x86 assembly (clang, -O0):
<mod64_b>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
cmpl   $0x10,-0x14(%rbp)
jge    1174 <mod64_b+0x64>
movslq -0x14(%rbp),%rcx
lea    0xec4(%rip),%rax
mov    (%rax,%rcx,4),%edi
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x10,%ecx
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%esi
call   1030 <mul23@plt>
mov    %eax,%edx
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x10,%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1127 <mod64_b+0x17>
movl   $0x0,-0x18(%rbp)
cmpl   $0x10,-0x18(%rbp)
jge    11b9 <mod64_b+0xa9>
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
add    $0x10,%ecx
movslq %ecx,%rcx
add    (%rax,%rcx,4),%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)
jmp    117b <mod64_b+0x6b>
movl   $0x10,-0x1c(%rbp)
movl   $0xf,-0x20(%rbp)
cmpl   $0x20,-0x1c(%rbp)
jge    120e <mod64_b+0xfe>
mov    -0x8(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%ecx
add    $0x10,%ecx
movslq %ecx,%rcx
sub    (%rax,%rcx,4),%edx
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x20(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x20(%rbp)
jmp    11c7 <mod64_b+0xb7>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mod64_b>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rsi,%r14
mov    %rdi,%r15
xor    %ebx,%ebx
lea    0xed6(%rip),%r12
nopw   0x0(%rax,%rax,1)
mov    (%rbx,%r12,1),%edi
mov    0x40(%r15,%rbx,1),%esi
call   1030 <mul23@plt>
mov    %eax,0x40(%r15,%rbx,1)
add    $0x4,%rbx
cmp    $0x40,%rbx
jne    1130 <mod64_b+0x20>
movdqu (%r15),%xmm0
movdqu 0x40(%r15),%xmm1
paddd  %xmm0,%xmm1
movdqu %xmm1,(%r14)
movdqu 0x10(%r15),%xmm0
movdqu 0x50(%r15),%xmm1
movdqa %xmm1,%xmm2
paddd  %xmm0,%xmm2
movdqu %xmm2,0x10(%r14)
mov    0x20(%r15),%r12d
mov    0x60(%r15),%r8d
lea    (%r8,%r12,1),%ecx
mov    %ecx,0x20(%r14)
mov    0x24(%r15),%edx
mov    0x64(%r15),%r9d
lea    (%r9,%rdx,1),%ecx
mov    %ecx,0x24(%r14)
mov    0x28(%r15),%edi
mov    0x68(%r15),%r10d
lea    (%r10,%rdi,1),%ecx
mov    %ecx,0x28(%r14)
mov    0x2c(%r15),%esi
mov    0x6c(%r15),%r11d
lea    (%r11,%rsi,1),%ebx
mov    %ebx,0x2c(%r14)
mov    0x30(%r15),%ebx
mov    0x70(%r15),%r13d
lea    0x0(%r13,%rbx,1),%ebp
mov    %ebp,0x30(%r14)
mov    0x34(%r15),%ebp
mov    0x74(%r15),%eax
lea    (%rax,%rbp,1),%ecx
mov    %ecx,0x34(%r14)
movq   0x38(%r15),%xmm2
movq   0x78(%r15),%xmm3
movdqa %xmm3,%xmm4
paddd  %xmm2,%xmm4
psubd  %xmm3,%xmm2
shufps $0x14,%xmm2,%xmm4
movups %xmm4,0x38(%r14)
sub    %eax,%ebp
mov    %ebp,0x48(%r14)
sub    %r13d,%ebx
mov    %ebx,0x4c(%r14)
sub    %r11d,%esi
mov    %esi,0x50(%r14)
sub    %r10d,%edi
mov    %edi,0x54(%r14)
sub    %r9d,%edx
mov    %edx,0x58(%r14)
sub    %r8d,%r12d
mov    %r12d,0x5c(%r14)
psubd  %xmm1,%xmm0
pshufd $0xff,%xmm0,%xmm1
movd   %xmm1,0x60(%r14)
pshufd $0xee,%xmm0,%xmm0
movd   %xmm0,0x64(%r14)
movdqu 0x8(%r15),%xmm0
movdqu 0x48(%r15),%xmm1
psubd  %xmm1,%xmm0
pshufd $0x1b,%xmm0,%xmm0
movdqu %xmm0,0x68(%r14)
mov    0x4(%r15),%eax
sub    0x44(%r15),%eax
mov    %eax,0x78(%r14)
mov    (%r15),%eax
sub    0x40(%r15),%eax
mov    %eax,0x7c(%r14)
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@mod64_b.cos_mod = internal constant [16 x i32] [i32 4199362, i32 4240198, i32 4323885, i32 4454708, i32 4639772, i32 4890013, i32 5221943, i32 5660703, i32 6245623, i32 7040975, i32 8158494, i32 9809974, i32 12450076, i32 17261920, i32 28585092, i32 85479984]
define void @mod64_b(i32* noalias %0, i32* noalias %1) {
%3 = alloca i32*
%4 = alloca i32*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i32* %0, i32** %3
store i32* %1, i32** %4
store i32 0, i32* %5
br label %9
9: ; preds = %29, %2
%10 = load i32, i32* %5
%11 = icmp slt i32 %10, 16
br i1 %11, label %12, label %32
12: ; preds = %9
%13 = load i32, i32* %5
%14 = sext i32 %13 to i64
%15 = getelementptr inbounds [16 x i32], [16 x i32]* @mod64_b.cos_mod, i64 0, i64 %14
%16 = load i32, i32* %15
%17 = load i32*, i32** %3
%18 = load i32, i32* %5
%19 = add nsw i32 16, %18
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds i32, i32* %17, i64 %20
%22 = load i32, i32* %21
%23 = call i32 @mul23(i32 %16, i32 %22)
%24 = load i32*, i32** %3
%25 = load i32, i32* %5
%26 = add nsw i32 16, %25
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i32, i32* %24, i64 %27
store i32 %23, i32* %28
br label %29
29: ; preds = %12
%30 = load i32, i32* %5
%31 = add nsw i32 %30, 1
store i32 %31, i32* %5
br label %9
32: ; preds = %9
store i32 0, i32* %6
br label %33
33: ; preds = %53, %32
%34 = load i32, i32* %6
%35 = icmp slt i32 %34, 16
br i1 %35, label %36, label %56
36: ; preds = %33
%37 = load i32*, i32** %3
%38 = load i32, i32* %6
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds i32, i32* %37, i64 %39
%41 = load i32, i32* %40
%42 = load i32*, i32** %3
%43 = load i32, i32* %6
%44 = add nsw i32 16, %43
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds i32, i32* %42, i64 %45
%47 = load i32, i32* %46
%48 = add nsw i32 %41, %47
%49 = load i32*, i32** %4
%50 = load i32, i32* %6
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds i32, i32* %49, i64 %51
store i32 %48, i32* %52
br label %53
53: ; preds = %36
%54 = load i32, i32* %6
%55 = add nsw i32 %54, 1
store i32 %55, i32* %6
br label %33
56: ; preds = %33
store i32 16, i32* %7
store i32 15, i32* %8
br label %57
57: ; preds = %77, %56
%58 = load i32, i32* %7
%59 = icmp slt i32 %58, 32
br i1 %59, label %60, label %82
60: ; preds = %57
%61 = load i32*, i32** %3
%62 = load i32, i32* %8
%63 = sext i32 %62 to i64
%64 = getelementptr inbounds i32, i32* %61, i64 %63
%65 = load i32, i32* %64
%66 = load i32*, i32** %3
%67 = load i32, i32* %8
%68 = add nsw i32 16, %67
%69 = sext i32 %68 to i64
%70 = getelementptr inbounds i32, i32* %66, i64 %69
%71 = load i32, i32* %70
%72 = sub nsw i32 %65, %71
%73 = load i32*, i32** %4
%74 = load i32, i32* %7
%75 = sext i32 %74 to i64
%76 = getelementptr inbounds i32, i32* %73, i64 %75
store i32 %72, i32* %76
br label %77
77: ; preds = %60
%78 = load i32, i32* %7
%79 = add nsw i32 %78, 1
store i32 %79, i32* %7
%80 = load i32, i32* %8
%81 = add nsw i32 %80, -1
store i32 %81, i32* %8
br label %57
82: ; preds = %57
ret void
}

LLVM IR (-O2):
@mod64_b.cos_mod = internal unnamed_addr constant [16 x i32] [i32 4199362, i32 4240198, i32 4323885, i32 4454708, i32 4639772, i32 4890013, i32 5221943, i32 5660703, i32 6245623, i32 7040975, i32 8158494, i32 9809974, i32 12450076, i32 17261920, i32 28585092, i32 85479984]
define void @mod64_b(i32* noalias nocapture %0, i32* noalias nocapture writeonly %1) {
br label %3
3: ; preds = %2, %3
%4 = phi i64 [ 0, %2 ], [ %11, %3 ]
%5 = getelementptr inbounds [16 x i32], [16 x i32]* @mod64_b.cos_mod, i64 0, i64 %4
%6 = load i32, i32* %5
%7 = add nuw nsw i64 %4, 16
%8 = getelementptr inbounds i32, i32* %0, i64 %7
%9 = load i32, i32* %8
%10 = tail call i32 @mul23(i32 %6, i32 %9)
store i32 %10, i32* %8
%11 = add nuw nsw i64 %4, 1
%12 = icmp eq i64 %11, 16
br i1 %12, label %13, label %3
13: ; preds = %3
%14 = getelementptr inbounds i32, i32* %0, i64 16
%15 = getelementptr inbounds i32, i32* %0, i64 1
%16 = getelementptr inbounds i32, i32* %0, i64 17
%17 = getelementptr inbounds i32, i32* %0, i64 2
%18 = getelementptr inbounds i32, i32* %0, i64 18
%19 = bitcast i32* %0 to <4 x i32>*
%20 = load <4 x i32>, <4 x i32>* %19
%21 = bitcast i32* %14 to <4 x i32>*
%22 = load <4 x i32>, <4 x i32>* %21
%23 = add nsw <4 x i32> %22, %20
%24 = bitcast i32* %1 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %24
%25 = getelementptr inbounds i32, i32* %0, i64 4
%26 = getelementptr inbounds i32, i32* %0, i64 20
%27 = getelementptr inbounds i32, i32* %1, i64 4
%28 = bitcast i32* %25 to <4 x i32>*
%29 = load <4 x i32>, <4 x i32>* %28
%30 = bitcast i32* %26 to <4 x i32>*
%31 = load <4 x i32>, <4 x i32>* %30
%32 = add nsw <4 x i32> %31, %29
%33 = bitcast i32* %27 to <4 x i32>*
store <4 x i32> %32, <4 x i32>* %33
%34 = getelementptr inbounds i32, i32* %0, i64 8
%35 = load i32, i32* %34
%36 = getelementptr inbounds i32, i32* %0, i64 24
%37 = load i32, i32* %36
%38 = add nsw i32 %37, %35
%39 = getelementptr inbounds i32, i32* %1, i64 8
store i32 %38, i32* %39
%40 = getelementptr inbounds i32, i32* %0, i64 9
%41 = load i32, i32* %40
%42 = getelementptr inbounds i32, i32* %0, i64 25
%43 = load i32, i32* %42
%44 = add nsw i32 %43, %41
%45 = getelementptr inbounds i32, i32* %1, i64 9
store i32 %44, i32* %45
%46 = getelementptr inbounds i32, i32* %0, i64 10
%47 = load i32, i32* %46
%48 = getelementptr inbounds i32, i32* %0, i64 26
%49 = load i32, i32* %48
%50 = add nsw i32 %49, %47
%51 = getelementptr inbounds i32, i32* %1, i64 10
store i32 %50, i32* %51
%52 = getelementptr inbounds i32, i32* %0, i64 11
%53 = load i32, i32* %52
%54 = getelementptr inbounds i32, i32* %0, i64 27
%55 = load i32, i32* %54
%56 = add nsw i32 %55, %53
%57 = getelementptr inbounds i32, i32* %1, i64 11
store i32 %56, i32* %57
%58 = getelementptr inbounds i32, i32* %0, i64 12
%59 = load i32, i32* %58
%60 = getelementptr inbounds i32, i32* %0, i64 28
%61 = load i32, i32* %60
%62 = add nsw i32 %61, %59
%63 = getelementptr inbounds i32, i32* %1, i64 12
store i32 %62, i32* %63
%64 = getelementptr inbounds i32, i32* %0, i64 13
%65 = load i32, i32* %64
%66 = getelementptr inbounds i32, i32* %0, i64 29
%67 = load i32, i32* %66
%68 = add nsw i32 %67, %65
%69 = getelementptr inbounds i32, i32* %1, i64 13
store i32 %68, i32* %69
%70 = getelementptr inbounds i32, i32* %0, i64 14
%71 = getelementptr inbounds i32, i32* %0, i64 30
%72 = getelementptr inbounds i32, i32* %1, i64 14
%73 = bitcast i32* %70 to <2 x i32>*
%74 = load <2 x i32>, <2 x i32>* %73
%75 = bitcast i32* %71 to <2 x i32>*
%76 = load <2 x i32>, <2 x i32>* %75
%77 = shufflevector <2 x i32> %76, <2 x i32> %74, <4 x i32> <i32 0, i32 1, i32 3, i32 2>
%78 = shufflevector <2 x i32> %74, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
%79 = shufflevector <2 x i32> %76, <2 x i32> poison, <4 x i32> <i32 1, i32 0, i32 undef, i32 undef>
%80 = shufflevector <4 x i32> %78, <4 x i32> %79, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
%81 = add nsw <4 x i32> %77, %80
%82 = sub nsw <4 x i32> %77, %80
%83 = shufflevector <4 x i32> %81, <4 x i32> %82, <4 x i32> <i32 0, i32 1, i32 6, i32 7>
%84 = bitcast i32* %72 to <4 x i32>*
store <4 x i32> %83, <4 x i32>* %84
%85 = sub nsw i32 %65, %67
%86 = getelementptr inbounds i32, i32* %1, i64 18
store i32 %85, i32* %86
%87 = sub nsw i32 %59, %61
%88 = getelementptr inbounds i32, i32* %1, i64 19
store i32 %87, i32* %88
%89 = sub nsw i32 %53, %55
%90 = getelementptr inbounds i32, i32* %1, i64 20
store i32 %89, i32* %90
%91 = sub nsw i32 %47, %49
%92 = getelementptr inbounds i32, i32* %1, i64 21
store i32 %91, i32* %92
%93 = sub nsw i32 %41, %43
%94 = getelementptr inbounds i32, i32* %1, i64 22
store i32 %93, i32* %94
%95 = sub nsw i32 %35, %37
%96 = getelementptr inbounds i32, i32* %1, i64 23
store i32 %95, i32* %96
%97 = sub nsw <4 x i32> %29, %31
%98 = extractelement <4 x i32> %97, i64 3
%99 = getelementptr inbounds i32, i32* %1, i64 24
store i32 %98, i32* %99
%100 = sub nsw <4 x i32> %29, %31
%101 = extractelement <4 x i32> %100, i64 2
%102 = getelementptr inbounds i32, i32* %1, i64 25
store i32 %101, i32* %102
%103 = getelementptr inbounds i32, i32* %1, i64 26
%104 = bitcast i32* %17 to <4 x i32>*
%105 = load <4 x i32>, <4 x i32>* %104
%106 = bitcast i32* %18 to <4 x i32>*
%107 = load <4 x i32>, <4 x i32>* %106
%108 = sub nsw <4 x i32> %105, %107
%109 = shufflevector <4 x i32> %108, <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%110 = bitcast i32* %103 to <4 x i32>*
store <4 x i32> %109, <4 x i32>* %110
%111 = load i32, i32* %15
%112 = load i32, i32* %16
%113 = sub nsw i32 %111, %112
%114 = getelementptr inbounds i32, i32* %1, i64 30
store i32 %113, i32* %114
%115 = load i32, i32* %0
%116 = load i32, i32* %14
%117 = sub nsw i32 %115, %116
%118 = getelementptr inbounds i32, i32* %1, i64 31
store i32 %117, i32* %118
ret void
}