#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 /*<<< orphan*/ strcpy(char *, char *);
size_t strlen(char *);
void pca_decrypt(char *password) {
  char cleartext[128];
  int i;
  if (strlen(password) > 0) {
    cleartext[0] = password[0] ^ 0xab;
    for (i = 1; i < strlen(password); i++)
      cleartext[i] = password[i - 1] ^ password[i] ^ (i - 1);
    cleartext[strlen(password)] = '\0';
    strcpy(password, cleartext);
  }
}


x86 assembly (clang, -O0):
<pca_decrypt>:
push   %rbp
mov    %rsp,%rbp
sub    $0xa0,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <strlen@plt>
cmp    $0x0,%rax
jbe    11fd <pca_decrypt+0xdd>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
xor    $0xab,%eax
mov    %al,-0x90(%rbp)
movl   $0x1,-0x94(%rbp)
movslq -0x94(%rbp),%rax
mov    %rax,-0xa0(%rbp)
mov    -0x8(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,%rcx
mov    -0xa0(%rbp),%rax
cmp    %rcx,%rax
jae    11dc <pca_decrypt+0xbc>
mov    -0x8(%rbp),%rax
mov    -0x94(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
mov    -0x8(%rbp),%rcx
movslq -0x94(%rbp),%rdx
movsbl (%rcx,%rdx,1),%ecx
xor    %ecx,%eax
mov    -0x94(%rbp),%ecx
sub    $0x1,%ecx
xor    %ecx,%eax
mov    %al,%cl
movslq -0x94(%rbp),%rax
mov    %cl,-0x90(%rbp,%rax,1)
mov    -0x94(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x94(%rbp)
jmp    115e <pca_decrypt+0x3e>
mov    -0x8(%rbp),%rdi
call   1040 <strlen@plt>
movb   $0x0,-0x90(%rbp,%rax,1)
mov    -0x8(%rbp),%rdi
lea    -0x90(%rbp),%rsi
call   1030 <strcpy@plt>
add    $0xa0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<pca_decrypt>:
push   %rbp
push   %r14
push   %rbx
sub    $0x80,%rsp
mov    (%rdi),%bpl
test   %bpl,%bpl
je     124a <pca_decrypt+0x12a>
mov    %rdi,%r14
mov    %ebp,%eax
xor    $0xab,%al
mov    %al,(%rsp)
call   1040 <strlen@plt>
cmp    $0x2,%rax
jb     123b <pca_decrypt+0x11b>
lea    -0x1(%rax),%rdx
mov    $0x1,%ecx
cmp    $0x20,%rdx
jb     1220 <pca_decrypt+0x100>
mov    %rdx,%rsi
and    $0xffffffffffffffe0,%rsi
lea    0x1(%rsi),%rcx
movzbl %bpl,%edi
movd   %edi,%xmm4
pslldq $0xf,%xmm4
movdqa 0xe7d(%rip),%xmm0
xor    %edi,%edi
pcmpeqd %xmm1,%xmm1
movdqa 0xe7f(%rip),%xmm2
movdqa 0xe87(%rip),%xmm3
nopl   0x0(%rax)
movdqu 0x1(%r14,%rdi,1),%xmm5
movdqa %xmm5,%xmm6
movdqa %xmm0,%xmm7
paddb  %xmm1,%xmm7
pxor   %xmm5,%xmm7
pslldq $0x1,%xmm5
psrldq $0xf,%xmm4
por    %xmm5,%xmm4
pxor   %xmm4,%xmm7
movdqu 0x11(%r14,%rdi,1),%xmm4
psrldq $0xf,%xmm6
movdqa %xmm4,%xmm5
pslldq $0x1,%xmm5
por    %xmm6,%xmm5
movdqa %xmm0,%xmm6
paddb  %xmm2,%xmm6
pxor   %xmm4,%xmm6
pxor   %xmm5,%xmm6
movdqu %xmm7,0x1(%rsp,%rdi,1)
movdqu %xmm6,0x11(%rsp,%rdi,1)
add    $0x20,%rdi
paddb  %xmm3,%xmm0
cmp    %rdi,%rsi
jne    11a0 <pca_decrypt+0x80>
cmp    %rsi,%rdx
je     123b <pca_decrypt+0x11b>
pextrw $0x7,%xmm4,%ebp
shr    $0x8,%ebp
nopl   0x0(%rax,%rax,1)
lea    -0x1(%rcx),%edx
xor    %bpl,%dl
movzbl (%r14,%rcx,1),%ebx
xor    %bl,%dl
mov    %dl,(%rsp,%rcx,1)
add    $0x1,%rcx
mov    %ebx,%ebp
cmp    %rcx,%rax
jne    1220 <pca_decrypt+0x100>
movb   $0x0,(%rsp,%rax,1)
mov    %rsp,%rsi
mov    %r14,%rdi
call   1030 <strcpy@plt>
add    $0x80,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret

LLVM IR (-O0):
define void @pca_decrypt(i8* %0) {
%2 = alloca i8*
%3 = alloca [128 x i8]
%4 = alloca i32
store i8* %0, i8** %2
%5 = load i8*, i8** %2
%6 = call i64 @strlen(i8* %5)
%7 = icmp ugt i64 %6, 0
br i1 %7, label %8, label %54
8: ; preds = %1
%9 = load i8*, i8** %2
%10 = getelementptr inbounds i8, i8* %9, i64 0
%11 = load i8, i8* %10
%12 = sext i8 %11 to i32
%13 = xor i32 %12, 171
%14 = trunc i32 %13 to i8
%15 = getelementptr inbounds [128 x i8], [128 x i8]* %3, i64 0, i64 0
store i8 %14, i8* %15
store i32 1, i32* %4
br label %16
16: ; preds = %44, %8
%17 = load i32, i32* %4
%18 = sext i32 %17 to i64
%19 = load i8*, i8** %2
%20 = call i64 @strlen(i8* %19)
%21 = icmp ult i64 %18, %20
br i1 %21, label %22, label %47
22: ; preds = %16
%23 = load i8*, i8** %2
%24 = load i32, i32* %4
%25 = sub nsw i32 %24, 1
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds i8, i8* %23, i64 %26
%28 = load i8, i8* %27
%29 = sext i8 %28 to i32
%30 = load i8*, i8** %2
%31 = load i32, i32* %4
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds i8, i8* %30, i64 %32
%34 = load i8, i8* %33
%35 = sext i8 %34 to i32
%36 = xor i32 %29, %35
%37 = load i32, i32* %4
%38 = sub nsw i32 %37, 1
%39 = xor i32 %36, %38
%40 = trunc i32 %39 to i8
%41 = load i32, i32* %4
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds [128 x i8], [128 x i8]* %3, i64 0, i64 %42
store i8 %40, i8* %43
br label %44
44: ; preds = %22
%45 = load i32, i32* %4
%46 = add nsw i32 %45, 1
store i32 %46, i32* %4
br label %16
47: ; preds = %16
%48 = load i8*, i8** %2
%49 = call i64 @strlen(i8* %48)
%50 = getelementptr inbounds [128 x i8], [128 x i8]* %3, i64 0, i64 %49
store i8 0, i8* %50
%51 = load i8*, i8** %2
%52 = getelementptr inbounds [128 x i8], [128 x i8]* %3, i64 0, i64 0
%53 = call i32 @strcpy(i8* %51, i8* %52)
br label %54
54: ; preds = %47, %1
ret void
}

LLVM IR (-O2):
define void @pca_decrypt(i8* %0) {
%2 = alloca [128 x i8]
%3 = getelementptr inbounds [128 x i8], [128 x i8]* %2, i64 0, i64 0
%4 = load i8, i8* %0
%5 = icmp eq i8 %4, 0
br i1 %5, label %64, label %6
6: ; preds = %1
%7 = xor i8 %4, -85
store i8 %7, i8* %3
%8 = tail call i64 @strlen(i8* %0)
%9 = icmp ugt i64 %8, 1
br i1 %9, label %10, label %61
10: ; preds = %6
%11 = add i64 %8, -1
%12 = icmp ult i64 %11, 32
br i1 %12, label %46, label %13
13: ; preds = %10
%14 = and i64 %11, -32
%15 = or i64 %14, 1
%16 = insertelement <16 x i8> poison, i8 %4, i64 15
br label %17
17: ; preds = %17, %13
%18 = phi i64 [ 0, %13 ], [ %40, %17 ]
%19 = phi <16 x i8> [ %16, %13 ], [ %27, %17 ]
%20 = phi <16 x i8> [ <i8 1, i8 2, i8 3, i8 4, i8 5, i8 6, i8 7, i8 8, i8 9, i8 10, i8 11, i8 12, i8 13, i8 14, i8 15, i8 16>, %13 ], [ %41, %17 ]
%21 = or i64 %18, 1
%22 = getelementptr inbounds i8, i8* %0, i64 %21
%23 = bitcast i8* %22 to <16 x i8>*
%24 = load <16 x i8>, <16 x i8>* %23
%25 = getelementptr inbounds i8, i8* %22, i64 16
%26 = bitcast i8* %25 to <16 x i8>*
%27 = load <16 x i8>, <16 x i8>* %26
%28 = shufflevector <16 x i8> %19, <16 x i8> %24, <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
%29 = shufflevector <16 x i8> %24, <16 x i8> %27, <16 x i32> <i32 15, i32 16, i32 17, i32 18, i32 19, i32 20, i32 21, i32 22, i32 23, i32 24, i32 25, i32 26, i32 27, i32 28, i32 29, i32 30>
%30 = add <16 x i8> %20, <i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1>
%31 = add <16 x i8> %20, <i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15, i8 15>
%32 = xor <16 x i8> %28, %30
%33 = xor <16 x i8> %29, %31
%34 = xor <16 x i8> %32, %24
%35 = xor <16 x i8> %33, %27
%36 = getelementptr inbounds [128 x i8], [128 x i8]* %2, i64 0, i64 %21
%37 = bitcast i8* %36 to <16 x i8>*
store <16 x i8> %34, <16 x i8>* %37
%38 = getelementptr inbounds i8, i8* %36, i64 16
%39 = bitcast i8* %38 to <16 x i8>*
store <16 x i8> %35, <16 x i8>* %39
%40 = add nuw i64 %18, 32
%41 = add <16 x i8> %20, <i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32, i8 32>
%42 = icmp eq i64 %40, %14
br i1 %42, label %43, label %17
43: ; preds = %17
%44 = icmp eq i64 %11, %14
%45 = extractelement <16 x i8> %27, i64 15
br i1 %44, label %61, label %46
46: ; preds = %10, %43
%47 = phi i8 [ %45, %43 ], [ %4, %10 ]
%48 = phi i64 [ %15, %43 ], [ 1, %10 ]
br label %49
49: ; preds = %46, %49
%50 = phi i8 [ %53, %49 ], [ %47, %46 ]
%51 = phi i64 [ %59, %49 ], [ %48, %46 ]
%52 = getelementptr inbounds i8, i8* %0, i64 %51
%53 = load i8, i8* %52
%54 = trunc i64 %51 to i8
%55 = add i8 %54, -1
%56 = xor i8 %50, %55
%57 = xor i8 %56, %53
%58 = getelementptr inbounds [128 x i8], [128 x i8]* %2, i64 0, i64 %51
store i8 %57, i8* %58
%59 = add nuw nsw i64 %51, 1
%60 = icmp eq i64 %59, %8
br i1 %60, label %61, label %49
61: ; preds = %49, %43, %6
%62 = getelementptr inbounds [128 x i8], [128 x i8]* %2, i64 0, i64 %8
store i8 0, i8* %62
%63 = call i32 @strcpy(i8* %0, i8* %3)
br label %64
64: ; preds = %61, %1
ret void
}