#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 */
typedef scalar_t__ uint8_t;
typedef int uint16_t;

/* Variables and functions */
int checksum_icmpv6(char *, int);
int /*<<< orphan*/ memcpy(char *, scalar_t__ *, int);
char *icmp_reply(char *buffer, uint8_t *src_address) {
  int offset = 0;
  uint16_t checksum = 0;
  uint16_t payload_length = 0;
  uint8_t dst_address[16];
  int ix;
  offset += 8;
  for (ix = offset; ix < (offset + 16); ix++) {
    dst_address[ix - offset] = (uint8_t)buffer[ix];
  }
  memcpy(&buffer[offset], &src_address[0], 16);
  offset += 16;
  memcpy(&buffer[offset], &dst_address[0], 16);
  offset += 16;
  buffer[offset] = 0x81;
  payload_length = buffer[4] << 8 | buffer[5];
  checksum = checksum_icmpv6(buffer, (payload_length + 40));
  buffer[42] = (checksum >> 8) & 255;
  buffer[43] = (checksum >> 0) & 255;
  return buffer;
}


x86 assembly (clang, -O0):
<icmp_reply>:
push   %rbp
mov    %rsp,%rbp
sub    $0xb0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x14(%rbp),%eax
add    $0x8,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0xa4(%rbp)
mov    -0xa4(%rbp),%eax
mov    -0x14(%rbp),%ecx
add    $0x10,%ecx
cmp    %ecx,%eax
jge    11a5 <icmp_reply+0x85>
mov    -0x8(%rbp),%rax
movslq -0xa4(%rbp),%rcx
movsbq (%rax,%rcx,1),%rcx
mov    -0xa4(%rbp),%eax
sub    -0x14(%rbp),%eax
cltq
mov    %rcx,-0xa0(%rbp,%rax,8)
ff
mov    -0xa4(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xa4(%rbp)
jmp    115a <icmp_reply+0x3a>
mov    -0x8(%rbp),%rdi
movslq -0x14(%rbp),%rax
add    %rax,%rdi
mov    -0x10(%rbp),%rsi
mov    $0x10,%edx
call   1040 <memcpy@plt>
mov    -0x14(%rbp),%eax
add    $0x10,%eax
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%rdi
movslq -0x14(%rbp),%rax
add    %rax,%rdi
lea    -0xa0(%rbp),%rsi
mov    $0x10,%edx
call   1040 <memcpy@plt>
mov    -0x14(%rbp),%eax
add    $0x10,%eax
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movb   $0x81,(%rax,%rcx,1)
mov    -0x8(%rbp),%rax
movsbl 0x4(%rax),%eax
shl    $0x8,%eax
mov    -0x8(%rbp),%rcx
movsbl 0x5(%rcx),%ecx
or     %ecx,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x1c(%rbp),%esi
add    $0x28,%esi
call   1030 <checksum_icmpv6@plt>
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
sar    $0x8,%eax
and    $0xff,%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x2a(%rax)
mov    -0x18(%rbp),%eax
sar    $0x0,%eax
and    $0xff,%eax
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %cl,0x2b(%rax)
mov    -0x8(%rbp),%rax
add    $0xb0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<icmp_reply>:
push   %rbx
sub    $0x80,%rsp
mov    %rdi,%rbx
add    $0x8,%rdi
movsbq 0x8(%rbx),%rax
mov    %rax,(%rsp)
movsbq 0x9(%rbx),%rax
mov    %rax,0x8(%rsp)
movsbq 0xa(%rbx),%rax
mov    %rax,0x10(%rsp)
movsbq 0xb(%rbx),%rax
mov    %rax,0x18(%rsp)
movsbq 0xc(%rbx),%rax
mov    %rax,0x20(%rsp)
movsbq 0xd(%rbx),%rax
mov    %rax,0x28(%rsp)
movsbq 0xe(%rbx),%rax
mov    %rax,0x30(%rsp)
movsbq 0xf(%rbx),%rax
mov    %rax,0x38(%rsp)
movsbq 0x10(%rbx),%rax
mov    %rax,0x40(%rsp)
movsbq 0x11(%rbx),%rax
mov    %rax,0x48(%rsp)
movsbq 0x12(%rbx),%rax
mov    %rax,0x50(%rsp)
movsbq 0x13(%rbx),%rax
mov    %rax,0x58(%rsp)
movsbq 0x14(%rbx),%rax
mov    %rax,0x60(%rsp)
movsbq 0x15(%rbx),%rax
mov    %rax,0x68(%rsp)
movsbq 0x16(%rbx),%rax
mov    %rax,0x70(%rsp)
movsbq 0x17(%rbx),%rax
mov    %rax,0x78(%rsp)
mov    $0x10,%edx
call   1040 <memcpy@plt>
lea    0x18(%rbx),%rdi
mov    %rsp,%rsi
mov    $0x10,%edx
call   1040 <memcpy@plt>
movb   $0x81,0x28(%rbx)
movsbl 0x4(%rbx),%eax
shl    $0x8,%eax
movsbl 0x5(%rbx),%esi
or     %eax,%esi
add    $0x28,%esi
mov    %rbx,%rdi
call   1030 <checksum_icmpv6@plt>
rol    $0x8,%ax
mov    %ax,0x2a(%rbx)
mov    %rbx,%rax
add    $0x80,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define i8* @icmp_reply(i8* %0, i64* %1) {
%3 = alloca i8*
%4 = alloca i64*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca [16 x i64]
%9 = alloca i32
store i8* %0, i8** %3
store i64* %1, i64** %4
store i32 0, i32* %5
store i32 0, i32* %6
store i32 0, i32* %7
%10 = load i32, i32* %5
%11 = add nsw i32 %10, 8
store i32 %11, i32* %5
%12 = load i32, i32* %5
store i32 %12, i32* %9
br label %13
13: ; preds = %30, %2
%14 = load i32, i32* %9
%15 = load i32, i32* %5
%16 = add nsw i32 %15, 16
%17 = icmp slt i32 %14, %16
br i1 %17, label %18, label %33
18: ; preds = %13
%19 = load i8*, i8** %3
%20 = load i32, i32* %9
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds i8, i8* %19, i64 %21
%23 = load i8, i8* %22
%24 = sext i8 %23 to i64
%25 = load i32, i32* %9
%26 = load i32, i32* %5
%27 = sub nsw i32 %25, %26
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds [16 x i64], [16 x i64]* %8, i64 0, i64 %28
store i64 %24, i64* %29
br label %30
30: ; preds = %18
%31 = load i32, i32* %9
%32 = add nsw i32 %31, 1
store i32 %32, i32* %9
br label %13
33: ; preds = %13
%34 = load i8*, i8** %3
%35 = load i32, i32* %5
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds i8, i8* %34, i64 %36
%38 = load i64*, i64** %4
%39 = getelementptr inbounds i64, i64* %38, i64 0
%40 = call i32 @memcpy(i8* %37, i64* %39, i32 16)
%41 = load i32, i32* %5
%42 = add nsw i32 %41, 16
store i32 %42, i32* %5
%43 = load i8*, i8** %3
%44 = load i32, i32* %5
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds i8, i8* %43, i64 %45
%47 = getelementptr inbounds [16 x i64], [16 x i64]* %8, i64 0, i64 0
%48 = call i32 @memcpy(i8* %46, i64* %47, i32 16)
%49 = load i32, i32* %5
%50 = add nsw i32 %49, 16
store i32 %50, i32* %5
%51 = load i8*, i8** %3
%52 = load i32, i32* %5
%53 = sext i32 %52 to i64
%54 = getelementptr inbounds i8, i8* %51, i64 %53
store i8 -127, i8* %54
%55 = load i8*, i8** %3
%56 = getelementptr inbounds i8, i8* %55, i64 4
%57 = load i8, i8* %56
%58 = sext i8 %57 to i32
%59 = shl i32 %58, 8
%60 = load i8*, i8** %3
%61 = getelementptr inbounds i8, i8* %60, i64 5
%62 = load i8, i8* %61
%63 = sext i8 %62 to i32
%64 = or i32 %59, %63
store i32 %64, i32* %7
%65 = load i8*, i8** %3
%66 = load i32, i32* %7
%67 = add nsw i32 %66, 40
%68 = call i32 @checksum_icmpv6(i8* %65, i32 %67)
store i32 %68, i32* %6
%69 = load i32, i32* %6
%70 = ashr i32 %69, 8
%71 = and i32 %70, 255
%72 = trunc i32 %71 to i8
%73 = load i8*, i8** %3
%74 = getelementptr inbounds i8, i8* %73, i64 42
store i8 %72, i8* %74
%75 = load i32, i32* %6
%76 = ashr i32 %75, 0
%77 = and i32 %76, 255
%78 = trunc i32 %77 to i8
%79 = load i8*, i8** %3
%80 = getelementptr inbounds i8, i8* %79, i64 43
store i8 %78, i8* %80
%81 = load i8*, i8** %3
ret i8* %81
}

LLVM IR (-O2):
define i8* @icmp_reply(i8* returned %0, i64* %1) {
%3 = alloca [16 x i64]
%4 = bitcast [16 x i64]* %3 to i8*
%5 = getelementptr inbounds i8, i8* %0, i64 8
%6 = load i8, i8* %5
%7 = sext i8 %6 to i64
%8 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 0
store i64 %7, i64* %8
%9 = getelementptr inbounds i8, i8* %0, i64 9
%10 = load i8, i8* %9
%11 = sext i8 %10 to i64
%12 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 1
store i64 %11, i64* %12
%13 = getelementptr inbounds i8, i8* %0, i64 10
%14 = load i8, i8* %13
%15 = sext i8 %14 to i64
%16 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 2
store i64 %15, i64* %16
%17 = getelementptr inbounds i8, i8* %0, i64 11
%18 = load i8, i8* %17
%19 = sext i8 %18 to i64
%20 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 3
store i64 %19, i64* %20
%21 = getelementptr inbounds i8, i8* %0, i64 12
%22 = load i8, i8* %21
%23 = sext i8 %22 to i64
%24 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 4
store i64 %23, i64* %24
%25 = getelementptr inbounds i8, i8* %0, i64 13
%26 = load i8, i8* %25
%27 = sext i8 %26 to i64
%28 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 5
store i64 %27, i64* %28
%29 = getelementptr inbounds i8, i8* %0, i64 14
%30 = load i8, i8* %29
%31 = sext i8 %30 to i64
%32 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 6
store i64 %31, i64* %32
%33 = getelementptr inbounds i8, i8* %0, i64 15
%34 = load i8, i8* %33
%35 = sext i8 %34 to i64
%36 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 7
store i64 %35, i64* %36
%37 = getelementptr inbounds i8, i8* %0, i64 16
%38 = load i8, i8* %37
%39 = sext i8 %38 to i64
%40 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 8
store i64 %39, i64* %40
%41 = getelementptr inbounds i8, i8* %0, i64 17
%42 = load i8, i8* %41
%43 = sext i8 %42 to i64
%44 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 9
store i64 %43, i64* %44
%45 = getelementptr inbounds i8, i8* %0, i64 18
%46 = load i8, i8* %45
%47 = sext i8 %46 to i64
%48 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 10
store i64 %47, i64* %48
%49 = getelementptr inbounds i8, i8* %0, i64 19
%50 = load i8, i8* %49
%51 = sext i8 %50 to i64
%52 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 11
store i64 %51, i64* %52
%53 = getelementptr inbounds i8, i8* %0, i64 20
%54 = load i8, i8* %53
%55 = sext i8 %54 to i64
%56 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 12
store i64 %55, i64* %56
%57 = getelementptr inbounds i8, i8* %0, i64 21
%58 = load i8, i8* %57
%59 = sext i8 %58 to i64
%60 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 13
store i64 %59, i64* %60
%61 = getelementptr inbounds i8, i8* %0, i64 22
%62 = load i8, i8* %61
%63 = sext i8 %62 to i64
%64 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 14
store i64 %63, i64* %64
%65 = getelementptr inbounds i8, i8* %0, i64 23
%66 = load i8, i8* %65
%67 = sext i8 %66 to i64
%68 = getelementptr inbounds [16 x i64], [16 x i64]* %3, i64 0, i64 15
store i64 %67, i64* %68
%69 = tail call i32 @memcpy(i8* %5, i64* %1, i32 16)
%70 = getelementptr inbounds i8, i8* %0, i64 24
%71 = call i32 @memcpy(i8* %70, i64* %8, i32 16)
%72 = getelementptr inbounds i8, i8* %0, i64 40
store i8 -127, i8* %72
%73 = getelementptr inbounds i8, i8* %0, i64 4
%74 = load i8, i8* %73
%75 = sext i8 %74 to i32
%76 = shl nsw i32 %75, 8
%77 = getelementptr inbounds i8, i8* %0, i64 5
%78 = load i8, i8* %77
%79 = sext i8 %78 to i32
%80 = or i32 %76, %79
%81 = add nsw i32 %80, 40
%82 = call i32 @checksum_icmpv6(i8* %0, i32 %81)
%83 = lshr i32 %82, 8
%84 = trunc i32 %83 to i8
%85 = getelementptr inbounds i8, i8* %0, i64 42
store i8 %84, i8* %85
%86 = trunc i32 %82 to i8
%87 = getelementptr inbounds i8, i8* %0, i64 43
store i8 %86, i8* %87
ret i8* %0
}