#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 mod_c(const int *restrict input, int *restrict output) {
  static const int cos_mod[32] = {
      1048892,  1051425,  1056522,   1064244,  1074689,  1087987,  1104313,
      1123884,  1146975,  1173922,   1205139,  1241133,  1282529,  1330095,
      1384791,  1447815,  -1520688,  -1605358, -1704360, -1821051, -1959964,
      -2127368, -2332183, -2587535,  -2913561, -3342802, -3931480, -4785806,
      -6133390, -8566050, -14253820, -42727120};
  for (int i = 0; i < 16; i++)
    output[i] = mul23(cos_mod[i], input[i] + input[16 + i]);
  for (int i = 16, k = 15; i < 32; i++, k--)
    output[i] = mul23(cos_mod[i], input[k] - input[16 + k]);
}


x86 assembly (clang, -O0):
<mod_c>:
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    117a <mod_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    $0x10,%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 <mod_c+0x17>
movl   $0x10,-0x18(%rbp)
movl   $0xf,-0x1c(%rbp)
cmpl   $0x20,-0x18(%rbp)
jge    11e4 <mod_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    $0x10,%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 <mod_c+0x78>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mod_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    0x40(%r12,%rbx,1),%esi
add    (%r12,%rbx,1),%esi
call   1030 <mul23@plt>
mov    %eax,(%r14,%rbx,1)
add    $0x4,%rbx
cmp    $0x40,%rbx
jne    1130 <mod_c+0x20>
add    $0x7c,%r12
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
mov    0x40(%r15,%rbx,4),%edi
mov    -0x40(%r12),%esi
sub    (%r12),%esi
call   1030 <mul23@plt>
mov    %eax,0x40(%r14,%rbx,4)
add    $0x1,%rbx
add    $0xfffffffffffffffc,%r12
cmp    $0x10,%rbx
jne    1160 <mod_c+0x50>
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
@mod_c.cos_mod = internal constant [32 x i32] [i32 1048892, i32 1051425, i32 1056522, i32 1064244, i32 1074689, i32 1087987, i32 1104313, i32 1123884, i32 1146975, i32 1173922, i32 1205139, i32 1241133, i32 1282529, i32 1330095, i32 1384791, i32 1447815, i32 -1520688, i32 -1605358, i32 -1704360, i32 -1821051, i32 -1959964, i32 -2127368, i32 -2332183, i32 -2587535, i32 -2913561, i32 -3342802, i32 -3931480, i32 -4785806, i32 -6133390, i32 -8566050, i32 -14253820, i32 -42727120]
define void @mod_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, 16
br i1 %10, label %11, label %36
11: ; preds = %8
%12 = load i32, i32* %5
%13 = sext i32 %12 to i64
%14 = getelementptr inbounds [32 x i32], [32 x i32]* @mod_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 16, %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 16, i32* %6
store i32 15, i32* %7
br label %37
37: ; preds = %62, %36
%38 = load i32, i32* %6
%39 = icmp slt i32 %38, 32
br i1 %39, label %40, label %67
40: ; preds = %37
%41 = load i32, i32* %6
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds [32 x i32], [32 x i32]* @mod_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 16, %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):
@mod_c.cos_mod = internal unnamed_addr constant [32 x i32] [i32 1048892, i32 1051425, i32 1056522, i32 1064244, i32 1074689, i32 1087987, i32 1104313, i32 1123884, i32 1146975, i32 1173922, i32 1205139, i32 1241133, i32 1282529, i32 1330095, i32 1384791, i32 1447815, i32 -1520688, i32 -1605358, i32 -1704360, i32 -1821051, i32 -1959964, i32 -2127368, i32 -2332183, i32 -2587535, i32 -2913561, i32 -3342802, i32 -3931480, i32 -4785806, i32 -6133390, i32 -8566050, i32 -14253820, i32 -42727120]
define void @mod_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 [32 x i32], [32 x i32]* @mod_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, 16
%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, 16
br i1 %16, label %18, label %3
17: ; preds = %18
ret void
18: ; preds = %3, %18
%19 = phi i64 [ %31, %18 ], [ 16, %3 ]
%20 = phi i64 [ %32, %18 ], [ 15, %3 ]
%21 = getelementptr inbounds [32 x i32], [32 x i32]* @mod_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, 16
%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, 32
br i1 %33, label %17, label %18
}