const char *caesarEncrypt(char string[], int size) {
  int x;
  for (x = 0; x < size; x++) {
    if (string[x] >= 'A' && string[x] <= 'Z') {
      if (string[x] - 3 < 'A') {
        string[x] = string[x] - (3 - 1) - 'A' + 'Z';
      } else {
        string[x] -= 3;
      }
      continue;
    }
    if (string[x] >= 'a' && string[x] <= 'z') {
      if (string[x] - 3 < 'a') {
        string[x] = string[x] - (3 - 1) - 'a' + 'z';
      } else {
        string[x] -= 3;
      }
    }
  }
  return string;
}


x86 assembly (clang, -O0):
<caesarEncrypt>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    1231 <caesarEncrypt+0x131>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x41,%eax
jl     119e <caesarEncrypt+0x9e>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x5a,%eax
jg     119e <caesarEncrypt+0x9e>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sub    $0x3,%eax
cmp    $0x41,%eax
jge    1187 <caesarEncrypt+0x87>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sub    $0x2,%eax
sub    $0x41,%eax
add    $0x5a,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1199 <caesarEncrypt+0x99>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%edx
sub    $0x3,%edx
mov    %dl,(%rax,%rcx,1)
jmp    1223 <caesarEncrypt+0x123>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x61,%eax
jl     121e <caesarEncrypt+0x11e>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x7a,%eax
jg     121e <caesarEncrypt+0x11e>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sub    $0x3,%eax
cmp    $0x61,%eax
jge    1207 <caesarEncrypt+0x107>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
sub    $0x2,%eax
sub    $0x61,%eax
add    $0x7a,%eax
mov    %al,%dl
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1219 <caesarEncrypt+0x119>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movsbl (%rax,%rcx,1),%edx
sub    $0x3,%edx
mov    %dl,(%rax,%rcx,1)
jmp    121e <caesarEncrypt+0x11e>
jmp    1223 <caesarEncrypt+0x123>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    1112 <caesarEncrypt+0x12>
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<caesarEncrypt>:
mov    %rdi,%rax
test   %esi,%esi
jle    13cf <caesarEncrypt+0x2cf>
mov    %esi,%r8d
cmp    $0x8,%esi
jae    111a <caesarEncrypt+0x1a>
xor    %edx,%edx
jmp    13d0 <caesarEncrypt+0x2d0>
mov    %r8d,%edx
and    $0xfffffff8,%edx
xor    %esi,%esi
movdqa 0xed5(%rip),%xmm8
movdqa 0xedd(%rip),%xmm1
pcmpeqd %xmm2,%xmm2
movdqa 0xee0(%rip),%xmm9
movdqa 0xee8(%rip),%xmm4
movdqa 0xef0(%rip),%xmm5
jmp    117b <caesarEncrypt+0x7b>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movdqa %xmm6,-0x78(%rsp)
add    -0x71(%rsp),%cl
mov    %cl,0x7(%rax,%rsi,1)
add    $0x8,%rsi
cmp    %rsi,%rdx
je     13ca <caesarEncrypt+0x2ca>
movq   (%rax,%rsi,1),%xmm6
movdqa %xmm6,%xmm0
paddb  %xmm8,%xmm0
movdqa %xmm0,%xmm3
pmaxub %xmm1,%xmm3
pcmpeqb %xmm0,%xmm3
movdqa %xmm6,%xmm0
paddb  %xmm9,%xmm0
movdqa %xmm0,%xmm7
pmaxub %xmm1,%xmm7
pcmpeqb %xmm0,%xmm7
movdqa %xmm7,%xmm0
pandn  %xmm3,%xmm7
pxor   %xmm2,%xmm3
punpcklbw %xmm3,%xmm3
pxor   %xmm2,%xmm0
punpcklbw %xmm0,%xmm0
por    %xmm3,%xmm0
movdqa %xmm7,%xmm3
pandn  %xmm4,%xmm3
pand   %xmm5,%xmm7
por    %xmm3,%xmm7
psraw  $0x8,%xmm0
movd   %xmm0,%edi
test   $0x1,%dil
je     1205 <caesarEncrypt+0x105>
movd   %xmm6,%ecx
movd   %xmm7,%r10d
mov    $0x17,%r9d
cmp    %r10b,%cl
jb     11ff <caesarEncrypt+0xff>
mov    $0xfd,%r9d
add    %r9b,%cl
mov    %cl,(%rax,%rsi,1)
shr    $0x10,%edi
test   $0x1,%dil
je     1248 <caesarEncrypt+0x148>
movdqa %xmm6,%xmm3
pmaxub %xmm7,%xmm3
pcmpeqb %xmm6,%xmm3
pxor   %xmm2,%xmm3
pslld  $0x8,%xmm3
movd   %xmm3,%edi
shr    $0x10,%edi
mov    $0x17,%ecx
test   $0x1,%dil
jne    123a <caesarEncrypt+0x13a>
mov    $0xfd,%ecx
movdqa %xmm6,-0x18(%rsp)
add    -0x17(%rsp),%cl
mov    %cl,0x1(%rax,%rsi,1)
pextrw $0x2,%xmm0,%ecx
test   $0x1,%cl
je     128a <caesarEncrypt+0x18a>
movdqa %xmm6,%xmm3
pmaxub %xmm7,%xmm3
pcmpeqb %xmm6,%xmm3
pshuflw $0x55,%xmm3,%xmm3
pxor   %xmm2,%xmm3
pextrw $0x2,%xmm3,%edi
mov    $0x17,%ecx
test   $0x1,%dil
jne    127c <caesarEncrypt+0x17c>
mov    $0xfd,%ecx
movdqa %xmm6,-0x28(%rsp)
add    -0x26(%rsp),%cl
mov    %cl,0x2(%rax,%rsi,1)
pextrw $0x3,%xmm0,%ecx
test   $0x1,%cl
je     12cc <caesarEncrypt+0x1cc>
movdqa %xmm6,%xmm3
pmaxub %xmm7,%xmm3
pcmpeqb %xmm6,%xmm3
pxor   %xmm2,%xmm3
psllq  $0x18,%xmm3
pextrw $0x3,%xmm3,%edi
mov    $0x17,%ecx
test   $0x1,%dil
jne    12be <caesarEncrypt+0x1be>
mov    $0xfd,%ecx
movdqa %xmm6,-0x38(%rsp)
add    -0x35(%rsp),%cl
mov    %cl,0x3(%rax,%rsi,1)
pextrw $0x4,%xmm0,%ecx
test   $0x1,%cl
je     130e <caesarEncrypt+0x20e>
movdqa %xmm6,%xmm3
pmaxub %xmm7,%xmm3
pcmpeqb %xmm6,%xmm3
pshufd $0x55,%xmm3,%xmm3
pxor   %xmm2,%xmm3
pextrw $0x4,%xmm3,%edi
mov    $0x17,%ecx
test   $0x1,%dil
jne    1300 <caesarEncrypt+0x200>
mov    $0xfd,%ecx
movdqa %xmm6,-0x48(%rsp)
add    -0x44(%rsp),%cl
mov    %cl,0x4(%rax,%rsi,1)
pextrw $0x5,%xmm0,%ecx
test   $0x1,%cl
je     1350 <caesarEncrypt+0x250>
movdqa %xmm6,%xmm3
pmaxub %xmm7,%xmm3
pcmpeqb %xmm6,%xmm3
pxor   %xmm2,%xmm3
pslldq $0x5,%xmm3
pextrw $0x5,%xmm3,%edi
mov    $0x17,%ecx
test   $0x1,%dil
jne    1342 <caesarEncrypt+0x242>
mov    $0xfd,%ecx
movdqa %xmm6,-0x58(%rsp)
add    -0x53(%rsp),%cl
mov    %cl,0x5(%rax,%rsi,1)
pextrw $0x6,%xmm0,%ecx
test   $0x1,%cl
je     138d <caesarEncrypt+0x28d>
movdqa %xmm6,%xmm3
pmaxub %xmm7,%xmm3
pcmpeqb %xmm6,%xmm3
pxor   %xmm2,%xmm3
pextrw $0x3,%xmm3,%edi
mov    $0x17,%ecx
test   $0x1,%dil
jne    137f <caesarEncrypt+0x27f>
mov    $0xfd,%ecx
movdqa %xmm6,-0x68(%rsp)
add    -0x62(%rsp),%cl
mov    %cl,0x6(%rax,%rsi,1)
pextrw $0x7,%xmm0,%ecx
test   $0x1,%cl
je     116e <caesarEncrypt+0x6e>
pmaxub %xmm6,%xmm7
pcmpeqb %xmm6,%xmm7
pxor   %xmm2,%xmm7
pslldq $0x7,%xmm7
pextrw $0x7,%xmm7,%edi
mov    $0x17,%ecx
test   $0x1,%dil
jne    1160 <caesarEncrypt+0x60>
mov    $0xfd,%ecx
jmp    1160 <caesarEncrypt+0x60>
cmp    %r8,%rdx
jne    13d0 <caesarEncrypt+0x2d0>
ret
mov    $0x17,%r9d
jmp    13fb <caesarEncrypt+0x2fb>
nopl   0x0(%rax,%rax,1)
cmp    %cl,%dil
mov    $0xfd,%ecx
cmovb  %r9d,%ecx
add    %dil,%cl
mov    %cl,(%rax,%rdx,1)
add    $0x1,%rdx
cmp    %rdx,%r8
je     13cf <caesarEncrypt+0x2cf>
movzbl (%rax,%rdx,1),%edi
lea    -0x41(%rdi),%esi
mov    $0x44,%cl
cmp    $0x1a,%sil
jb     13e0 <caesarEncrypt+0x2e0>
lea    -0x61(%rdi),%esi
mov    $0x64,%cl
cmp    $0x19,%sil
jbe    13e0 <caesarEncrypt+0x2e0>
jmp    13f2 <caesarEncrypt+0x2f2>

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

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