#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 */
unsigned int Strings_Length(char *, unsigned int);
int /*<<< orphan*/ memcpy(char *, char *, unsigned int);
void Strings_Extract(char *source_, unsigned int _source_high,
                     unsigned int startIndex, unsigned int numberToExtract,
                     char *destination, unsigned int _destination_high) {
  unsigned int sh;
  unsigned int dh;
  unsigned int i;
  char source[_source_high + 1];
  memcpy(source, source_, _source_high + 1);
  sh = Strings_Length((char *)source, _source_high);
  dh = _destination_high;
  i = 0;
  while (((i < numberToExtract) && (startIndex < sh)) && (i <= dh)) {
    destination[i] = source[startIndex];
    i += 1;
    startIndex += 1;
  }
  if (i <= dh) {
    destination[i] = (char)000;
  }
}


x86 assembly (clang, -O0):
<Strings_Extract>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8,-0x20(%rbp)
mov    %r9d,-0x24(%rbp)
mov    -0xc(%rbp),%eax
add    $0x1,%eax
mov    %rsp,%rcx
mov    %rcx,-0x38(%rbp)
mov    %rax,%rcx
add    $0xf,%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%rdi
sub    %rcx,%rdi
mov    %rdi,-0x48(%rbp)
mov    %rdi,%rsp
mov    %rax,-0x40(%rbp)
mov    -0x8(%rbp),%rsi
mov    -0xc(%rbp),%edx
add    $0x1,%edx
call   1030 <memcpy@plt>
mov    -0x48(%rbp),%rdi
mov    -0xc(%rbp),%esi
call   1040 <Strings_Length@plt>
mov    %eax,-0x28(%rbp)
mov    -0x24(%rbp),%eax
mov    %eax,-0x2c(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%ecx
xor    %eax,%eax
cmp    -0x14(%rbp),%ecx
mov    %al,-0x49(%rbp)
jae    11bf <Strings_Extract+0x9f>
mov    -0x10(%rbp),%ecx
xor    %eax,%eax
cmp    -0x28(%rbp),%ecx
mov    %al,-0x49(%rbp)
jae    11bf <Strings_Extract+0x9f>
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
setbe  %al
mov    %al,-0x49(%rbp)
mov    -0x49(%rbp),%al
test   $0x1,%al
jne    11cf <Strings_Extract+0xaf>
jmp    11fa <Strings_Extract+0xda>
mov    -0x48(%rbp),%rax
mov    -0x10(%rbp),%ecx
mov    (%rax,%rcx,1),%dl
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    1191 <Strings_Extract+0x71>
mov    -0x30(%rbp),%eax
cmp    -0x2c(%rbp),%eax
ja     1211 <Strings_Extract+0xf1>
mov    -0x20(%rbp),%rax
mov    -0x30(%rbp),%ecx
movb   $0x0,(%rax,%rcx,1)
mov    -0x38(%rbp),%rax
mov    %rax,%rsp
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Strings_Extract>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %r9d,-0x2c(%rbp)
mov    %r8,%rbx
mov    %ecx,%r12d
mov    %edx,%r13d
mov    %esi,%r15d
mov    %rdi,%rsi
lea    0x1(%r15),%edx
mov    %rsp,%r14
lea    0xf(%rdx),%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r14
mov    %r14,%rsp
mov    %r14,%rdi
call   1030 <memcpy@plt>
mov    %r14,%rdi
mov    %r15d,%esi
call   1040 <Strings_Length@plt>
xor    %ecx,%ecx
test   %r12d,%r12d
je     13f0 <Strings_Extract+0x2d0>
cmp    %r13d,%eax
jbe    13f0 <Strings_Extract+0x2d0>
mov    %r13d,%ecx
mov    %eax,%r10d
mov    %r12d,%r11d
lea    -0x1(%r11),%rax
mov    %rcx,%r8
not    %r8
add    %r10,%r8
cmp    %rax,%r8
cmovae %rax,%r8
mov    -0x2c(%rbp),%r15d
test   %rax,%rax
cmove  %rax,%r8
cmp    %r15,%r8
cmovae %r15,%r8
cmp    $0xf,%r8
jae    11b9 <Strings_Extract+0x99>
xor    %eax,%eax
jmp    13b2 <Strings_Extract+0x292>
add    $0x1,%r8
movabs $0x1fffffff0,%rax
and    %r8,%rax
lea    -0x10(%rax),%rdx
mov    %rdx,%rsi
shr    $0x4,%rsi
add    $0x1,%rsi
mov    %esi,%r9d
and    $0x3,%r9d
cmp    $0x30,%rdx
jae    1237 <Strings_Extract+0x117>
movdqa 0xe12(%rip),%xmm0
movdqa 0xe19(%rip),%xmm10
movdqa 0xe21(%rip),%xmm2
movdqa 0xe29(%rip),%xmm3
movdqa 0xe31(%rip),%xmm4
movdqa 0xe39(%rip),%xmm5
movdqa 0xe41(%rip),%xmm6
movdqa 0xe49(%rip),%xmm7
xor    %edx,%edx
test   %r9,%r9
jne    12fd <Strings_Extract+0x1dd>
jmp    1360 <Strings_Extract+0x240>
and    $0xfffffffffffffffc,%rsi
lea    (%rcx,%r14,1),%rdi
add    $0x30,%rdi
movdqa 0xdb5(%rip),%xmm0
movdqa 0xdbc(%rip),%xmm10
movdqa 0xdc4(%rip),%xmm2
movdqa 0xdcc(%rip),%xmm3
movdqa 0xdd4(%rip),%xmm4
movdqa 0xddc(%rip),%xmm5
movdqa 0xde4(%rip),%xmm6
movdqa 0xdec(%rip),%xmm7
xor    %edx,%edx
movdqa 0xdf1(%rip),%xmm9
nop
movdqa %xmm0,%xmm8
movups -0x30(%rdi,%rdx,1),%xmm1
movups %xmm1,(%rbx,%rdx,1)
movups -0x20(%rdi,%rdx,1),%xmm1
movups %xmm1,0x10(%rbx,%rdx,1)
movups -0x10(%rdi,%rdx,1),%xmm1
movups %xmm1,0x20(%rbx,%rdx,1)
movdqu (%rdi,%rdx,1),%xmm1
movdqu %xmm1,0x30(%rbx,%rdx,1)
add    $0x40,%rdx
paddq  %xmm9,%xmm7
paddq  %xmm9,%xmm6
paddq  %xmm9,%xmm5
paddq  %xmm9,%xmm4
paddq  %xmm9,%xmm3
paddq  %xmm9,%xmm2
paddq  %xmm9,%xmm10
paddq  %xmm9,%xmm0
add    $0xfffffffffffffffc,%rsi
jne    1290 <Strings_Extract+0x170>
paddq  0xd98(%rip),%xmm8
test   %r9,%r9
je     1360 <Strings_Extract+0x240>
lea    (%rbx,%rdx,1),%rsi
add    %rcx,%rdx
add    %r14,%rdx
shl    $0x4,%r9
xor    %edi,%edi
movdqa 0xd8a(%rip),%xmm9
cs nopw 0x0(%rax,%rax,1)
movdqa %xmm0,%xmm8
movdqu (%rdx,%rdi,1),%xmm1
movdqu %xmm1,(%rsi,%rdi,1)
paddq  %xmm9,%xmm7
paddq  %xmm9,%xmm6
paddq  %xmm9,%xmm5
paddq  %xmm9,%xmm4
paddq  %xmm9,%xmm3
paddq  %xmm9,%xmm2
paddq  %xmm9,%xmm10
paddq  %xmm9,%xmm0
add    $0x10,%rdi
cmp    %rdi,%r9
jne    1320 <Strings_Extract+0x200>
cmp    %rax,%r8
jne    13af <Strings_Extract+0x28f>
movq   %r15,%xmm0
pshufd $0x44,%xmm0,%xmm0
movdqa 0xd39(%rip),%xmm1
pxor   %xmm1,%xmm8
pxor   %xmm1,%xmm0
movdqa %xmm0,%xmm1
pcmpgtd %xmm8,%xmm1
pcmpeqd %xmm8,%xmm0
pshufd $0xf5,%xmm0,%xmm0
pand   %xmm1,%xmm0
pshufd $0xf5,%xmm1,%xmm1
por    %xmm0,%xmm1
pcmpeqd %xmm0,%xmm0
pxor   %xmm1,%xmm0
pextrw $0x4,%xmm0,%edx
jmp    13e9 <Strings_Extract+0x2c9>
add    %rax,%rcx
add    $0x1,%rcx
cs nopw 0x0(%rax,%rax,1)
mov    %rax,%rdx
movzbl -0x1(%r14,%rcx,1),%eax
mov    %al,(%rbx,%rdx,1)
lea    0x1(%rdx),%rax
cmp    %r15,%rdx
setae  %dl
jae    13e9 <Strings_Extract+0x2c9>
cmp    %r11,%rax
jae    13e9 <Strings_Extract+0x2c9>
lea    0x1(%rcx),%rsi
cmp    %r10,%rcx
mov    %rsi,%rcx
jb     13c0 <Strings_Extract+0x2a0>
test   $0x1,%dl
jne    13f4 <Strings_Extract+0x2d4>
mov    %eax,%ecx
movb   $0x0,(%rbx,%rcx,1)
lea    -0x28(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @Strings_Extract(i8* %0, i32 %1, i32 %2, i32 %3, i8* %4, i32 %5) {
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i8*
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i8*
%17 = alloca i64
store i8* %0, i8** %7
store i32 %1, i32* %8
store i32 %2, i32* %9
store i32 %3, i32* %10
store i8* %4, i8** %11
store i32 %5, i32* %12
%18 = load i32, i32* %8
%19 = add i32 %18, 1
%20 = zext i32 %19 to i64
%21 = call i8* @llvm.stacksave()
store i8* %21, i8** %16
%22 = alloca i8, i64 %20
store i64 %20, i64* %17
%23 = load i8*, i8** %7
%24 = load i32, i32* %8
%25 = add i32 %24, 1
%26 = call i32 @memcpy(i8* %22, i8* %23, i32 %25)
%27 = load i32, i32* %8
%28 = call i32 @Strings_Length(i8* %22, i32 %27)
store i32 %28, i32* %13
%29 = load i32, i32* %12
store i32 %29, i32* %14
store i32 0, i32* %15
br label %30
30: ; preds = %44, %6
%31 = load i32, i32* %15
%32 = load i32, i32* %10
%33 = icmp ult i32 %31, %32
br i1 %33, label %34, label %42
34: ; preds = %30
%35 = load i32, i32* %9
%36 = load i32, i32* %13
%37 = icmp ult i32 %35, %36
br i1 %37, label %38, label %42
38: ; preds = %34
%39 = load i32, i32* %15
%40 = load i32, i32* %14
%41 = icmp ule i32 %39, %40
br label %42
42: ; preds = %38, %34, %30
%43 = phi i1 [ false, %34 ], [ false, %30 ], [ %41, %38 ]
br i1 %43, label %44, label %57
44: ; preds = %42
%45 = load i32, i32* %9
%46 = zext i32 %45 to i64
%47 = getelementptr inbounds i8, i8* %22, i64 %46
%48 = load i8, i8* %47
%49 = load i8*, i8** %11
%50 = load i32, i32* %15
%51 = zext i32 %50 to i64
%52 = getelementptr inbounds i8, i8* %49, i64 %51
store i8 %48, i8* %52
%53 = load i32, i32* %15
%54 = add i32 %53, 1
store i32 %54, i32* %15
%55 = load i32, i32* %9
%56 = add i32 %55, 1
store i32 %56, i32* %9
br label %30
57: ; preds = %42
%58 = load i32, i32* %15
%59 = load i32, i32* %14
%60 = icmp ule i32 %58, %59
br i1 %60, label %61, label %66
61: ; preds = %57
%62 = load i8*, i8** %11
%63 = load i32, i32* %15
%64 = zext i32 %63 to i64
%65 = getelementptr inbounds i8, i8* %62, i64 %64
store i8 0, i8* %65
br label %66
66: ; preds = %61, %57
%67 = load i8*, i8** %16
ret void
}

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