#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 int pid_t;
typedef int /*<<< orphan*/ parent_buff;
typedef int /*<<< orphan*/ child_buff;

/* Variables and functions */
int EXIT_FAILURE;
int /*<<< orphan*/ EXIT_SUCCESS;
int /*<<< orphan*/ _Exit(int /*<<< orphan*/);
int /*<<< orphan*/ calculate_result(int *);
int /*<<< orphan*/ close(int);
int fork();
int /*<<< orphan*/ perror(char *);
int pipe(int *);
int /*<<< orphan*/ printf(char *, int, int, int);
int /*<<< orphan*/ read(int, int *, int);
int /*<<< orphan*/ wait(int /*<<< orphan*/ *);
int /*<<< orphan*/ write(int, int *, int);
int main(void) {
  int child_pipe_fd[2];
  int parent_pipe_fd[2];
  pid_t child_pid;
  int pipe_status = 0;
  int child_buff[3];
  int parent_buff[3];
  pipe_status = pipe(parent_pipe_fd);
  if (pipe_status == -1) {
    perror("pipe()");
  } else {
    pipe_status = pipe(child_pipe_fd);
    if (pipe_status == -1) {
      perror("pipe()");
      return EXIT_FAILURE;
    }
    child_pid = fork();
    if (child_pid == -1) {
      perror("fork()");
    } else if (child_pid == 0) {
      child_buff[0] = 2;
      child_buff[1] = 3;
      child_buff[2] = -5;
      close(parent_pipe_fd[0]);
      close(child_pipe_fd[1]);
      write(parent_pipe_fd[1], child_buff, sizeof(child_buff));
      close(parent_pipe_fd[1]);
      read(child_pipe_fd[0], child_buff, sizeof(child_buff));
      printf("Parent said: %d,%d,%d\n", child_buff[0], child_buff[1],
             child_buff[2]);
      _Exit(EXIT_SUCCESS);
    } else {
      close(parent_pipe_fd[1]);
      close(child_pipe_fd[0]);
      read(parent_pipe_fd[0], parent_buff, sizeof(parent_buff));
      close(parent_pipe_fd[0]);
      printf("Child said: %d,%d,%d\n", parent_buff[0], parent_buff[1],
             parent_buff[2]);
      calculate_result(parent_buff);
      write(child_pipe_fd[1], parent_buff, sizeof(parent_buff));
      wait(NULL);
    }
  }
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movl   $0x0,-0x4(%rbp)
movl   $0x0,-0x1c(%rbp)
lea    -0x14(%rbp),%rdi
call   1060 <pipe@plt>
mov    %eax,-0x1c(%rbp)
cmpl   $0xffffffff,-0x1c(%rbp)
jne    11dd <main+0x3d>
lea    0xe2d(%rip),%rdi
call   1080 <perror@plt>
jmp    131c <main+0x17c>
lea    -0xc(%rbp),%rdi
call   1060 <pipe@plt>
mov    %eax,-0x1c(%rbp)
cmpl   $0xffffffff,-0x1c(%rbp)
jne    1210 <main+0x70>
lea    0xe06(%rip),%rdi
call   1080 <perror@plt>
mov    0x2dda(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x4(%rbp)
jmp    1323 <main+0x183>
mov    $0x0,%al
call   10c0 <fork@plt>
mov    %eax,-0x18(%rbp)
cmpl   $0xffffffff,-0x18(%rbp)
jne    1235 <main+0x95>
lea    0xddc(%rip),%rdi
call   1080 <perror@plt>
jmp    1317 <main+0x177>
cmpl   $0x0,-0x18(%rbp)
jne    12b1 <main+0x111>
movl   $0x2,-0x28(%rbp)
movl   $0x3,-0x24(%rbp)
movl   $0xfffffffb,-0x20(%rbp)
mov    -0x14(%rbp),%edi
call   1050 <close@plt>
mov    -0x8(%rbp),%edi
call   1050 <close@plt>
mov    -0x10(%rbp),%edi
lea    -0x28(%rbp),%rsi
mov    $0xc,%edx
call   1030 <write@plt>
mov    -0x10(%rbp),%edi
call   1050 <close@plt>
mov    -0xc(%rbp),%edi
lea    -0x28(%rbp),%rsi
mov    $0xc,%edx
call   1070 <read@plt>
mov    -0x28(%rbp),%esi
mov    -0x24(%rbp),%edx
mov    -0x20(%rbp),%ecx
lea    0xd70(%rip),%rdi
call   1040 <printf@plt>
mov    0x2d2e(%rip),%rax
mov    (%rax),%edi
call   1090 <_Exit@plt>
mov    -0x10(%rbp),%edi
call   1050 <close@plt>
mov    -0xc(%rbp),%edi
call   1050 <close@plt>
mov    -0x14(%rbp),%edi
lea    -0x34(%rbp),%rsi
mov    $0xc,%edx
call   1070 <read@plt>
mov    -0x14(%rbp),%edi
call   1050 <close@plt>
mov    -0x34(%rbp),%esi
mov    -0x30(%rbp),%edx
mov    -0x2c(%rbp),%ecx
lea    0xd3b(%rip),%rdi
call   1040 <printf@plt>
lea    -0x34(%rbp),%rdi
call   10a0 <calculate_result@plt>
mov    -0x8(%rbp),%edi
lea    -0x34(%rbp),%rsi
mov    $0xc,%edx
call   1030 <write@plt>
xor    %eax,%eax
mov    %eax,%edi
call   10b0 <wait@plt>
jmp    1317 <main+0x177>
jmp    131c <main+0x17c>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbx
sub    $0x20,%rsp
lea    0x4(%rsp),%rdi
call   1060 <pipe@plt>
cmp    $0xffffffff,%eax
je     1258 <main+0xb8>
lea    0x18(%rsp),%rdi
call   1060 <pipe@plt>
cmp    $0xffffffff,%eax
je     1268 <main+0xc8>
xor    %ebx,%ebx
xor    %eax,%eax
call   10c0 <fork@plt>
cmp    $0xffffffff,%eax
je     127f <main+0xdf>
test   %eax,%eax
je     128d <main+0xed>
mov    0x8(%rsp),%edi
call   1050 <close@plt>
mov    0x18(%rsp),%edi
call   1050 <close@plt>
mov    0x4(%rsp),%edi
lea    0xc(%rsp),%rbx
mov    %rbx,%rsi
mov    $0xc,%edx
call   1070 <read@plt>
mov    0x4(%rsp),%edi
call   1050 <close@plt>
mov    0xc(%rsp),%esi
mov    0x10(%rsp),%edx
mov    0x14(%rsp),%ecx
lea    0xdfc(%rip),%rdi
call   1040 <printf@plt>
mov    %rbx,%rdi
call   10a0 <calculate_result@plt>
mov    0x1c(%rsp),%edi
mov    %rbx,%rsi
mov    $0xc,%edx
call   1030 <write@plt>
xor    %ebx,%ebx
xor    %edi,%edi
call   10b0 <wait@plt>
mov    %ebx,%eax
add    $0x20,%rsp
pop    %rbx
ret
lea    0xda1(%rip),%rdi
call   1080 <perror@plt>
xor    %ebx,%ebx
jmp    1250 <main+0xb0>
lea    0xd91(%rip),%rdi
call   1080 <perror@plt>
mov    0x2d65(%rip),%rax
mov    (%rax),%ebx
jmp    1250 <main+0xb0>
lea    0xd81(%rip),%rdi
call   1080 <perror@plt>
jmp    1250 <main+0xb0>
movabs $0x300000002,%rax
mov    %rax,0xc(%rsp)
movl   $0xfffffffb,0x14(%rsp)
ff
mov    0x4(%rsp),%edi
call   1050 <close@plt>
mov    0x1c(%rsp),%edi
call   1050 <close@plt>
mov    0x8(%rsp),%edi
lea    0xc(%rsp),%rbx
mov    %rbx,%rsi
mov    $0xc,%edx
call   1030 <write@plt>
mov    0x8(%rsp),%edi
call   1050 <close@plt>
mov    0x18(%rsp),%edi
mov    %rbx,%rsi
mov    $0xc,%edx
call   1070 <read@plt>
mov    0xc(%rsp),%esi
mov    0x10(%rsp),%edx
mov    0x14(%rsp),%ecx
lea    0xd15(%rip),%rdi
call   1040 <printf@plt>
mov    0x2cd3(%rip),%rax
mov    (%rax),%edi
call   1090 <_Exit@plt>

LLVM IR (-O0):
@.str = [7 x i8] c"pipe()\00"
@EXIT_FAILURE = global i32 0
@.str.1 = [7 x i8] c"fork()\00"
@.str.2 = [23 x i8] c"Parent said: %d,%d,%d\0A\00"
@EXIT_SUCCESS = global i32 0
@.str.3 = [22 x i8] c"Child said: %d,%d,%d\0A\00"
define i32 @main() {
%1 = alloca i32
%2 = alloca [2 x i32]
%3 = alloca [2 x i32]
%4 = alloca i32
%5 = alloca i32
%6 = alloca [3 x i32]
%7 = alloca [3 x i32]
store i32 0, i32* %1
store i32 0, i32* %5
%8 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 0
%9 = call i32 @pipe(i32* %8)
store i32 %9, i32* %5
%10 = load i32, i32* %5
%11 = icmp eq i32 %10, -1
br i1 %11, label %12, label %14
12: ; preds = %0
%13 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0))
br label %91
14: ; preds = %0
%15 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%16 = call i32 @pipe(i32* %15)
store i32 %16, i32* %5
%17 = load i32, i32* %5
%18 = icmp eq i32 %17, -1
br i1 %18, label %19, label %22
19: ; preds = %14
%20 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0))
%21 = load i32, i32* @EXIT_FAILURE
store i32 %21, i32* %1
br label %92
22: ; preds = %14
%23 = call i32 (...) @fork()
store i32 %23, i32* %4
%24 = load i32, i32* %4
%25 = icmp eq i32 %24, -1
br i1 %25, label %26, label %28
26: ; preds = %22
%27 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i64 0, i64 0))
br label %90
28: ; preds = %22
%29 = load i32, i32* %4
%30 = icmp eq i32 %29, 0
br i1 %30, label %31, label %61
31: ; preds = %28
%32 = getelementptr inbounds [3 x i32], [3 x i32]* %6, i64 0, i64 0
store i32 2, i32* %32
%33 = getelementptr inbounds [3 x i32], [3 x i32]* %6, i64 0, i64 1
store i32 3, i32* %33
%34 = getelementptr inbounds [3 x i32], [3 x i32]* %6, i64 0, i64 2
store i32 -5, i32* %34
%35 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 0
%36 = load i32, i32* %35
%37 = call i32 @close(i32 %36)
%38 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%39 = load i32, i32* %38
%40 = call i32 @close(i32 %39)
%41 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 1
%42 = load i32, i32* %41
%43 = getelementptr inbounds [3 x i32], [3 x i32]* %6, i64 0, i64 0
%44 = call i32 @write(i32 %42, i32* %43, i32 12)
%45 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 1
%46 = load i32, i32* %45
%47 = call i32 @close(i32 %46)
%48 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%49 = load i32, i32* %48
%50 = getelementptr inbounds [3 x i32], [3 x i32]* %6, i64 0, i64 0
%51 = call i32 @read(i32 %49, i32* %50, i32 12)
%52 = getelementptr inbounds [3 x i32], [3 x i32]* %6, i64 0, i64 0
%53 = load i32, i32* %52
%54 = getelementptr inbounds [3 x i32], [3 x i32]* %6, i64 0, i64 1
%55 = load i32, i32* %54
%56 = getelementptr inbounds [3 x i32], [3 x i32]* %6, i64 0, i64 2
%57 = load i32, i32* %56
%58 = call i32 @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.2, i64 0, i64 0), i32 %53, i32 %55, i32 %57)
%59 = load i32, i32* @EXIT_SUCCESS
%60 = call i32 @_Exit(i32 %59)
unreachable
61: ; preds = %28
%62 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 1
%63 = load i32, i32* %62
%64 = call i32 @close(i32 %63)
%65 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%66 = load i32, i32* %65
%67 = call i32 @close(i32 %66)
%68 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 0
%69 = load i32, i32* %68
%70 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 0
%71 = call i32 @read(i32 %69, i32* %70, i32 12)
%72 = getelementptr inbounds [2 x i32], [2 x i32]* %3, i64 0, i64 0
%73 = load i32, i32* %72
%74 = call i32 @close(i32 %73)
%75 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 0
%76 = load i32, i32* %75
%77 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 1
%78 = load i32, i32* %77
%79 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 2
%80 = load i32, i32* %79
%81 = call i32 @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.3, i64 0, i64 0), i32 %76, i32 %78, i32 %80)
%82 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 0
%83 = call i32 @calculate_result(i32* %82)
%84 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%85 = load i32, i32* %84
%86 = getelementptr inbounds [3 x i32], [3 x i32]* %7, i64 0, i64 0
%87 = call i32 @write(i32 %85, i32* %86, i32 12)
%88 = call i32 @wait(i32* null)
br label %89
89: ; preds = %61
br label %90
90: ; preds = %89, %26
br label %91
91: ; preds = %90, %12
store i32 0, i32* %1
br label %92
92: ; preds = %91, %19
%93 = load i32, i32* %1
ret i32 %93
}

