char *strrev(string)
char *string;
{
  static char *dst;
  char *p;
  unsigned int i, len;
  len = strlen(string);
  dst = (char *)malloc(len);
  for (i = 0; i < len; i++) {
    dst[i] = string[len - i - 1];
  }
  dst[i] = '\0';
  return dst;
}


x86 assembly (clang, -O0):
<strrev>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %eax,%edi
call   1040 <malloc@plt>
mov    %rax,0x2eef(%rip)
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x18(%rbp),%eax
jae    1189 <strrev+0x69>
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
sub    -0x14(%rbp),%ecx
sub    $0x1,%ecx
mov    %ecx,%ecx
mov    (%rax,%rcx,1),%dl
mov    0x2ec3(%rip),%rax
mov    -0x14(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1150 <strrev+0x30>
mov    0x2ea8(%rip),%rax
mov    -0x14(%rbp),%ecx
movb   $0x0,(%rax,%rcx,1)
mov    0x2e9a(%rip),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<strrev>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%rbx
call   1030 <strlen@plt>
mov    %rax,%r14
mov    %r14d,%edi
call   1040 <malloc@plt>
mov    %rax,0x2efa(%rip)
test   %r14d,%r14d
je     11b9 <strrev+0x99>
mov    %r14d,%r9d
cmp    $0x8,%r9
jae    11c7 <strrev+0xa7>
xor    %edx,%edx
mov    %r14d,%ecx
sub    %edx,%ecx
lea    0x1(%rdx),%rsi
test   $0x1,%cl
je     116c <strrev+0x4c>
mov    %edx,%ecx
not    %ecx
add    %r14d,%ecx
mov    (%rbx,%rcx,1),%cl
mov    %cl,(%rax,%rdx,1)
mov    %rsi,%rdx
cmp    %rsi,%r9
je     11b4 <strrev+0x94>
mov    %r14,%rcx
sub    %rdx,%rcx
mov    $0xfffffffe,%esi
add    %rcx,%rsi
mov    %rdx,%rdi
not    %rdi
add    %r14,%rdi
nopl   0x0(%rax,%rax,1)
mov    %edi,%ecx
movzbl (%rbx,%rcx,1),%ecx
mov    %cl,(%rax,%rdx,1)
mov    %esi,%ecx
movzbl (%rbx,%rcx,1),%ecx
mov    %cl,0x1(%rax,%rdx,1)
add    $0x2,%rdx
add    $0xfffffffffffffffe,%rsi
add    $0xfffffffffffffffe,%rdi
cmp    %rdx,%r9
jne    1190 <strrev+0x70>
mov    %r14d,%ecx
jmp    11bb <strrev+0x9b>
xor    %ecx,%ecx
movb   $0x0,(%rax,%rcx,1)
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret
lea    -0x1(%r9),%rsi
lea    -0x1(%r14),%edi
xor    %edx,%edx
cmp    %esi,%edi
jb     114e <strrev+0x2e>
shr    $0x20,%rsi
jne    114e <strrev+0x2e>
cmp    $0x20,%r9d
jae    11f0 <strrev+0xd0>
xor    %edx,%edx
jmp    12a9 <strrev+0x189>
mov    %r14d,%r8d
and    $0x1f,%r8d
mov    %r9,%rdx
sub    %r8,%rdx
lea    -0x1(%r14),%rdi
xor    %esi,%esi
pxor   %xmm0,%xmm0
nopw   0x0(%rax,%rax,1)
mov    %edi,%ecx
movdqu -0x1f(%rbx,%rcx,1),%xmm1
movdqu -0xf(%rbx,%rcx,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,(%rax,%rsi,1)
movdqu %xmm1,0x10(%rax,%rsi,1)
add    $0x20,%rsi
add    $0xffffffffffffffe0,%rdi
cmp    %rsi,%rdx
jne    1210 <strrev+0xf0>
test   %r8,%r8
je     11b4 <strrev+0x94>
cmp    $0x8,%r8d
jb     114e <strrev+0x2e>
mov    %rdx,%rsi
mov    %r14d,%r8d
and    $0x7,%r8d
mov    %r9,%rdx
sub    %r8,%rdx
mov    %rsi,%rdi
not    %rdi
add    %r14,%rdi
pxor   %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
mov    %edi,%ecx
movq   -0x7(%rbx,%rcx,1),%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm1,%xmm1
movq   %xmm1,(%rax,%rsi,1)
add    $0x8,%rsi
add    $0xfffffffffffffff8,%rdi
cmp    %rsi,%rdx
jne    12d0 <strrev+0x1b0>
test   %r8,%r8
jne    114e <strrev+0x2e>
jmp    11b4 <strrev+0x94>

LLVM IR (-O0):
@strrev.dst = internal global i8* null
define i8* @strrev(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 = call i64 @strlen(i8* %6)
%8 = trunc i64 %7 to i32
store i32 %8, i32* %5
%9 = load i32, i32* %5
%10 = zext i32 %9 to i64
%11 = call i8* @malloc(i64 %10)
store i8* %11, i8** @strrev.dst
store i32 0, i32* %4
br label %12
12: ; preds = %29, %1
%13 = load i32, i32* %4
%14 = load i32, i32* %5
%15 = icmp ult i32 %13, %14
br i1 %15, label %16, label %32
16: ; preds = %12
%17 = load i8*, i8** %2
%18 = load i32, i32* %5
%19 = load i32, i32* %4
%20 = sub i32 %18, %19
%21 = sub i32 %20, 1
%22 = zext i32 %21 to i64
%23 = getelementptr inbounds i8, i8* %17, i64 %22
%24 = load i8, i8* %23
%25 = load i8*, i8** @strrev.dst
%26 = load i32, i32* %4
%27 = zext i32 %26 to i64
%28 = getelementptr inbounds i8, i8* %25, i64 %27
store i8 %24, i8* %28
br label %29
29: ; preds = %16
%30 = load i32, i32* %4
%31 = add i32 %30, 1
store i32 %31, i32* %4
br label %12
32: ; preds = %12
%33 = load i8*, i8** @strrev.dst
%34 = load i32, i32* %4
%35 = zext i32 %34 to i64
%36 = getelementptr inbounds i8, i8* %33, i64 %35
store i8 0, i8* %36
%37 = load i8*, i8** @strrev.dst
ret i8* %37
}

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