#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 */
struct A {
  int dummy;
};

/* Variables and functions */
int A_write(struct A *, void *, int);
int /*<<< orphan*/ write_raw_varint32(unsigned long, void *, int);
int A_write_delimited_to(struct A *_A, void *_buffer, int offset) {
  int i, shift, new_offset, size;
  new_offset = A_write(_A, _buffer, offset);
  size = new_offset - offset;
  shift = (size > 127) ? 2 : 1;
  for (i = new_offset - 1; i >= offset; --i)
    *((char *)_buffer + i + shift) = *((char *)_buffer + i);
  write_raw_varint32((unsigned long)size, _buffer, offset);
  return new_offset + shift;
}


x86 assembly (clang, -O0):
<A_write_delimited_to>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x14(%rbp),%edx
call   1040 <A_write@plt>
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
sub    -0x14(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%edx
mov    $0x1,%eax
mov    $0x2,%ecx
cmp    $0x7f,%edx
cmovg  %ecx,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x20(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jl     11a5 <A_write_delimited_to+0x85>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
add    %rcx,%rax
movslq -0x1c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x18(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x18(%rbp)
jmp    116e <A_write_delimited_to+0x4e>
movslq -0x24(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x14(%rbp),%edx
call   1030 <write_raw_varint32@plt>
mov    -0x20(%rbp),%eax
add    -0x1c(%rbp),%eax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<A_write_delimited_to>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %edx,%r15d
mov    %rsi,%rbx
call   1040 <A_write@plt>
mov    %eax,%r14d
sub    %r15d,%eax
xor    %ebp,%ebp
cmp    $0x7f,%eax
setg   %bpl
add    $0x1,%ebp
mov    %r14d,%r13d
sub    %r15d,%r13d
jle    1184 <A_write_delimited_to+0x64>
mov    %ebp,%r11d
movslq %r14d,%r12
movslq %r15d,%rcx
mov    %r12,%r8
sub    %rcx,%r8
cmp    $0x4,%r8
jae    11a6 <A_write_delimited_to+0x86>
mov    %r12,%rdi
lea    (%r11,%rbx,1),%rax
add    $0xffffffffffffffff,%rax
movzbl -0x1(%rbx,%rdi,1),%edx
mov    %dl,(%rax,%rdi,1)
lea    -0x1(%rdi),%rdx
mov    %rdx,%rdi
cmp    %rcx,%rdx
jg     1170 <A_write_delimited_to+0x50>
movslq %r13d,%rdi
mov    %rbx,%rsi
mov    %r15d,%edx
call   1030 <write_raw_varint32@plt>
add    %r14d,%ebp
mov    %ebp,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %rcx,%rax
not    %rax
add    %r12,%rax
lea    (%r12,%r11,1),%r9
lea    (%rbx,%r9,1),%rdx
add    $0xffffffffffffffff,%rdx
mov    %rdx,%rsi
sub    %rax,%rsi
cmp    %rdx,%rsi
ja     1165 <A_write_delimited_to+0x45>
lea    (%r12,%rbx,1),%rdx
add    $0xffffffffffffffff,%rdx
mov    %rdx,%rsi
sub    %rax,%rsi
cmp    %rdx,%rsi
ja     1165 <A_write_delimited_to+0x45>
lea    (%rcx,%r11,1),%rax
add    %rbx,%rax
lea    (%rbx,%r12,1),%rdx
cmp    %rdx,%rax
jae    11fa <A_write_delimited_to+0xda>
lea    (%rbx,%r9,1),%rax
lea    (%rbx,%rcx,1),%rdx
cmp    %rax,%rdx
jb     1165 <A_write_delimited_to+0x45>
cmp    $0x10,%r8
jae    1207 <A_write_delimited_to+0xe7>
xor    %esi,%esi
jmp    12d4 <A_write_delimited_to+0x1b4>
mov    %r8,%rsi
and    $0xfffffffffffffff0,%rsi
lea    -0x10(%rsi),%rax
mov    %rax,%rdx
shr    $0x4,%rdx
add    $0x1,%rdx
mov    %edx,%r10d
and    $0x3,%r10d
cmp    $0x30,%rax
jae    122e <A_write_delimited_to+0x10e>
xor    %edi,%edi
jmp    128b <A_write_delimited_to+0x16b>
and    $0xfffffffffffffffc,%rdx
mov    %r9,(%rsp)
lea    (%rbx,%r9,1),%rax
add    $0xfffffffffffffff0,%rax
lea    (%r12,%rbx,1),%r9
add    $0xfffffffffffffff0,%r9
xor    %edi,%edi
nopl   0x0(%rax,%rax,1)
movups (%r9,%rdi,1),%xmm0
movups %xmm0,(%rax,%rdi,1)
movups -0x10(%r9,%rdi,1),%xmm0
movups %xmm0,-0x10(%rax,%rdi,1)
movups -0x20(%r9,%rdi,1),%xmm0
movups %xmm0,-0x20(%rax,%rdi,1)
movups -0x30(%r9,%rdi,1),%xmm0
movups %xmm0,-0x30(%rax,%rdi,1)
add    $0xffffffffffffffc0,%rdi
add    $0xfffffffffffffffc,%rdx
jne    1250 <A_write_delimited_to+0x130>
neg    %rdi
mov    (%rsp),%r9
test   %r10,%r10
je     12c5 <A_write_delimited_to+0x1a5>
sub    %rdi,%r9
add    %rbx,%r9
add    $0xfffffffffffffff0,%r9
mov    %r12,%rdx
sub    %rdi,%rdx
add    %rbx,%rdx
add    $0xfffffffffffffff0,%rdx
shl    $0x4,%r10
xor    %edi,%edi
nopl   (%rax)
movups (%rdx,%rdi,1),%xmm0
movups %xmm0,(%r9,%rdi,1)
add    $0xfffffffffffffff0,%rdi
mov    %r10,%rax
add    %rdi,%rax
jne    12b0 <A_write_delimited_to+0x190>
cmp    %rsi,%r8
je     1184 <A_write_delimited_to+0x64>
test   $0xc,%r8b
je     130e <A_write_delimited_to+0x1ee>
mov    %r8,%r9
and    $0xfffffffffffffffc,%r9
mov    %r12,%rdi
sub    %r9,%rdi
sub    %rsi,%r12
lea    (%r12,%rbx,1),%rax
add    $0xfffffffffffffffc,%rax
sub    %r9,%rsi
nop
mov    (%rax),%edx
mov    %edx,(%rax,%r11,1)
add    $0xfffffffffffffffc,%rax
add    $0x4,%rsi
jne    12f0 <A_write_delimited_to+0x1d0>
cmp    %r9,%r8
jne    1168 <A_write_delimited_to+0x48>
jmp    1184 <A_write_delimited_to+0x64>
sub    %rsi,%r12
jmp    1165 <A_write_delimited_to+0x45>

LLVM IR (-O0):
%struct.A = type { i32 }
define i32 @A_write_delimited_to(%struct.A* %0, i8* %1, i32 %2) {
%4 = alloca %struct.A*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
store %struct.A* %0, %struct.A** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%11 = load %struct.A*, %struct.A** %4
%12 = load i8*, i8** %5
%13 = load i32, i32* %6
%14 = call i32 @A_write(%struct.A* %11, i8* %12, i32 %13)
store i32 %14, i32* %9
%15 = load i32, i32* %9
%16 = load i32, i32* %6
%17 = sub nsw i32 %15, %16
store i32 %17, i32* %10
%18 = load i32, i32* %10
%19 = icmp sgt i32 %18, 127
%20 = zext i1 %19 to i64
%21 = select i1 %19, i32 2, i32 1
store i32 %21, i32* %8
%22 = load i32, i32* %9
%23 = sub nsw i32 %22, 1
store i32 %23, i32* %7
br label %24
24: ; preds = %41, %3
%25 = load i32, i32* %7
%26 = load i32, i32* %6
%27 = icmp sge i32 %25, %26
br i1 %27, label %28, label %44
28: ; preds = %24
%29 = load i8*, i8** %5
%30 = load i32, i32* %7
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds i8, i8* %29, i64 %31
%33 = load i8, i8* %32
%34 = load i8*, i8** %5
%35 = load i32, i32* %7
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds i8, i8* %34, i64 %36
%38 = load i32, i32* %8
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds i8, i8* %37, i64 %39
store i8 %33, i8* %40
br label %41
41: ; preds = %28
%42 = load i32, i32* %7
%43 = add nsw i32 %42, -1
store i32 %43, i32* %7
br label %24
44: ; preds = %24
%45 = load i32, i32* %10
%46 = sext i32 %45 to i64
%47 = load i8*, i8** %5
%48 = load i32, i32* %6
%49 = call i32 @write_raw_varint32(i64 %46, i8* %47, i32 %48)
%50 = load i32, i32* %9
%51 = load i32, i32* %8
%52 = add nsw i32 %50, %51
ret i32 %52
}

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