#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 */
int strlen(char const *);
void substring(char *dest, const char *src, int start, int end) {
  int i = start;
  if (start > strlen(src)) {
    return;
  }
  if (end > strlen(src)) {
    end = strlen(src);
  }
  while (i < end) {
    dest[i - start] = src[i];
    i++;
  }
  dest[i - start] = '\0';
}


x86 assembly (clang, -O0):
<substring>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
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    -0x14(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,%ecx
mov    -0x20(%rbp),%eax
cmp    %ecx,%eax
jle    114d <substring+0x3d>
jmp    11c0 <substring+0xb0>
mov    -0x18(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,%ecx
mov    -0x24(%rbp),%eax
cmp    %ecx,%eax
jle    1175 <substring+0x65>
mov    -0x10(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,-0x18(%rbp)
jmp    117a <substring+0x6a>
mov    -0x1c(%rbp),%eax
cmp    -0x18(%rbp),%eax
jge    11af <substring+0x9f>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x8(%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    117a <substring+0x6a>
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    -0x14(%rbp),%ecx
movslq %ecx,%rcx
movb   $0x0,(%rax,%rcx,1)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<substring>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %ecx,%r14d
mov    %edx,%r15d
mov    %rsi,%rbp
mov    %rdi,%rbx
mov    %rsi,%rdi
call   1030 <strlen@plt>
cmp    %r15d,%eax
jl     1348 <substring+0x238>
mov    %rbp,%rdi
call   1030 <strlen@plt>
cmp    %r14d,%eax
jge    114d <substring+0x3d>
mov    %rbp,%rdi
call   1030 <strlen@plt>
mov    %eax,%r14d
mov    %r15d,%eax
cmp    %r15d,%r14d
jle    133f <substring+0x22f>
movslq %r15d,%r8
movslq %r14d,%r12
mov    %r12,%r10
sub    %r8,%r10
mov    %r8,%rcx
cmp    $0x8,%r10
jb     12c1 <substring+0x1b1>
lea    (%r8,%rbp,1),%r11
lea    (%r12,%rbp,1),%rcx
cmp    %rbx,%rcx
jbe    118f <substring+0x7f>
lea    (%rbx,%r10,1),%rdx
mov    %r8,%rcx
cmp    %rdx,%r11
jb     12c1 <substring+0x1b1>
cmp    $0x20,%r10
jae    119c <substring+0x8c>
xor    %edi,%edi
jmp    128a <substring+0x17a>
mov    %r10,%rdi
and    $0xffffffffffffffe0,%rdi
lea    -0x20(%rdi),%rdx
mov    %rdx,%rcx
shr    $0x5,%rcx
add    $0x1,%rcx
mov    %ecx,%r9d
and    $0x3,%r9d
cmp    $0x60,%rdx
jae    11c3 <substring+0xb3>
xor    %edx,%edx
jmp    1238 <substring+0x128>
and    $0xfffffffffffffffc,%rcx
lea    (%r8,%rbp,1),%rsi
add    $0x70,%rsi
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movups -0x70(%rsi,%rdx,1),%xmm0
movups -0x60(%rsi,%rdx,1),%xmm1
movups %xmm0,(%rbx,%rdx,1)
movups %xmm1,0x10(%rbx,%rdx,1)
movups -0x50(%rsi,%rdx,1),%xmm0
movups -0x40(%rsi,%rdx,1),%xmm1
movups %xmm0,0x20(%rbx,%rdx,1)
movups %xmm1,0x30(%rbx,%rdx,1)
movups -0x30(%rsi,%rdx,1),%xmm0
movups -0x20(%rsi,%rdx,1),%xmm1
movups %xmm0,0x40(%rbx,%rdx,1)
movups %xmm1,0x50(%rbx,%rdx,1)
movups -0x10(%rsi,%rdx,1),%xmm0
movups (%rsi,%rdx,1),%xmm1
movups %xmm0,0x60(%rbx,%rdx,1)
movups %xmm1,0x70(%rbx,%rdx,1)
sub    $0xffffffffffffff80,%rdx
add    $0xfffffffffffffffc,%rcx
jne    11e0 <substring+0xd0>
test   %r9,%r9
je     127b <substring+0x16b>
lea    (%rdx,%rbx,1),%rcx
add    $0x10,%rcx
add    %r8,%rdx
add    %rbp,%rdx
add    $0x10,%rdx
shl    $0x5,%r9
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nop
movups -0x10(%rdx,%rsi,1),%xmm0
movups (%rdx,%rsi,1),%xmm1
movups %xmm0,-0x10(%rcx,%rsi,1)
movups %xmm1,(%rcx,%rsi,1)
add    $0x20,%rsi
cmp    %rsi,%r9
jne    1260 <substring+0x150>
cmp    %rdi,%r10
je     133c <substring+0x22c>
test   $0x18,%r10b
je     12bb <substring+0x1ab>
mov    %r10,%rdx
and    $0xfffffffffffffff8,%rdx
lea    (%rdx,%r8,1),%rcx
cs nopw 0x0(%rax,%rax,1)
nop
mov    (%r11,%rdi,1),%rsi
mov    %rsi,(%rbx,%rdi,1)
add    $0x8,%rdi
cmp    %rdi,%rdx
jne    12a0 <substring+0x190>
cmp    %rdx,%r10
jne    12c1 <substring+0x1b1>
jmp    133c <substring+0x22c>
add    %r8,%rdi
mov    %rdi,%rcx
mov    %r14d,%esi
sub    %ecx,%esi
mov    %rcx,%rdx
not    %rdx
add    %r12,%rdx
and    $0x3,%rsi
je     12f2 <substring+0x1e2>
mov    %rbx,%rdi
sub    %r8,%rdi
nopl   0x0(%rax,%rax,1)
movzbl 0x0(%rbp,%rcx,1),%eax
mov    %al,(%rdi,%rcx,1)
add    $0x1,%rcx
add    $0xffffffffffffffff,%rsi
jne    12e0 <substring+0x1d0>
cmp    $0x3,%rdx
jb     133c <substring+0x22c>
mov    %rbx,%rdx
sub    %r8,%rdx
add    $0x3,%rdx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movzbl 0x0(%rbp,%rcx,1),%eax
mov    %al,-0x3(%rdx,%rcx,1)
movzbl 0x1(%rbp,%rcx,1),%eax
mov    %al,-0x2(%rdx,%rcx,1)
movzbl 0x2(%rbp,%rcx,1),%eax
mov    %al,-0x1(%rdx,%rcx,1)
movzbl 0x3(%rbp,%rcx,1),%eax
mov    %al,(%rdx,%rcx,1)
add    $0x4,%rcx
cmp    %rcx,%r12
jne    1310 <substring+0x200>
mov    %r14d,%eax
sub    %r15d,%eax
cltq
movb   $0x0,(%rbx,%rax,1)
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

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

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