void back(char *str, int len) {
  char *p = str;
  while (*p++)
    ;
  for (; p >= str; p--)
    *(p + len) = *p;
}


x86 assembly (clang, -O0):
<back>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x18(%rbp)
cmpb   $0x0,(%rax)
je     1130 <back+0x30>
jmp    1113 <back+0x13>
jmp    1135 <back+0x35>
mov    -0x18(%rbp),%rax
cmp    -0x8(%rbp),%rax
jb     1165 <back+0x65>
mov    -0x18(%rbp),%rax
mov    (%rax),%dl
mov    -0x18(%rbp),%rax
movslq -0xc(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
jmp    1135 <back+0x35>
pop    %rbp
ret

x86 assembly (clang, -O2):
<back>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
lea    -0x1(%rdi),%rax
xor    %ecx,%ecx
mov    %rdi,%rdx
mov    %rdi,%rbx
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%rbx
add    $0x1,%rdx
add    $0x1,%rax
cmpb   $0x0,(%rdi,%rcx,1)
lea    0x1(%rcx),%rcx
jne    1120 <back+0x20>
lea    (%rdi,%rcx,1),%rbx
cmp    %rdi,%rbx
jb     1170 <back+0x70>
lea    -0x1(%rdi),%r9
cmp    %r9,%rax
mov    %r9,%r8
cmovb  %rax,%r8
movslq %esi,%r11
mov    %rdi,%r10
sub    %r8,%r10
add    %rcx,%r10
cmp    $0x4,%r10
jae    117b <back+0x7b>
nop
movzbl (%rbx),%eax
mov    %al,(%rbx,%r11,1)
add    $0xffffffffffffffff,%rbx
cmp    %rdi,%rbx
jae    1160 <back+0x60>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
lea    (%rdi,%r11,1),%r8
lea    (%r8,%rcx,1),%r14
cmp    %r9,%rax
mov    %r9,%r15
cmovb  %rax,%r15
sub    %rdi,%r15
sub    %rcx,%r15
lea    (%r15,%r14,1),%rsi
add    $0x1,%rsi
cmp    %r14,%rsi
ja     1160 <back+0x60>
lea    (%rbx,%r15,1),%rsi
add    $0x1,%rsi
cmp    %rbx,%rsi
ja     1160 <back+0x60>
mov    %r11,%rsi
sub    %rdi,%rsi
cmp    %r9,%rax
mov    %r9,%r14
cmovb  %rax,%r14
add    %r14,%rsi
sub    %rcx,%rsi
lea    (%rsi,%rbx,1),%r15
add    $0x1,%r15
lea    (%rdi,%rcx,1),%rsi
add    $0x1,%rsi
cmp    %rsi,%r15
jae    11f7 <back+0xf7>
lea    (%rcx,%r8,1),%r15
add    $0x1,%r15
sub    %rdi,%r14
sub    %rcx,%r14
lea    (%r14,%rbx,1),%rsi
add    $0x1,%rsi
cmp    %r15,%rsi
jb     1160 <back+0x60>
cmp    $0x10,%r10
jae    1204 <back+0x104>
xor    %ebp,%ebp
jmp    1307 <back+0x207>
mov    %r10,%rbp
and    $0xfffffffffffffff0,%rbp
lea    -0x10(%rbp),%rbx
mov    %rbx,%r14
shr    $0x4,%r14
add    $0x1,%r14
cmp    $0x30,%rbx
jae    1225 <back+0x125>
xor    %r15d,%r15d
jmp    128d <back+0x18d>
cmp    %r9,%rax
mov    %r9,%r15
cmovb  %rax,%r15
mov    %rdi,%r12
sub    %r15,%r12
add    %rcx,%r12
and    $0xfffffffffffffff0,%r12
add    $0xfffffffffffffff0,%r12
shr    $0x4,%r12
add    $0x1,%r12
and    $0xfffffffffffffffc,%r12
xor    %r15d,%r15d
nop
lea    (%rdi,%r15,1),%rbx
movups -0xf(%rcx,%rbx,1),%xmm0
lea    (%r8,%r15,1),%rsi
movups %xmm0,-0xf(%rcx,%rsi,1)
movups -0x1f(%rcx,%rbx,1),%xmm0
movups %xmm0,-0x1f(%rcx,%rsi,1)
movups -0x2f(%rcx,%rbx,1),%xmm0
movups %xmm0,-0x2f(%rcx,%rsi,1)
movups -0x3f(%rcx,%rbx,1),%xmm0
movups %xmm0,-0x3f(%rcx,%rsi,1)
add    $0xffffffffffffffc0,%r15
add    $0xfffffffffffffffc,%r12
jne    1250 <back+0x150>
neg    %r15
test   $0x3,%r14b
je     12ee <back+0x1ee>
cmp    %r9,%rax
mov    %r9,%rsi
cmovb  %rax,%rsi
mov    %edi,%ebx
sub    %esi,%ebx
lea    (%rcx,%rbx,1),%esi
and    $0x30,%sil
add    $0xf0,%sil
shr    $0x4,%sil
add    $0x1,%sil
movzbl %sil,%r14d
and    $0x3,%r14d
shl    $0x4,%r14
mov    %rdi,%r12
sub    %r15,%r12
mov    %r8,%r13
sub    %r15,%r13
xor    %ebx,%ebx
xchg   %ax,%ax
lea    (%r12,%rbx,1),%rsi
movups -0xf(%rcx,%rsi,1),%xmm0
lea    (%rbx,%r13,1),%rsi
movups %xmm0,-0xf(%rcx,%rsi,1)
add    $0xfffffffffffffff0,%rbx
mov    %r14,%rsi
add    %rbx,%rsi
jne    12d0 <back+0x1d0>
cmp    %rbp,%r10
je     1170 <back+0x70>
cmp    %r9,%rax
mov    %r9,%rbx
cmovb  %rax,%rbx
test   $0xc,%r10b
je     137b <back+0x27b>
cmp    %r9,%rax
cmovb  %rax,%r9
mov    %rdi,%r14
sub    %r9,%r14
add    %rcx,%r14
mov    %r14,%r10
and    $0xfffffffffffffffc,%r10
sub    %r9,%rdx
and    $0xfffffffffffffffc,%rdx
mov    %rdi,%rbx
sub    %rdx,%rbx
add    %rcx,%rbx
mov    %r11,%rdx
sub    %rbp,%rdx
neg    %rbp
add    $0xfffffffffffffffd,%rdx
mov    %r10,%r9
neg    %r9
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
lea    (%rdi,%rbp,1),%rsi
mov    -0x3(%rcx,%rsi,1),%esi
lea    (%r8,%rbp,1),%rax
mov    %esi,-0x3(%rcx,%rax,1)
add    $0xfffffffffffffffc,%rbp
add    $0xfffffffffffffffc,%rdx
cmp    %rbp,%r9
jne    1350 <back+0x250>
cmp    %r10,%r14
jne    1160 <back+0x60>
jmp    1170 <back+0x70>
sub    %rbx,%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rdi,%rbx
sub    %rdx,%rbx
add    %rcx,%rbx
jmp    1160 <back+0x60>

LLVM IR (-O0):
define void @back(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i8*
store i8* %0, i8** %3
store i32 %1, i32* %4
%6 = load i8*, i8** %3
store i8* %6, i8** %5
br label %7
7: ; preds = %12, %2
%8 = load i8*, i8** %5
%9 = getelementptr inbounds i8, i8* %8, i32 1
store i8* %9, i8** %5
%10 = load i8, i8* %8
%11 = icmp ne i8 %10, 0
br i1 %11, label %12, label %13
12: ; preds = %7
br label %7
13: ; preds = %7
br label %14
14: ; preds = %25, %13
%15 = load i8*, i8** %5
%16 = load i8*, i8** %3
%17 = icmp uge i8* %15, %16
br i1 %17, label %18, label %28
18: ; preds = %14
%19 = load i8*, i8** %5
%20 = load i8, i8* %19
%21 = load i8*, i8** %5
%22 = load i32, i32* %4
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds i8, i8* %21, i64 %23
store i8 %20, i8* %24
br label %25
25: ; preds = %18
%26 = load i8*, i8** %5
%27 = getelementptr inbounds i8, i8* %26, i32 -1
store i8* %27, i8** %5
br label %14
28: ; preds = %14
ret void
}

LLVM IR (-O2):
define void @back(i8* %0, i32 %1) {
%3 = ptrtoint i8* %0 to i64
br label %4
4: ; preds = %4, %2
%5 = phi i8* [ %0, %2 ], [ %6, %4 ]
%6 = getelementptr inbounds i8, i8* %5, i64 1
%7 = load i8, i8* %5
%8 = icmp eq i8 %7, 0
br i1 %8, label %9, label %4
9: ; preds = %4
%10 = ptrtoint i8* %6 to i64
%11 = icmp ult i8* %6, %0
br i1 %11, label %153, label %12
12: ; preds = %9
%13 = sext i32 %1 to i64
%14 = add i64 %10, -1
%15 = add i64 %3, -1
%16 = call i64 @llvm.umin.i64(i64 %14, i64 %15)
%17 = sub i64 %10, %16
%18 = icmp ult i64 %17, 4
br i1 %18, label %145, label %19
19: ; preds = %12
%20 = add i64 %10, -1
%21 = add i64 %3, -1
%22 = call i64 @llvm.umin.i64(i64 %20, i64 %21)
%23 = sub i64 %20, %22
%24 = getelementptr i8, i8* %6, i64 %13
%25 = sub i64 0, %23
%26 = getelementptr i8, i8* %24, i64 %25
%27 = icmp ugt i8* %26, %24
%28 = sub i64 0, %23
%29 = getelementptr i8, i8* %6, i64 %28
%30 = icmp ugt i8* %29, %6
%31 = or i1 %27, %30
br i1 %31, label %145, label %32
32: ; preds = %19
%33 = add i64 %10, -1
%34 = add i64 %3, -1
%35 = call i64 @llvm.umin.i64(i64 %33, i64 %34)
%36 = add i64 %35, %13
%37 = add i64 %36, 1
%38 = sub i64 %37, %10
%39 = getelementptr i8, i8* %6, i64 %38
%40 = add nsw i64 %13, 1
%41 = getelementptr i8, i8* %6, i64 %40
%42 = add i64 %35, 1
%43 = sub i64 %42, %10
%44 = getelementptr i8, i8* %6, i64 %43
%45 = getelementptr i8, i8* %5, i64 2
%46 = icmp ult i8* %39, %45
%47 = icmp ult i8* %44, %41
%48 = and i1 %46, %47
br i1 %48, label %145, label %49
49: ; preds = %32
%50 = icmp ult i64 %17, 16
br i1 %50, label %122, label %51
51: ; preds = %49
%52 = and i64 %17, -16
%53 = add i64 %52, -16
%54 = lshr exact i64 %53, 4
%55 = add nuw nsw i64 %54, 1
%56 = and i64 %55, 3
%57 = icmp ult i64 %53, 48
br i1 %57, label %98, label %58
58: ; preds = %51
%59 = and i64 %55, 2305843009213693948
br label %60
60: ; preds = %60, %58
%61 = phi i64 [ 0, %58 ], [ %95, %60 ]
%62 = phi i64 [ 0, %58 ], [ %96, %60 ]
%63 = sub i64 0, %61
%64 = getelementptr i8, i8* %6, i64 %63
%65 = getelementptr i8, i8* %64, i64 -15
%66 = bitcast i8* %65 to <16 x i8>*
%67 = load <16 x i8>, <16 x i8>* %66
%68 = getelementptr inbounds i8, i8* %64, i64 %13
%69 = getelementptr inbounds i8, i8* %68, i64 -15
%70 = bitcast i8* %69 to <16 x i8>*
store <16 x i8> %67, <16 x i8>* %70
%71 = sub nuw nsw i64 -16, %61
%72 = getelementptr i8, i8* %6, i64 %71
%73 = getelementptr i8, i8* %72, i64 -15
%74 = bitcast i8* %73 to <16 x i8>*
%75 = load <16 x i8>, <16 x i8>* %74
%76 = getelementptr inbounds i8, i8* %72, i64 %13
%77 = getelementptr inbounds i8, i8* %76, i64 -15
%78 = bitcast i8* %77 to <16 x i8>*
store <16 x i8> %75, <16 x i8>* %78
%79 = sub nuw nsw i64 -32, %61
%80 = getelementptr i8, i8* %6, i64 %79
%81 = getelementptr i8, i8* %80, i64 -15
%82 = bitcast i8* %81 to <16 x i8>*
%83 = load <16 x i8>, <16 x i8>* %82
%84 = getelementptr inbounds i8, i8* %80, i64 %13
%85 = getelementptr inbounds i8, i8* %84, i64 -15
%86 = bitcast i8* %85 to <16 x i8>*
store <16 x i8> %83, <16 x i8>* %86
%87 = sub nuw nsw i64 -48, %61
%88 = getelementptr i8, i8* %6, i64 %87
%89 = getelementptr i8, i8* %88, i64 -15
%90 = bitcast i8* %89 to <16 x i8>*
%91 = load <16 x i8>, <16 x i8>* %90
%92 = getelementptr inbounds i8, i8* %88, i64 %13
%93 = getelementptr inbounds i8, i8* %92, i64 -15
%94 = bitcast i8* %93 to <16 x i8>*
store <16 x i8> %91, <16 x i8>* %94
%95 = add nuw i64 %61, 64
%96 = add i64 %62, 4
%97 = icmp eq i64 %96, %59
br i1 %97, label %98, label %60
98: ; preds = %60, %51
%99 = phi i64 [ 0, %51 ], [ %95, %60 ]
%100 = icmp eq i64 %56, 0
br i1 %100, label %115, label %101
101: ; preds = %98, %101
%102 = phi i64 [ %112, %101 ], [ %99, %98 ]
%103 = phi i64 [ %113, %101 ], [ 0, %98 ]
%104 = sub i64 0, %102
%105 = getelementptr i8, i8* %6, i64 %104
%106 = getelementptr i8, i8* %105, i64 -15
%107 = bitcast i8* %106 to <16 x i8>*
%108 = load <16 x i8>, <16 x i8>* %107
%109 = getelementptr inbounds i8, i8* %105, i64 %13
%110 = getelementptr inbounds i8, i8* %109, i64 -15
%111 = bitcast i8* %110 to <16 x i8>*
store <16 x i8> %108, <16 x i8>* %111
%112 = add nuw i64 %102, 16
%113 = add i64 %103, 1
%114 = icmp eq i64 %113, %56
br i1 %114, label %115, label %101
115: ; preds = %101, %98
%116 = icmp eq i64 %17, %52
br i1 %116, label %153, label %117
117: ; preds = %115
%118 = sub i64 0, %52
%119 = getelementptr i8, i8* %6, i64 %118
%120 = and i64 %17, 12
%121 = icmp eq i64 %120, 0
br i1 %121, label %145, label %122
122: ; preds = %49, %117
%123 = phi i64 [ %52, %117 ], [ 0, %49 ]
%124 = add i64 %10, -1
%125 = add i64 %3, -1
%126 = call i64 @llvm.umin.i64(i64 %124, i64 %125)
%127 = sub i64 %10, %126
%128 = and i64 %127, -4
%129 = sub i64 0, %128
%130 = getelementptr i8, i8* %6, i64 %129
br label %131
131: ; preds = %131, %122
%132 = phi i64 [ %123, %122 ], [ %141, %131 ]
%133 = sub i64 0, %132
%134 = getelementptr i8, i8* %6, i64 %133
%135 = getelementptr i8, i8* %134, i64 -3
%136 = bitcast i8* %135 to <4 x i8>*
%137 = load <4 x i8>, <4 x i8>* %136
%138 = getelementptr inbounds i8, i8* %134, i64 %13
%139 = getelementptr inbounds i8, i8* %138, i64 -3
%140 = bitcast i8* %139 to <4 x i8>*
store <4 x i8> %137, <4 x i8>* %140
%141 = add nuw i64 %132, 4
%142 = icmp eq i64 %141, %128
br i1 %142, label %143, label %131
143: ; preds = %131
%144 = icmp eq i64 %127, %128
br i1 %144, label %153, label %145
145: ; preds = %32, %19, %12, %117, %143
%146 = phi i8* [ %6, %12 ], [ %6, %32 ], [ %6, %19 ], [ %119, %117 ], [ %130, %143 ]
br label %147
147: ; preds = %145, %147
%148 = phi i8* [ %151, %147 ], [ %146, %145 ]
%149 = load i8, i8* %148
%150 = getelementptr inbounds i8, i8* %148, i64 %13
store i8 %149, i8* %150
%151 = getelementptr inbounds i8, i8* %148, i64 -1
%152 = icmp ult i8* %151, %0
br i1 %152, label %153, label %147
153: ; preds = %147, %115, %143, %9
ret void
}