void soustringcopy(char *source, char *destination, int posdepart, int nbpos) {
  int i;
  for (i = posdepart; i < posdepart + nbpos; i++) {
    destination[i - posdepart] = source[i];
  }
  destination[i - posdepart] = '\0';
}


x86 assembly (clang, -O0):
<soustringcopy>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
mov    -0x14(%rbp),%ecx
add    -0x18(%rbp),%ecx
cmp    %ecx,%eax
jge    1152 <soustringcopy+0x52>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    -0x14(%rbp),%ecx
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1118 <soustringcopy+0x18>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    -0x14(%rbp),%ecx
movslq %ecx,%rcx
movb   $0x0,(%rax,%rcx,1)
pop    %rbp
ret

x86 assembly (clang, -O2):
<soustringcopy>:
push   %r14
push   %rbx
mov    %edx,%ebx
test   %ecx,%ecx
jle    1250 <soustringcopy+0x150>
add    %edx,%ecx
movslq %edx,%r8
movslq %ecx,%r14
lea    0x1(%r8),%rax
cmp    %r14,%rax
mov    %r14,%r10
cmovg  %rax,%r10
sub    %r8,%r10
mov    %r8,%rbx
cmp    $0x20,%r10
jb     1234 <soustringcopy+0x134>
cmp    %r14,%rax
cmovle %r14,%rax
lea    (%rdi,%rax,1),%rcx
cmp    %rsi,%rcx
jbe    1159 <soustringcopy+0x59>
sub    %r8,%rax
add    %rsi,%rax
lea    (%rdi,%r8,1),%rcx
mov    %r8,%rbx
cmp    %rax,%rcx
jb     1234 <soustringcopy+0x134>
mov    %r10,%r9
and    $0xffffffffffffffe0,%r9
lea    -0x20(%r9),%rax
mov    %rax,%rcx
shr    $0x5,%rcx
add    $0x1,%rcx
mov    %ecx,%r11d
and    $0x3,%r11d
cmp    $0x60,%rax
jae    1180 <soustringcopy+0x80>
xor    %ebx,%ebx
jmp    11e8 <soustringcopy+0xe8>
and    $0xfffffffffffffffc,%rcx
lea    (%r8,%rdi,1),%rax
add    $0x70,%rax
xor    %ebx,%ebx
xchg   %ax,%ax
movups -0x70(%rax,%rbx,1),%xmm0
movups -0x60(%rax,%rbx,1),%xmm1
movups %xmm0,(%rsi,%rbx,1)
movups %xmm1,0x10(%rsi,%rbx,1)
movups -0x50(%rax,%rbx,1),%xmm0
movups -0x40(%rax,%rbx,1),%xmm1
movups %xmm0,0x20(%rsi,%rbx,1)
movups %xmm1,0x30(%rsi,%rbx,1)
movups -0x30(%rax,%rbx,1),%xmm0
movups -0x20(%rax,%rbx,1),%xmm1
movups %xmm0,0x40(%rsi,%rbx,1)
movups %xmm1,0x50(%rsi,%rbx,1)
movups -0x10(%rax,%rbx,1),%xmm0
movups (%rax,%rbx,1),%xmm1
movups %xmm0,0x60(%rsi,%rbx,1)
movups %xmm1,0x70(%rsi,%rbx,1)
sub    $0xffffffffffffff80,%rbx
add    $0xfffffffffffffffc,%rcx
jne    1190 <soustringcopy+0x90>
test   %r11,%r11
je     122b <soustringcopy+0x12b>
lea    (%rbx,%rsi,1),%rax
add    $0x10,%rax
add    %r8,%rbx
lea    (%rdi,%rbx,1),%rcx
add    $0x10,%rcx
shl    $0x5,%r11
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
movups -0x10(%rcx,%rbx,1),%xmm0
movups (%rcx,%rbx,1),%xmm1
movups %xmm0,-0x10(%rax,%rbx,1)
movups %xmm1,(%rax,%rbx,1)
add    $0x20,%rbx
cmp    %rbx,%r11
jne    1210 <soustringcopy+0x110>
lea    (%r9,%r8,1),%rbx
cmp    %r9,%r10
je     1250 <soustringcopy+0x150>
mov    %rsi,%rax
sub    %r8,%rax
nopw   0x0(%rax,%rax,1)
movzbl (%rdi,%rbx,1),%ecx
mov    %cl,(%rax,%rbx,1)
add    $0x1,%rbx
cmp    %r14,%rbx
jl     1240 <soustringcopy+0x140>
sub    %edx,%ebx
movslq %ebx,%rax
movb   $0x0,(%rsi,%rax,1)
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define void @soustringcopy(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* %7
store i32 %10, i32* %9
br label %11
11: ; preds = %29, %4
%12 = load i32, i32* %9
%13 = load i32, i32* %7
%14 = load i32, i32* %8
%15 = add nsw i32 %13, %14
%16 = icmp slt i32 %12, %15
br i1 %16, label %17, label %32
17: ; preds = %11
%18 = load i8*, i8** %5
%19 = load i32, i32* %9
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds i8, i8* %18, i64 %20
%22 = load i8, i8* %21
%23 = load i8*, i8** %6
%24 = load i32, i32* %9
%25 = load i32, i32* %7
%26 = sub nsw i32 %24, %25
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds i8, i8* %23, i64 %27
store i8 %22, i8* %28
br label %29
29: ; preds = %17
%30 = load i32, i32* %9
%31 = add nsw i32 %30, 1
store i32 %31, i32* %9
br label %11
32: ; preds = %11
%33 = load i8*, i8** %6
%34 = load i32, i32* %9
%35 = load i32, i32* %7
%36 = sub nsw i32 %34, %35
%37 = sext i32 %36 to i64
%38 = getelementptr inbounds i8, i8* %33, i64 %37
store i8 0, i8* %38
ret void
}

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