void substr(char *dst, char *src, int begin, int len) {
  int tmplen = len;
  src += begin;
  if (!len) {
    while (*src) {
      *dst = *src;
      dst++;
      src++;
    }
  } else {
    while (tmplen) {
      *dst = *src;
      dst++;
      src++;
      tmplen--;
    }
  }
  *dst = 0;
}


x86 assembly (clang, -O0):
<substr>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x14(%rbp),%ecx
mov    -0x10(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x10(%rbp)
cmpl   $0x0,-0x18(%rbp)
jne    1173 <substr+0x73>
jmp    1138 <substr+0x38>
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
je     116e <substr+0x6e>
mov    -0x10(%rbp),%rax
mov    (%rax),%cl
mov    -0x8(%rbp),%rax
mov    %cl,(%rax)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1138 <substr+0x38>
jmp    11b9 <substr+0xb9>
jmp    1178 <substr+0x78>
cmpl   $0x0,-0x1c(%rbp)
je     11b4 <substr+0xb4>
mov    -0x10(%rbp),%rax
mov    (%rax),%cl
mov    -0x8(%rbp),%rax
mov    %cl,(%rax)
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    1178 <substr+0x78>
jmp    11b9 <substr+0xb9>
mov    -0x8(%rbp),%rax
movb   $0x0,(%rax)
pop    %rbp
ret

x86 assembly (clang, -O2):
<substr>:
push   %r14
push   %rbx
movslq %edx,%r10
lea    (%rsi,%r10,1),%rax
test   %ecx,%ecx
je     116b <substr+0x6b>
lea    -0x1(%rcx),%r8d
cmp    $0x1f,%r8d
jb     125d <substr+0x15d>
lea    (%r10,%r8,1),%rdx
add    %rsi,%rdx
add    $0x1,%rdx
cmp    %rdi,%rdx
jbe    113d <substr+0x3d>
lea    (%r8,%rdi,1),%rdx
add    $0x1,%rdx
cmp    %rdx,%rax
jb     125d <substr+0x15d>
add    $0x1,%r8
mov    %r8,%r9
and    $0xffffffffffffffe0,%r9
lea    -0x20(%r9),%rdx
mov    %rdx,%r14
shr    $0x5,%r14
add    $0x1,%r14
mov    %r14d,%r11d
and    $0x3,%r11d
cmp    $0x60,%rdx
jae    1196 <substr+0x96>
xor    %ebx,%ebx
jmp    1208 <substr+0x108>
mov    (%rax),%al
test   %al,%al
je     12f1 <substr+0x1f1>
lea    (%r10,%rsi,1),%rcx
add    $0x1,%rcx
nopl   (%rax)
mov    %al,(%rdi)
add    $0x1,%rdi
movzbl (%rcx),%eax
add    $0x1,%rcx
test   %al,%al
jne    1180 <substr+0x80>
jmp    12f1 <substr+0x1f1>
and    $0xfffffffffffffffc,%r14
lea    (%r10,%rsi,1),%rdx
add    $0x70,%rdx
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movups -0x70(%rdx,%rbx,1),%xmm0
movups -0x60(%rdx,%rbx,1),%xmm1
movups %xmm0,(%rdi,%rbx,1)
movups %xmm1,0x10(%rdi,%rbx,1)
movups -0x50(%rdx,%rbx,1),%xmm0
movups -0x40(%rdx,%rbx,1),%xmm1
movups %xmm0,0x20(%rdi,%rbx,1)
movups %xmm1,0x30(%rdi,%rbx,1)
movups -0x30(%rdx,%rbx,1),%xmm0
movups -0x20(%rdx,%rbx,1),%xmm1
movups %xmm0,0x40(%rdi,%rbx,1)
movups %xmm1,0x50(%rdi,%rbx,1)
movups -0x10(%rdx,%rbx,1),%xmm0
movups (%rdx,%rbx,1),%xmm1
movups %xmm0,0x60(%rdi,%rbx,1)
movups %xmm1,0x70(%rdi,%rbx,1)
sub    $0xffffffffffffff80,%rbx
add    $0xfffffffffffffffc,%r14
jne    11b0 <substr+0xb0>
test   %r11,%r11
je     124b <substr+0x14b>
add    %rbx,%r10
lea    (%rsi,%r10,1),%rdx
add    $0x10,%rdx
lea    (%rbx,%rdi,1),%rsi
add    $0x10,%rsi
shl    $0x5,%r11
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
movups -0x10(%rdx,%rbx,1),%xmm0
movups (%rdx,%rbx,1),%xmm1
movups %xmm0,-0x10(%rsi,%rbx,1)
movups %xmm1,(%rsi,%rbx,1)
add    $0x20,%rbx
cmp    %rbx,%r11
jne    1230 <substr+0x130>
add    %r9,%rdi
cmp    %r9,%r8
je     12f1 <substr+0x1f1>
sub    %r9d,%ecx
add    %r9,%rax
lea    -0x1(%rcx),%r8d
test   $0x7,%cl
je     1287 <substr+0x187>
mov    %ecx,%ebx
and    $0x7,%ebx
xor    %esi,%esi
nopl   (%rax)
movzbl (%rax,%rsi,1),%edx
mov    %dl,(%rdi,%rsi,1)
add    $0x1,%rsi
cmp    %esi,%ebx
jne    1270 <substr+0x170>
sub    %esi,%ecx
add    %rsi,%rdi
add    %rsi,%rax
cmp    $0x7,%r8d
jb     12f1 <substr+0x1f1>
mov    %ecx,%edx
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movzbl (%rax,%rcx,1),%ebx
mov    %bl,(%rdi,%rcx,1)
movzbl 0x1(%rax,%rcx,1),%ebx
mov    %bl,0x1(%rdi,%rcx,1)
movzbl 0x2(%rax,%rcx,1),%ebx
mov    %bl,0x2(%rdi,%rcx,1)
movzbl 0x3(%rax,%rcx,1),%ebx
mov    %bl,0x3(%rdi,%rcx,1)
movzbl 0x4(%rax,%rcx,1),%ebx
mov    %bl,0x4(%rdi,%rcx,1)
movzbl 0x5(%rax,%rcx,1),%ebx
mov    %bl,0x5(%rdi,%rcx,1)
movzbl 0x6(%rax,%rcx,1),%ebx
mov    %bl,0x6(%rdi,%rcx,1)
movzbl 0x7(%rax,%rcx,1),%ebx
mov    %bl,0x7(%rdi,%rcx,1)
add    $0x8,%rcx
cmp    %ecx,%edx
jne    12a0 <substr+0x1a0>
add    %rcx,%rdi
movb   $0x0,(%rdi)
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define void @substr(i8* %0, i8* %1, i32 %2, i32 %3) {
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i8* %0, i8** %5
store i8* %1, i8** %6
store i32 %2, i32* %7
store i32 %3, i32* %8
%10 = load i32, i32* %8
store i32 %10, i32* %9
%11 = load i32, i32* %7
%12 = load i8*, i8** %6
%13 = sext i32 %11 to i64
%14 = getelementptr inbounds i8, i8* %12, i64 %13
store i8* %14, i8** %6
%15 = load i32, i32* %8
%16 = icmp ne i32 %15, 0
br i1 %16, label %31, label %17
17: ; preds = %4
br label %18
18: ; preds = %22, %17
%19 = load i8*, i8** %6
%20 = load i8, i8* %19
%21 = icmp ne i8 %20, 0
br i1 %21, label %22, label %30
22: ; preds = %18
%23 = load i8*, i8** %6
%24 = load i8, i8* %23
%25 = load i8*, i8** %5
store i8 %24, i8* %25
%26 = load i8*, i8** %5
%27 = getelementptr inbounds i8, i8* %26, i32 1
store i8* %27, i8** %5
%28 = load i8*, i8** %6
%29 = getelementptr inbounds i8, i8* %28, i32 1
store i8* %29, i8** %6
br label %18
30: ; preds = %18
br label %46
31: ; preds = %4
br label %32
32: ; preds = %35, %31
%33 = load i32, i32* %9
%34 = icmp ne i32 %33, 0
br i1 %34, label %35, label %45
35: ; preds = %32
%36 = load i8*, i8** %6
%37 = load i8, i8* %36
%38 = load i8*, i8** %5
store i8 %37, i8* %38
%39 = load i8*, i8** %5
%40 = getelementptr inbounds i8, i8* %39, i32 1
store i8* %40, i8** %5
%41 = load i8*, i8** %6
%42 = getelementptr inbounds i8, i8* %41, i32 1
store i8* %42, i8** %6
%43 = load i32, i32* %9
%44 = add nsw i32 %43, -1
store i32 %44, i32* %9
br label %32
45: ; preds = %32
br label %46
46: ; preds = %45, %30
%47 = load i8*, i8** %5
store i8 0, i8* %47
ret void
}

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