#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*/ assert(int);
int /*<<< orphan*/ free(char *);
char *strdup(char *);
int strlen(char *);
void reverse(char *str) {
  assert(str && "Invalid parameter, str can not be NULL");
  char *temp = strdup(str);
  assert(temp && "Insufficient memory");
  int len = strlen(temp);
  for (int i = len - 1; i >= 0; i--, str++) {
    *str = temp[i];
  }
  str[len] = '\0';
  free(temp);
  return;
}


x86 assembly (clang, -O0):
<reverse>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
xor    %eax,%eax
cmpq   $0x0,-0x8(%rbp)
mov    %al,-0x19(%rbp)
je     1166 <reverse+0x26>
mov    $0x1,%al
mov    %al,-0x19(%rbp)
jmp    1166 <reverse+0x26>
mov    -0x19(%rbp),%al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
mov    -0x8(%rbp),%rdi
call   1060 <strdup@plt>
mov    %rax,-0x10(%rbp)
xor    %eax,%eax
cmpq   $0x0,-0x10(%rbp)
mov    %al,-0x1a(%rbp)
je     119a <reverse+0x5a>
mov    $0x1,%al
mov    %al,-0x1a(%rbp)
jmp    119a <reverse+0x5a>
mov    -0x1a(%rbp),%al
and    $0x1,%al
movzbl %al,%edi
call   1050 <assert@plt>
mov    -0x10(%rbp),%rdi
call   1040 <strlen@plt>
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x18(%rbp)
cmpl   $0x0,-0x18(%rbp)
jl     11f1 <reverse+0xb1>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,1),%cl
mov    -0x8(%rbp),%rax
mov    %cl,(%rax)
mov    -0x18(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    11bc <reverse+0x7c>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x10(%rbp),%rdi
call   1030 <free@plt>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<reverse>:
push   %r15
push   %r14
push   %rbx
mov    %rdi,%r14
xor    %edi,%edi
test   %r14,%r14
setne  %dil
call   1050 <assert@plt>
mov    %r14,%rdi
call   1060 <strdup@plt>
mov    %rax,%r15
xor    %edi,%edi
test   %rax,%rax
setne  %dil
call   1050 <assert@plt>
mov    %r15,%rdi
call   1040 <strlen@plt>
test   %eax,%eax
jle    127a <reverse+0x13a>
mov    %eax,%r8d
cmp    $0x20,%eax
jb     1251 <reverse+0x111>
lea    -0x1(%r8),%rdi
lea    -0x1(%rax),%ecx
cmp    %edi,%ecx
jb     1251 <reverse+0x111>
mov    %rdi,%rcx
shr    $0x20,%rcx
jne    1251 <reverse+0x111>
mov    %r8d,%r9d
and    $0xffffffe0,%r9d
mov    %r8d,%ecx
and    $0x1f,%ecx
lea    (%r14,%r9,1),%rdx
xor    %esi,%esi
pxor   %xmm0,%xmm0
xchg   %ax,%ax
mov    %edi,%ebx
movdqu -0x1f(%r15,%rbx,1),%xmm1
movdqu -0xf(%r15,%rbx,1),%xmm2
movdqa %xmm2,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
packuswb %xmm3,%xmm2
movdqa %xmm1,%xmm3
punpcklbw %xmm0,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm3,%xmm1
movdqu %xmm2,(%r14,%rsi,1)
movdqu %xmm1,0x10(%r14,%rsi,1)
add    $0x20,%rsi
add    $0xffffffffffffffe0,%rdi
cmp    %rsi,%r9
jne    11c0 <reverse+0x80>
cmp    %r8,%r9
jne    1257 <reverse+0x117>
jmp    127d <reverse+0x13d>
mov    %r8,%rcx
mov    %r14,%rdx
add    $0x1,%rcx
nopl   0x0(%rax,%rax,1)
lea    -0x2(%rcx),%esi
movzbl (%r15,%rsi,1),%ebx
mov    %bl,(%rdx)
add    $0x1,%rdx
add    $0xffffffffffffffff,%rcx
cmp    $0x1,%rcx
ja     1260 <reverse+0x120>
jmp    127d <reverse+0x13d>
mov    %r14,%rdx
cltq
movb   $0x0,(%rdx,%rax,1)
mov    %r15,%rdi
pop    %rbx
pop    %r14
pop    %r15
jmp    1030 <free@plt>

LLVM IR (-O0):
@.str = [39 x i8] c"Invalid parameter, str can not be NULL\00"
@.str.1 = [20 x i8] c"Insufficient memory\00"
define void @reverse(i8* %0) {
%2 = alloca i8*
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i32
store i8* %0, i8** %2
%6 = load i8*, i8** %2
%7 = icmp ne i8* %6, null
br i1 %7, label %8, label %9
8: ; preds = %1
br label %9
9: ; preds = %8, %1
%10 = phi i1 [ false, %1 ], [ true, %8 ]
%11 = zext i1 %10 to i32
%12 = call i32 @assert(i32 %11)
%13 = load i8*, i8** %2
%14 = call i8* @strdup(i8* %13)
store i8* %14, i8** %3
%15 = load i8*, i8** %3
%16 = icmp ne i8* %15, null
br i1 %16, label %17, label %18
17: ; preds = %9
br label %18
18: ; preds = %17, %9
%19 = phi i1 [ false, %9 ], [ true, %17 ]
%20 = zext i1 %19 to i32
%21 = call i32 @assert(i32 %20)
%22 = load i8*, i8** %3
%23 = call i32 @strlen(i8* %22)
store i32 %23, i32* %4
%24 = load i32, i32* %4
%25 = sub nsw i32 %24, 1
store i32 %25, i32* %5
br label %26
26: ; preds = %36, %18
%27 = load i32, i32* %5
%28 = icmp sge i32 %27, 0
br i1 %28, label %29, label %41
29: ; preds = %26
%30 = load i8*, i8** %3
%31 = load i32, i32* %5
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds i8, i8* %30, i64 %32
%34 = load i8, i8* %33
%35 = load i8*, i8** %2
store i8 %34, i8* %35
br label %36
36: ; preds = %29
%37 = load i32, i32* %5
%38 = add nsw i32 %37, -1
store i32 %38, i32* %5
%39 = load i8*, i8** %2
%40 = getelementptr inbounds i8, i8* %39, i32 1
store i8* %40, i8** %2
br label %26
41: ; preds = %26
%42 = load i8*, i8** %2
%43 = load i32, i32* %4
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds i8, i8* %42, i64 %44
store i8 0, i8* %45
%46 = load i8*, i8** %3
%47 = call i32 @free(i8* %46)
ret void
}

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