#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 */
size_t strlen(char const *);
int /*<<< orphan*/ strncpy(char *, char const *, size_t);
char *strins(char *s, size_t pos, const char *t) {
  size_t l1, l2, i;
  char *s1, *s2;
  l1 = strlen(s);
  if (pos <= l1) {
    l2 = strlen(t);
    s1 = s + l1 + l2;
    s2 = s + l1;
    for (i = l1 - pos + 1; i > 0; --i)
      *s1-- = *s2--;
    strncpy(s + pos, t, l2);
    return s;
  } else {
    return NULL;
  }
}


x86 assembly (clang, -O0):
<strins>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    -0x10(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x28(%rbp),%rax
ja     11e8 <strins+0xc8>
mov    -0x20(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
add    -0x28(%rbp),%rax
add    -0x30(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x10(%rbp),%rax
add    -0x28(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x28(%rbp),%rax
sub    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
cmpq   $0x0,-0x38(%rbp)
jbe    11c6 <strins+0xa6>
mov    -0x48(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x48(%rbp)
mov    (%rax),%cl
mov    -0x40(%rbp),%rax
mov    %rax,%rdx
add    $0xffffffffffffffff,%rdx
mov    %rdx,-0x40(%rbp)
mov    %cl,(%rax)
mov    -0x38(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x38(%rbp)
jmp    1188 <strins+0x68>
mov    -0x10(%rbp),%rdi
add    -0x18(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    -0x30(%rbp),%rdx
call   1030 <strncpy@plt>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    11f0 <strins+0xd0>
movq   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<strins>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%r12
call   1040 <strlen@plt>
mov    %rax,%rbx
sub    %r15,%rbx
jae    1149 <strins+0x29>
xor    %r12d,%r12d
jmp    1220 <strins+0x100>
mov    %rax,%r13
mov    %r14,%rdi
call   1040 <strlen@plt>
mov    %rbx,%r10
inc    %r10
je     120f <strins+0xef>
lea    (%r12,%r13,1),%r9
lea    (%r9,%rax,1),%r8
cmp    $0x4,%r10
jae    1232 <strins+0x112>
mov    %r9,%rsi
mov    %r8,%rbx
mov    %r10,%rbp
lea    -0x1(%rbp),%r8
mov    %rbp,%rdi
and    $0x7,%rdi
je     11a9 <strins+0x89>
xor    %edx,%edx
nopw   0x0(%rax,%rax,1)
movzbl (%rsi),%ecx
add    $0xffffffffffffffff,%rsi
mov    %cl,(%rbx)
add    $0xffffffffffffffff,%rbx
add    $0x1,%rdx
cmp    %rdx,%rdi
jne    1190 <strins+0x70>
sub    %rdx,%rbp
cmp    $0x7,%r8
jb     120f <strins+0xef>
neg    %rbp
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movzbl (%rsi,%rdx,1),%ecx
mov    %cl,(%rbx,%rdx,1)
movzbl -0x1(%rsi,%rdx,1),%ecx
mov    %cl,-0x1(%rbx,%rdx,1)
movzbl -0x2(%rsi,%rdx,1),%ecx
mov    %cl,-0x2(%rbx,%rdx,1)
movzbl -0x3(%rsi,%rdx,1),%ecx
mov    %cl,-0x3(%rbx,%rdx,1)
movzbl -0x4(%rsi,%rdx,1),%ecx
mov    %cl,-0x4(%rbx,%rdx,1)
movzbl -0x5(%rsi,%rdx,1),%ecx
mov    %cl,-0x5(%rbx,%rdx,1)
movzbl -0x6(%rsi,%rdx,1),%ecx
mov    %cl,-0x6(%rbx,%rdx,1)
movzbl -0x7(%rsi,%rdx,1),%ecx
mov    %cl,-0x7(%rbx,%rdx,1)
add    $0xfffffffffffffff8,%rdx
cmp    %rdx,%rbp
jne    11c0 <strins+0xa0>
add    %r12,%r15
mov    %r15,%rdi
mov    %r14,%rsi
mov    %rax,%rdx
call   1030 <strncpy@plt>
mov    %r12,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %r8,%rcx
sub    %rbx,%rcx
cmp    %r8,%rcx
ja     1172 <strins+0x52>
mov    %r9,%rcx
sub    %rbx,%rcx
cmp    %r9,%rcx
ja     1172 <strins+0x52>
lea    (%rax,%r15,1),%rcx
add    %r12,%rcx
mov    %rax,%rdx
add    %r13,%rdx
lea    (%r12,%r13,1),%rsi
add    $0x1,%rsi
cmp    %rsi,%rcx
jae    127f <strins+0x15f>
lea    (%r12,%rdx,1),%rcx
add    $0x1,%rcx
lea    (%r12,%r15,1),%rsi
cmp    %rcx,%rsi
jb     1172 <strins+0x52>
cmp    $0x10,%r10
jae    128c <strins+0x16c>
xor    %edi,%edi
jmp    1353 <strins+0x233>
mov    %r10,%rdi
and    $0xfffffffffffffff0,%rdi
lea    -0x10(%rdi),%rcx
mov    %rcx,%rsi
shr    $0x4,%rsi
add    $0x1,%rsi
mov    %esi,%r11d
and    $0x3,%r11d
cmp    $0x30,%rcx
jae    12b3 <strins+0x193>
xor    %ecx,%ecx
jmp    1304 <strins+0x1e4>
and    $0xfffffffffffffffc,%rsi
lea    -0xf(%r9),%rbx
lea    -0xf(%r8),%rbp
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movups (%rbx,%rcx,1),%xmm0
movups %xmm0,0x0(%rbp,%rcx,1)
movups -0x10(%rbx,%rcx,1),%xmm0
movups %xmm0,-0x10(%rbp,%rcx,1)
movups -0x20(%rbx,%rcx,1),%xmm0
movups %xmm0,-0x20(%rbp,%rcx,1)
movups -0x30(%rbx,%rcx,1),%xmm0
movups %xmm0,-0x30(%rbp,%rcx,1)
add    $0xffffffffffffffc0,%rcx
add    $0xfffffffffffffffc,%rsi
jne    12d0 <strins+0x1b0>
neg    %rcx
test   %r11,%r11
je     1344 <strins+0x224>
sub    %rcx,%rdx
lea    (%rdx,%r12,1),%rsi
add    $0xfffffffffffffff1,%rsi
sub    %rcx,%r13
lea    (%r12,%r13,1),%rcx
add    $0xfffffffffffffff1,%rcx
shl    $0x4,%r11
xor    %ebp,%ebp
cs nopw 0x0(%rax,%rax,1)
nop
movups (%rcx,%rbp,1),%xmm0
movups %xmm0,(%rsi,%rbp,1)
add    $0xfffffffffffffff0,%rbp
mov    %r11,%rbx
add    %rbp,%rbx
jne    1330 <strins+0x210>
cmp    %rdi,%r10
je     120f <strins+0xef>
test   $0xc,%r10b
je     13a1 <strins+0x281>
mov    %r10,%r11
and    $0xfffffffffffffffc,%r11
mov    %r11,%rcx
neg    %rcx
mov    %r9,%rsi
sub    %r11,%rsi
mov    %r8,%rbx
sub    %r11,%rbx
mov    %r10d,%ebp
and    $0x3,%ebp
neg    %rdi
cs nopw 0x0(%rax,%rax,1)
nop
mov    -0x3(%r9,%rdi,1),%edx
mov    %edx,-0x3(%r8,%rdi,1)
add    $0xfffffffffffffffc,%rdi
cmp    %rdi,%rcx
jne    1380 <strins+0x260>
cmp    %r11,%r10
jne    117b <strins+0x5b>
jmp    120f <strins+0xef>
and    $0xf,%r10d
sub    %rdi,%r8
sub    %rdi,%r9
jmp    1172 <strins+0x52>

LLVM IR (-O0):
define i8* @strins(i8* %0, i64 %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i8*
%8 = alloca i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i8*
%12 = alloca i8*
store i8* %0, i8** %5
store i64 %1, i64* %6
store i8* %2, i8** %7
%13 = load i8*, i8** %5
%14 = call i64 @strlen(i8* %13)
store i64 %14, i64* %8
%15 = load i64, i64* %6
%16 = load i64, i64* %8
%17 = icmp ule i64 %15, %16
br i1 %17, label %18, label %53
18: ; preds = %3
%19 = load i8*, i8** %7
%20 = call i64 @strlen(i8* %19)
store i64 %20, i64* %9
%21 = load i8*, i8** %5
%22 = load i64, i64* %8
%23 = getelementptr inbounds i8, i8* %21, i64 %22
%24 = load i64, i64* %9
%25 = getelementptr inbounds i8, i8* %23, i64 %24
store i8* %25, i8** %11
%26 = load i8*, i8** %5
%27 = load i64, i64* %8
%28 = getelementptr inbounds i8, i8* %26, i64 %27
store i8* %28, i8** %12
%29 = load i64, i64* %8
%30 = load i64, i64* %6
%31 = sub i64 %29, %30
%32 = add i64 %31, 1
store i64 %32, i64* %10
br label %33
33: ; preds = %42, %18
%34 = load i64, i64* %10
%35 = icmp ugt i64 %34, 0
br i1 %35, label %36, label %45
36: ; preds = %33
%37 = load i8*, i8** %12
%38 = getelementptr inbounds i8, i8* %37, i32 -1
store i8* %38, i8** %12
%39 = load i8, i8* %37
%40 = load i8*, i8** %11
%41 = getelementptr inbounds i8, i8* %40, i32 -1
store i8* %41, i8** %11
store i8 %39, i8* %40
br label %42
42: ; preds = %36
%43 = load i64, i64* %10
%44 = add i64 %43, -1
store i64 %44, i64* %10
br label %33
45: ; preds = %33
%46 = load i8*, i8** %5
%47 = load i64, i64* %6
%48 = getelementptr inbounds i8, i8* %46, i64 %47
%49 = load i8*, i8** %7
%50 = load i64, i64* %9
%51 = call i32 @strncpy(i8* %48, i8* %49, i64 %50)
%52 = load i8*, i8** %5
store i8* %52, i8** %4
br label %54
53: ; preds = %3
store i8* null, i8** %4
br label %54
54: ; preds = %53, %45
%55 = load i8*, i8** %4
ret i8* %55
}

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