LLVM IR (-O2):
@.str = [7 x i8] c"pipe()\00"
@EXIT_FAILURE = global i32 0
@.str.1 = [7 x i8] c"fork()\00"
@.str.2 = [23 x i8] c"Parent said: %d,%d,%d\0A\00"
@EXIT_SUCCESS = global i32 0
@.str.3 = [22 x i8] c"Child said: %d,%d,%d\0A\00"
define i32 @main() {
%1 = alloca [2 x i32]
%2 = alloca [2 x i32]
%3 = alloca [3 x i32]
%4 = alloca [3 x i32]
%5 = bitcast [2 x i32]* %1 to i8*
%6 = bitcast [2 x i32]* %2 to i8*
%7 = bitcast [3 x i32]* %3 to i8*
%8 = bitcast [3 x i32]* %4 to i8*
%9 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 0
%10 = call i32 @pipe(i32* %9)
%11 = icmp eq i32 %10, -1
br i1 %11, label %12, label %14
12: ; preds = %0
%13 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0))
br label %69
14: ; preds = %0
%15 = getelementptr inbounds [2 x i32], [2 x i32]* %1, i64 0, i64 0
%16 = call i32 @pipe(i32* %15)
%17 = icmp eq i32 %16, -1
br i1 %17, label %18, label %21
18: ; preds = %14
%19 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0))
%20 = load i32, i32* @EXIT_FAILURE
br label %69
21: ; preds = %14
%22 = call i32 (...) @fork()
switch i32 %22, label %47 [
i32 -1, label %23
i32 0, label %25
]
23: ; preds = %21
%24 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i64 0, i64 0))
br label %69
25: ; preds = %21
%26 = getelementptr inbounds [3 x i32], [3 x i32]* %3, i64 0, i64 0
store i32 2, i32* %26
%27 = getelementptr inbounds [3 x i32], [3 x i32]* %3, i64 0, i64 1
store i32 3, i32* %27
%28 = getelementptr inbounds [3 x i32], [3 x i32]* %3, i64 0, i64 2
store i32 -5, i32* %28
%29 = load i32, i32* %9
%30 = call i32 @close(i32 %29)
%31 = getelementptr inbounds [2 x i32], [2 x i32]* %1, i64 0, i64 1
%32 = load i32, i32* %31
%33 = call i32 @close(i32 %32)
%34 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%35 = load i32, i32* %34
%36 = call i32 @write(i32 %35, i32* %26, i32 12)
%37 = load i32, i32* %34
%38 = call i32 @close(i32 %37)
%39 = load i32, i32* %15
%40 = call i32 @read(i32 %39, i32* %26, i32 12)
%41 = load i32, i32* %26
%42 = load i32, i32* %27
%43 = load i32, i32* %28
%44 = call i32 @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.2, i64 0, i64 0), i32 %41, i32 %42, i32 %43)
%45 = load i32, i32* @EXIT_SUCCESS
%46 = call i32 @_Exit(i32 %45)
unreachable
47: ; preds = %21
%48 = getelementptr inbounds [2 x i32], [2 x i32]* %2, i64 0, i64 1
%49 = load i32, i32* %48
%50 = call i32 @close(i32 %49)
%51 = load i32, i32* %15
%52 = call i32 @close(i32 %51)
%53 = load i32, i32* %9
%54 = getelementptr inbounds [3 x i32], [3 x i32]* %4, i64 0, i64 0
%55 = call i32 @read(i32 %53, i32* %54, i32 12)
%56 = load i32, i32* %9
%57 = call i32 @close(i32 %56)
%58 = load i32, i32* %54
%59 = getelementptr inbounds [3 x i32], [3 x i32]* %4, i64 0, i64 1
%60 = load i32, i32* %59
%61 = getelementptr inbounds [3 x i32], [3 x i32]* %4, i64 0, i64 2
%62 = load i32, i32* %61
%63 = call i32 @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.3, i64 0, i64 0), i32 %58, i32 %60, i32 %62)
%64 = call i32 @calculate_result(i32* %54)
%65 = getelementptr inbounds [2 x i32], [2 x i32]* %1, i64 0, i64 1
%66 = load i32, i32* %65
%67 = call i32 @write(i32 %66, i32* %54, i32 12)
%68 = call i32 @wait(i32* null)
br label %69
69: ; preds = %12, %47, %23, %18
%70 = phi i32 [ %20, %18 ], [ 0, %23 ], [ 0, %47 ], [ 0, %12 ]
ret i32 %70
}