#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 abs(int);
size_t strlen(char const *);
void decrypt(const char *c, const char *key, char *p) {
  size_t klen = strlen(key);
  size_t clen = strlen(c);
  for (size_t i = 0; i < clen / klen; i++)
    for (size_t j = 0; j < klen; j++) {
      int tp = c[i * klen + j] - 'A' - (key[j] - 'A');
      if (tp < 0) {
        tp = 26 - abs(tp) + 26;
      }
      p[i * klen + j] = tp % 26 + 'A';
    }
}


x86 assembly (clang, -O0):
<decrypt>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,-0x28(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x28(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x20(%rbp)
mov    %rax,%rcx
mov    -0x48(%rbp),%rax
cmp    %rcx,%rax
jae    1226 <decrypt+0x106>
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    1210 <decrypt+0xf0>
mov    -0x8(%rbp),%rax
mov    -0x30(%rbp),%rcx
imul   -0x20(%rbp),%rcx
add    -0x38(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sub    $0x41,%eax
mov    -0x10(%rbp),%rcx
mov    -0x38(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
sub    $0x41,%ecx
sub    %ecx,%eax
mov    %eax,-0x3c(%rbp)
cmpl   $0x0,-0x3c(%rbp)
jge    11dd <decrypt+0xbd>
mov    -0x3c(%rbp),%edi
call   1030 <abs@plt>
mov    %eax,%ecx
mov    $0x1a,%eax
sub    %ecx,%eax
add    $0x1a,%eax
mov    %eax,-0x3c(%rbp)
mov    -0x3c(%rbp),%eax
mov    $0x1a,%ecx
cltd
idiv   %ecx
add    $0x41,%edx
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%rcx
imul   -0x20(%rbp),%rcx
add    -0x38(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    1182 <decrypt+0x62>
jmp    1215 <decrypt+0xf5>
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
jmp    1156 <decrypt+0x36>
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<decrypt>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %rdx,0x8(%rsp)
mov    %rsi,%rbx
mov    %rdi,%r15
mov    %rsi,%rdi
call   1030 <strlen@plt>
mov    %rax,%r12
mov    %r15,%rdi
call   1030 <strlen@plt>
cmp    %rax,%r12
jbe    1150 <decrypt+0x40>
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %rax,%rcx
or     %r12,%rcx
shr    $0x20,%rcx
je     1163 <decrypt+0x53>
xor    %edx,%edx
div    %r12
jmp    1168 <decrypt+0x58>
xor    %edx,%edx
div    %r12d
cmp    $0x2,%rax
mov    $0x1,%r9d
cmovae %rax,%r9
lea    (%rbx,%r12,1),%rax
mov    %rax,0x10(%rsp)
mov    %r12,%r10
and    $0xfffffffffffffff0,%r10
mov    %r12,%r11
and    $0xfffffffffffffff8,%r11
xor    %r13d,%r13d
movdqa 0xe67(%rip),%xmm13
movdqa 0xe6e(%rip),%xmm10
movdqa 0xe75(%rip),%xmm11
movdqa 0xe7c(%rip),%xmm12
movdqa 0xe93(%rip),%xmm9
movdqa 0xe7a(%rip),%xmm8
mov    %r15,%rax
mov    0x8(%rsp),%rcx
jmp    11e3 <decrypt+0xd3>
add    $0x1,%r13
add    %r12,%rcx
add    %r12,%rax
cmp    %r9,%r13
je     1141 <decrypt+0x31>
test   %r12,%r12
je     11d0 <decrypt+0xc0>
cmp    $0x8,%r12
jb     14a0 <decrypt+0x390>
mov    %r12,%rdx
imul   %r13,%rdx
mov    0x8(%rsp),%rdi
lea    (%rdi,%rdx,1),%rsi
lea    (%r12,%rdx,1),%rbp
add    %rbp,%rdi
add    %r15,%rdx
add    %r15,%rbp
cmp    %rbp,%rsi
setb   %r8b
cmp    %rdi,%rdx
setb   %r14b
cmp    0x10(%rsp),%rsi
setb   %dl
cmp    %rbx,%rdi
seta   %bpl
test   %r14b,%r8b
jne    14a0 <decrypt+0x390>
mov    $0x0,%esi
and    %bpl,%dl
jne    14b0 <decrypt+0x3a0>
xor    %edx,%edx
cmp    $0x10,%r12
jb     13d0 <decrypt+0x2c0>
nop
movdqu (%rax,%rdx,1),%xmm1
punpckhbw %xmm1,%xmm4
punpcklwd %xmm4,%xmm14
psrad  $0x18,%xmm14
punpckhwd %xmm4,%xmm7
psrad  $0x18,%xmm7
punpcklbw %xmm1,%xmm1
punpcklwd %xmm1,%xmm6
psrad  $0x18,%xmm6
punpckhwd %xmm1,%xmm1
psrad  $0x18,%xmm1
movdqu (%rbx,%rdx,1),%xmm4
punpckhbw %xmm4,%xmm5
punpcklwd %xmm5,%xmm3
psrad  $0x18,%xmm3
psubd  %xmm3,%xmm14
punpckhwd %xmm5,%xmm3
psrad  $0x18,%xmm3
psubd  %xmm3,%xmm7
punpcklbw %xmm4,%xmm3
punpcklwd %xmm3,%xmm4
psrad  $0x18,%xmm4
psubd  %xmm4,%xmm6
punpckhwd %xmm3,%xmm3
psrad  $0x18,%xmm3
psubd  %xmm3,%xmm1
pxor   %xmm4,%xmm4
pcmpgtd %xmm14,%xmm4
pxor   %xmm15,%xmm15
pcmpgtd %xmm7,%xmm15
pxor   %xmm0,%xmm0
pcmpgtd %xmm6,%xmm0
pxor   %xmm2,%xmm2
pcmpgtd %xmm1,%xmm2
movdqa %xmm14,%xmm5
paddd  %xmm13,%xmm5
movdqa %xmm2,%xmm3
pandn  %xmm1,%xmm3
paddd  %xmm13,%xmm1
pand   %xmm2,%xmm1
por    %xmm3,%xmm1
movdqa %xmm0,%xmm2
pandn  %xmm6,%xmm2
paddd  %xmm13,%xmm6
pand   %xmm0,%xmm6
por    %xmm2,%xmm6
packssdw %xmm1,%xmm6
movdqa %xmm15,%xmm0
pandn  %xmm7,%xmm0
paddd  %xmm13,%xmm7
pand   %xmm15,%xmm7
por    %xmm0,%xmm7
pand   %xmm4,%xmm5
pandn  %xmm14,%xmm4
por    %xmm5,%xmm4
packssdw %xmm7,%xmm4
movdqa %xmm6,%xmm0
pmulhw %xmm10,%xmm0
movdqa %xmm0,%xmm1
psrlw  $0xf,%xmm1
psrlw  $0x3,%xmm0
paddw  %xmm1,%xmm0
pmullw %xmm11,%xmm0
psubw  %xmm0,%xmm6
movdqa %xmm4,%xmm0
pmulhw %xmm10,%xmm0
movdqa %xmm0,%xmm1
psrlw  $0xf,%xmm1
psrlw  $0x3,%xmm0
paddw  %xmm1,%xmm0
pmullw %xmm11,%xmm0
psubw  %xmm0,%xmm4
pand   %xmm12,%xmm4
pand   %xmm12,%xmm6
packuswb %xmm4,%xmm6
paddb  %xmm8,%xmm6
movdqu %xmm6,(%rcx,%rdx,1)
add    $0x10,%rdx
cmp    %rdx,%r10
jne    1250 <decrypt+0x140>
cmp    %r10,%r12
je     11d0 <decrypt+0xc0>
mov    %r10,%rdx
mov    %r10,%rsi
test   $0x8,%r12b
je     14b0 <decrypt+0x3a0>
xchg   %ax,%ax
movq   (%rax,%rdx,1),%xmm0
punpcklbw %xmm0,%xmm0
punpcklwd %xmm0,%xmm4
psrad  $0x18,%xmm4
punpckhwd %xmm0,%xmm1
psrad  $0x18,%xmm1
movq   (%rbx,%rdx,1),%xmm0
punpcklbw %xmm0,%xmm0
punpcklwd %xmm0,%xmm2
psrad  $0x18,%xmm2
psubd  %xmm2,%xmm4
punpckhwd %xmm0,%xmm0
psrad  $0x18,%xmm0
psubd  %xmm0,%xmm1
pxor   %xmm0,%xmm0
pcmpgtd %xmm4,%xmm0
pxor   %xmm2,%xmm2
pcmpgtd %xmm1,%xmm2
movdqa %xmm2,%xmm3
pandn  %xmm1,%xmm3
paddd  %xmm13,%xmm1
pand   %xmm2,%xmm1
por    %xmm3,%xmm1
movdqa %xmm0,%xmm2
pandn  %xmm4,%xmm2
paddd  %xmm13,%xmm4
pand   %xmm0,%xmm4
por    %xmm2,%xmm4
packssdw %xmm1,%xmm4
movdqa %xmm4,%xmm0
pmulhw %xmm10,%xmm0
movdqa %xmm0,%xmm1
psrlw  $0xf,%xmm1
psrlw  $0x3,%xmm0
paddw  %xmm1,%xmm0
pmullw %xmm11,%xmm0
psubw  %xmm0,%xmm4
pand   %xmm12,%xmm4
packuswb %xmm4,%xmm4
paddb  %xmm9,%xmm4
movq   %xmm4,(%rcx,%rdx,1)
add    $0x8,%rdx
cmp    %rdx,%r11
jne    13d0 <decrypt+0x2c0>
mov    %r11,%rsi
cmp    %r11,%r12
jne    14b0 <decrypt+0x3a0>
jmp    11d0 <decrypt+0xc0>
nopl   (%rax)
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsbl (%rax,%rsi,1),%edx
movsbl (%rbx,%rsi,1),%edi
sub    %edi,%edx
lea    0x34(%rdx),%edi
test   %edx,%edx
cmovns %edx,%edi
imul   $0x4ec5,%edi,%edx
mov    %edx,%ebp
shr    $0x1f,%ebp
shr    $0x13,%edx
add    %ebp,%edx
lea    (%rdx,%rdx,4),%ebp
lea    0x0(%rbp,%rbp,4),%ebp
add    %edx,%ebp
sub    %ebp,%edi
add    $0x41,%dil
mov    %dil,(%rcx,%rsi,1)
add    $0x1,%rsi
cmp    %rsi,%r12
jne    14b0 <decrypt+0x3a0>
jmp    11d0 <decrypt+0xc0>

LLVM IR (-O0):
define void @decrypt(i8* %0, i8* %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i64
%8 = alloca i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i8* %2, i8** %6
%12 = load i8*, i8** %5
%13 = call i64 @strlen(i8* %12)
store i64 %13, i64* %7
%14 = load i8*, i8** %4
%15 = call i64 @strlen(i8* %14)
store i64 %15, i64* %8
store i64 0, i64* %9
br label %16
16: ; preds = %68, %3
%17 = load i64, i64* %9
%18 = load i64, i64* %8
%19 = load i64, i64* %7
%20 = udiv i64 %18, %19
%21 = icmp ult i64 %17, %20
br i1 %21, label %22, label %71
22: ; preds = %16
store i64 0, i64* %10
br label %23
23: ; preds = %64, %22
%24 = load i64, i64* %10
%25 = load i64, i64* %7
%26 = icmp ult i64 %24, %25
br i1 %26, label %27, label %67
27: ; preds = %23
%28 = load i8*, i8** %4
%29 = load i64, i64* %9
%30 = load i64, i64* %7
%31 = mul i64 %29, %30
%32 = load i64, i64* %10
%33 = add i64 %31, %32
%34 = getelementptr inbounds i8, i8* %28, i64 %33
%35 = load i8, i8* %34
%36 = sext i8 %35 to i32
%37 = sub nsw i32 %36, 65
%38 = load i8*, i8** %5
%39 = load i64, i64* %10
%40 = getelementptr inbounds i8, i8* %38, i64 %39
%41 = load i8, i8* %40
%42 = sext i8 %41 to i32
%43 = sub nsw i32 %42, 65
%44 = sub nsw i32 %37, %43
store i32 %44, i32* %11
%45 = load i32, i32* %11
%46 = icmp slt i32 %45, 0
br i1 %46, label %47, label %52
47: ; preds = %27
%48 = load i32, i32* %11
%49 = call i32 @abs(i32 %48)
%50 = sub nsw i32 26, %49
%51 = add nsw i32 %50, 26
store i32 %51, i32* %11
br label %52
52: ; preds = %47, %27
%53 = load i32, i32* %11
%54 = srem i32 %53, 26
%55 = add nsw i32 %54, 65
%56 = trunc i32 %55 to i8
%57 = load i8*, i8** %6
%58 = load i64, i64* %9
%59 = load i64, i64* %7
%60 = mul i64 %58, %59
%61 = load i64, i64* %10
%62 = add i64 %60, %61
%63 = getelementptr inbounds i8, i8* %57, i64 %62
store i8 %56, i8* %63
br label %64
64: ; preds = %52
%65 = load i64, i64* %10
%66 = add i64 %65, 1
store i64 %66, i64* %10
br label %23
67: ; preds = %23
br label %68
68: ; preds = %67
%69 = load i64, i64* %9
%70 = add i64 %69, 1
store i64 %70, i64* %9
br label %16
71: ; preds = %16
ret void
}

LLVM IR (-O2):
define void @decrypt(i8* nocapture %0, i8* nocapture %1, i8* nocapture writeonly %2) {
%4 = tail call i64 @strlen(i8* dereferenceable(1) %1)
%5 = tail call i64 @strlen(i8* dereferenceable(1) %0)
%6 = icmp ugt i64 %4, %5
br i1 %6, label %92, label %7
7: ; preds = %3
%8 = udiv i64 %5, %4
%9 = icmp eq i64 %4, 0
%10 = call i64 @llvm.umax.i64(i64 %8, i64 1)
%11 = getelementptr i8, i8* %1, i64 %4
%12 = icmp ult i64 %4, 8
%13 = icmp ult i64 %4, 16
%14 = and i64 %4, -16
%15 = icmp eq i64 %4, %14
%16 = and i64 %4, 8
%17 = icmp eq i64 %16, 0
%18 = and i64 %4, -8
%19 = icmp eq i64 %4, %18
br label %20
20: ; preds = %7, %93
%21 = phi i64 [ 0, %7 ], [ %94, %93 ]
%22 = mul i64 %4, %21
%23 = getelementptr i8, i8* %2, i64 %22
%24 = add i64 %4, %22
%25 = getelementptr i8, i8* %2, i64 %24
%26 = getelementptr i8, i8* %0, i64 %22
%27 = getelementptr i8, i8* %0, i64 %24
br i1 %9, label %93, label %28
28: ; preds = %20
%29 = mul i64 %21, %4
br i1 %12, label %90, label %30
30: ; preds = %28
%31 = icmp ult i8* %23, %27
%32 = icmp ult i8* %26, %25
%33 = and i1 %31, %32
%34 = icmp ult i8* %23, %11
%35 = icmp ugt i8* %25, %1
%36 = and i1 %34, %35
%37 = or i1 %33, %36
br i1 %37, label %90, label %38
38: ; preds = %30
br i1 %13, label %64, label %39
39: ; preds = %38, %39
%40 = phi i64 [ %60, %39 ], [ 0, %38 ]
%41 = add i64 %40, %29
%42 = getelementptr inbounds i8, i8* %0, i64 %41
%43 = bitcast i8* %42 to <16 x i8>*
%44 = load <16 x i8>, <16 x i8>* %43
%45 = sext <16 x i8> %44 to <16 x i32>
%46 = getelementptr inbounds i8, i8* %1, i64 %40
%47 = bitcast i8* %46 to <16 x i8>*
%48 = load <16 x i8>, <16 x i8>* %47
%49 = sext <16 x i8> %48 to <16 x i32>
%50 = sub nsw <16 x i32> %45, %49
%51 = icmp slt <16 x i32> %50, zeroinitializer
%52 = add nsw <16 x i32> %50, <i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52>
%53 = select <16 x i1> %51, <16 x i32> %52, <16 x i32> %50
%54 = trunc <16 x i32> %53 to <16 x i16>
%55 = srem <16 x i16> %54, <i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26>
%56 = trunc <16 x i16> %55 to <16 x i8>
%57 = add nsw <16 x i8> %56, <i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65>
%58 = getelementptr inbounds i8, i8* %2, i64 %41
%59 = bitcast i8* %58 to <16 x i8>*
store <16 x i8> %57, <16 x i8>* %59
%60 = add nuw i64 %40, 16
%61 = icmp eq i64 %60, %14
br i1 %61, label %62, label %39
62: ; preds = %39
br i1 %15, label %93, label %63
63: ; preds = %62
br i1 %17, label %90, label %64
64: ; preds = %38, %63
%65 = phi i64 [ %14, %63 ], [ 0, %38 ]
br label %66
66: ; preds = %66, %64
%67 = phi i64 [ %65, %64 ], [ %87, %66 ]
%68 = add i64 %67, %29
%69 = getelementptr inbounds i8, i8* %0, i64 %68
%70 = bitcast i8* %69 to <8 x i8>*
%71 = load <8 x i8>, <8 x i8>* %70
%72 = sext <8 x i8> %71 to <8 x i32>
%73 = getelementptr inbounds i8, i8* %1, i64 %67
%74 = bitcast i8* %73 to <8 x i8>*
%75 = load <8 x i8>, <8 x i8>* %74
%76 = sext <8 x i8> %75 to <8 x i32>
%77 = sub nsw <8 x i32> %72, %76
%78 = icmp slt <8 x i32> %77, zeroinitializer
%79 = add nsw <8 x i32> %77, <i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52, i32 52>
%80 = select <8 x i1> %78, <8 x i32> %79, <8 x i32> %77
%81 = trunc <8 x i32> %80 to <8 x i16>
%82 = srem <8 x i16> %81, <i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26, i16 26>
%83 = trunc <8 x i16> %82 to <8 x i8>
%84 = add nsw <8 x i8> %83, <i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65, i8 65>
%85 = getelementptr inbounds i8, i8* %2, i64 %68
%86 = bitcast i8* %85 to <8 x i8>*
store <8 x i8> %84, <8 x i8>* %86
%87 = add nuw i64 %67, 8
%88 = icmp eq i64 %87, %18
br i1 %88, label %89, label %66
89: ; preds = %66
br i1 %19, label %93, label %90
90: ; preds = %30, %28, %63, %89
%91 = phi i64 [ 0, %28 ], [ 0, %30 ], [ %14, %63 ], [ %18, %89 ]
br label %96
92: ; preds = %93, %3
ret void
93: ; preds = %96, %62, %89, %20
%94 = add nuw i64 %21, 1
%95 = icmp eq i64 %94, %10
br i1 %95, label %92, label %20
96: ; preds = %90, %96
%97 = phi i64 [ %114, %96 ], [ %91, %90 ]
%98 = add i64 %97, %29
%99 = getelementptr inbounds i8, i8* %0, i64 %98
%100 = load i8, i8* %99
%101 = sext i8 %100 to i32
%102 = getelementptr inbounds i8, i8* %1, i64 %97
%103 = load i8, i8* %102
%104 = sext i8 %103 to i32
%105 = sub nsw i32 %101, %104
%106 = icmp slt i32 %105, 0
%107 = add nsw i32 %105, 52
%108 = select i1 %106, i32 %107, i32 %105
%109 = trunc i32 %108 to i16
%110 = srem i16 %109, 26
%111 = trunc i16 %110 to i8
%112 = add nsw i8 %111, 65
%113 = getelementptr inbounds i8, i8* %2, i64 %98
store i8 %112, i8* %113
%114 = add nuw i64 %97, 1
%115 = icmp eq i64 %114, %4
br i1 %115, label %93, label %96
}