#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 /*<<< orphan*/ O_RDONLY;
int /*<<< orphan*/ close(int);
int /*<<< orphan*/ free(char *);
scalar_t__ malloc(int);
int /*<<< orphan*/ memcpy(char *, char *, int);
int open(char const *, int /*<<< orphan*/);
int read(int, char *, int);
scalar_t__ realloc(char *, int);
const char **read_nul_sep(const char *filename) {
  char *buf = NULL;
  char *newbuf = NULL;
  int buflen = 0;
  int count = 0;
  int size = 0;
  int i = 0;
  char **results;
  int fd = open(filename, O_RDONLY);
  buf = (char *)malloc(4096);
  size = 4096;
  if (buf == NULL) {
    close(fd);
    return NULL;
  }
  while (1) {
    int r = 0;
    if (size - buflen == 0) {
      buf = (char *)realloc(buf, size * 2);
      size = size * 2;
      if (buf == NULL) {
        close(fd);
        return NULL;
      }
    }
    r = read(fd, &buf[buflen], size - buflen);
    if (r < 0) {
      close(fd);
      free(buf);
      return NULL;
    }
    if (r == 0) {
      close(fd);
      break;
    }
    buflen += r;
  }
  for (i = 0; i < buflen; i += 1) {
    if (buf[i] == '\0') {
      count += 1;
    }
  }
  if (buf[i - 1] != '\0') {
    count += 1;
  }
  results = (char **)malloc(sizeof(char *) * (count + 1) + (buflen + 1));
  for (i = count; i < count + 1; i += 1) {
    results[i] = NULL;
  }
  newbuf = ((char *)results) + sizeof(char *) * (count + 1);
  memcpy(newbuf, buf, buflen);
  newbuf[buflen] = '\0';
  free(buf);
  count = 0;
  for (i = 0; i < buflen;) {
    results[count++] = &newbuf[i];
    for (; i < buflen && newbuf[i] != '\0'; i += 1)
      ;
    i += 1;
  }
  return (const char **)results;
}


x86 assembly (clang, -O0):
<read_nul_sep>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
movq   $0x0,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
movl   $0x0,-0x28(%rbp)
movl   $0x0,-0x2c(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x10(%rbp),%rdi
mov    0x2e35(%rip),%rax
mov    (%rax),%esi
call   1090 <open@plt>
mov    %eax,-0x3c(%rbp)
mov    $0x1000,%edi
call   1070 <malloc@plt>
mov    %rax,-0x18(%rbp)
movl   $0x1000,-0x2c(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    11f2 <read_nul_sep+0x82>
mov    -0x3c(%rbp),%edi
call   1040 <close@plt>
movq   $0x0,-0x8(%rbp)
jmp    144d <read_nul_sep+0x2dd>
jmp    11f7 <read_nul_sep+0x87>
movl   $0x0,-0x40(%rbp)
mov    -0x2c(%rbp),%eax
sub    -0x24(%rbp),%eax
cmp    $0x0,%eax
jne    124e <read_nul_sep+0xde>
mov    -0x18(%rbp),%rdi
mov    -0x2c(%rbp),%esi
shl    $0x1,%esi
call   1080 <realloc@plt>
mov    %rax,-0x18(%rbp)
mov    -0x2c(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x2c(%rbp)
cmpq   $0x0,-0x18(%rbp)
jne    1249 <read_nul_sep+0xd9>
mov    -0x3c(%rbp),%edi
call   1040 <close@plt>
movq   $0x0,-0x8(%rbp)
jmp    144d <read_nul_sep+0x2dd>
jmp    124e <read_nul_sep+0xde>
mov    -0x3c(%rbp),%edi
mov    -0x18(%rbp),%rsi
movslq -0x24(%rbp),%rax
add    %rax,%rsi
mov    -0x2c(%rbp),%edx
sub    -0x24(%rbp),%edx
call   1050 <read@plt>
mov    %eax,-0x40(%rbp)
cmpl   $0x0,-0x40(%rbp)
jge    1292 <read_nul_sep+0x122>
mov    -0x3c(%rbp),%edi
call   1040 <close@plt>
mov    -0x18(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x8(%rbp)
jmp    144d <read_nul_sep+0x2dd>
cmpl   $0x0,-0x40(%rbp)
jne    12a9 <read_nul_sep+0x139>
mov    -0x3c(%rbp),%edi
call   1040 <close@plt>
jmp    12b7 <read_nul_sep+0x147>
mov    -0x40(%rbp),%eax
add    -0x24(%rbp),%eax
mov    %eax,-0x24(%rbp)
jmp    11f7 <read_nul_sep+0x87>
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    12fb <read_nul_sep+0x18b>
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
jne    12e8 <read_nul_sep+0x178>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    12ed <read_nul_sep+0x17d>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    12be <read_nul_sep+0x14e>
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
je     131e <read_nul_sep+0x1ae>
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
cltq
shl    $0x3,%rax
mov    -0x24(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
add    %rcx,%rax
mov    %eax,%edi
call   1070 <malloc@plt>
mov    %rax,-0x38(%rbp)
mov    -0x28(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    -0x28(%rbp),%ecx
add    $0x1,%ecx
cmp    %ecx,%eax
jge    1376 <read_nul_sep+0x206>
mov    -0x38(%rbp),%rax
movslq -0x30(%rbp),%rcx
movq   $0x0,(%rax,%rcx,8)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    1347 <read_nul_sep+0x1d7>
mov    -0x38(%rbp),%rax
mov    -0x28(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x24(%rbp),%edx
call   1060 <memcpy@plt>
mov    -0x20(%rbp),%rax
movslq -0x24(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x18(%rbp),%rdi
call   1030 <free@plt>
movl   $0x0,-0x28(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    1445 <read_nul_sep+0x2d5>
mov    -0x20(%rbp),%rdx
movslq -0x30(%rbp),%rax
add    %rax,%rdx
mov    -0x38(%rbp),%rax
mov    -0x28(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x28(%rbp)
movslq %ecx,%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x30(%rbp),%ecx
xor    %eax,%eax
cmp    -0x24(%rbp),%ecx
mov    %al,-0x41(%rbp)
jge    1414 <read_nul_sep+0x2a4>
mov    -0x20(%rbp),%rax
movslq -0x30(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
setne  %al
mov    %al,-0x41(%rbp)
mov    -0x41(%rbp),%al
test   $0x1,%al
jne    1424 <read_nul_sep+0x2b4>
jmp    1437 <read_nul_sep+0x2c7>
jmp    1429 <read_nul_sep+0x2b9>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    13ee <read_nul_sep+0x27e>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    13c1 <read_nul_sep+0x251>
mov    -0x38(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<read_nul_sep>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    0x2e63(%rip),%rax
mov    (%rax),%esi
call   1090 <open@plt>
mov    %eax,%r15d
mov    $0x1000,%ebp
mov    $0x1000,%edi
call   1070 <malloc@plt>
test   %rax,%rax
je     1208 <read_nul_sep+0x98>
mov    %rax,%r14
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
mov    %ecx,%ebx
cmp    %ecx,%ebp
jne    11cb <read_nul_sep+0x5b>
lea    (%rbx,%rbx,1),%ebp
mov    %r14,%rdi
mov    %ebp,%esi
call   1080 <realloc@plt>
mov    %rax,%r14
test   %rax,%rax
je     1208 <read_nul_sep+0x98>
movslq %ebx,%r12
lea    (%r14,%r12,1),%rsi
mov    %ebp,%edx
sub    %ebx,%edx
mov    %r15d,%edi
call   1050 <read@plt>
test   %eax,%eax
js     1218 <read_nul_sep+0xa8>
lea    (%rax,%rbx,1),%ecx
test   %eax,%eax
jne    11b0 <read_nul_sep+0x40>
mov    %r15d,%edi
call   1040 <close@plt>
test   %ebx,%ebx
jle    1230 <read_nul_sep+0xc0>
lea    -0x1(%rbx),%eax
mov    %ebx,%ecx
cmp    $0x8,%ebx
jae    123e <read_nul_sep+0xce>
xor    %edx,%edx
xor    %ebp,%ebp
jmp    1360 <read_nul_sep+0x1f0>
mov    %r15d,%edi
call   1040 <close@plt>
xor    %r15d,%r15d
jmp    1443 <read_nul_sep+0x2d3>
mov    %r15d,%edi
call   1040 <close@plt>
mov    %r14,%rdi
call   1030 <free@plt>
xor    %r15d,%r15d
jmp    1443 <read_nul_sep+0x2d3>
mov    $0xffffffffffffffff,%rax
xor    %ebp,%ebp
jmp    1373 <read_nul_sep+0x203>
mov    %ecx,%edx
and    $0xfffffff8,%edx
lea    -0x8(%rdx),%rsi
mov    %rsi,%rbp
shr    $0x3,%rbp
add    $0x1,%rbp
test   %rsi,%rsi
je     1455 <read_nul_sep+0x2e5>
mov    %rbp,%rsi
and    $0xfffffffffffffffe,%rsi
pxor   %xmm2,%xmm2
xor    %edi,%edi
movdqa 0xd90(%rip),%xmm3
pxor   %xmm0,%xmm0
pxor   %xmm1,%xmm1
nopl   0x0(%rax,%rax,1)
movd   (%r14,%rdi,1),%xmm5
movd   0x4(%r14,%rdi,1),%xmm4
pcmpeqb %xmm2,%xmm5
punpcklbw %xmm5,%xmm5
punpcklwd %xmm5,%xmm5
pand   %xmm3,%xmm5
paddd  %xmm0,%xmm5
pcmpeqb %xmm2,%xmm4
punpcklbw %xmm4,%xmm4
punpcklwd %xmm4,%xmm4
pand   %xmm3,%xmm4
paddd  %xmm1,%xmm4
movd   0x8(%r14,%rdi,1),%xmm0
movd   0xc(%r14,%rdi,1),%xmm1
pcmpeqb %xmm2,%xmm0
punpcklbw %xmm0,%xmm0
punpcklwd %xmm0,%xmm0
pand   %xmm3,%xmm0
paddd  %xmm5,%xmm0
pcmpeqb %xmm2,%xmm1
punpcklbw %xmm1,%xmm1
punpcklwd %xmm1,%xmm1
pand   %xmm3,%xmm1
paddd  %xmm4,%xmm1
add    $0x10,%rdi
add    $0xfffffffffffffffe,%rsi
jne    1280 <read_nul_sep+0x110>
test   $0x1,%bpl
je     133c <read_nul_sep+0x1cc>
movd   (%r14,%rdi,1),%xmm2
movd   0x4(%r14,%rdi,1),%xmm3
pxor   %xmm4,%xmm4
pcmpeqb %xmm4,%xmm2
punpcklbw %xmm2,%xmm2
punpcklwd %xmm2,%xmm2
movdqa 0xce0(%rip),%xmm5
pand   %xmm5,%xmm2
paddd  %xmm2,%xmm0
pcmpeqb %xmm4,%xmm3
punpcklbw %xmm3,%xmm3
punpcklwd %xmm3,%xmm3
pand   %xmm5,%xmm3
paddd  %xmm3,%xmm1
paddd  %xmm1,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddd  %xmm0,%xmm1
pshufd $0x55,%xmm1,%xmm0
paddd  %xmm1,%xmm0
movd   %xmm0,%ebp
cmp    %rcx,%rdx
je     1371 <read_nul_sep+0x201>
nopl   0x0(%rax,%rax,1)
cmpb   $0x1,(%r14,%rdx,1)
adc    $0x0,%ebp
add    $0x1,%rdx
cmp    %rdx,%rcx
jne    1360 <read_nul_sep+0x1f0>
cltq
mov    (%r14,%rax,1),%al
xor    %r13d,%r13d
mov    %al,0x7(%rsp)
test   %al,%al
setne  %r13b
lea    0x0(%rbp,%r13,1),%eax
mov    %rax,0x10(%rsp)
lea    0x8(,%rax,8),%rax
lea    (%rbx,%rax,1),%edi
add    $0x1,%edi
call   1070 <malloc@plt>
mov    %rax,%r15
mov    %ebp,%eax
mov    %rax,0x8(%rsp)
add    %rax,%r13
movq   $0x0,(%r15,%r13,8)
mov    0x10(%rsp),%rax
lea    (%r15,%rax,8),%rbp
add    $0x8,%rbp
mov    %rbp,%rdi
mov    %r14,%rsi
mov    %ebx,%edx
call   1060 <memcpy@plt>
movb   $0x0,(%r12,%rbp,1)
mov    %r14,%rdi
call   1030 <free@plt>
test   %ebx,%ebx
jle    1443 <read_nul_sep+0x2d3>
cmpb   $0x1,0x7(%rsp)
mov    0x8(%rsp),%rax
sbb    $0xffffffffffffffff,%rax
lea    (%r15,%rax,8),%r8
add    $0x8,%r8
xor    %ecx,%ecx
xor    %edx,%edx
jmp    140d <read_nul_sep+0x29d>
nopl   (%rax)
add    %edi,%edx
add    $0x1,%rcx
add    $0x1,%edx
cmp    %ebx,%edx
jge    1443 <read_nul_sep+0x2d3>
movslq %edx,%rdi
lea    (%rdi,%rbp,1),%rax
mov    %rax,(%r15,%rcx,8)
cmp    %ebx,%edi
jge    1402 <read_nul_sep+0x292>
lea    (%r8,%rdi,1),%rsi
mov    %r12,%rax
sub    %rdi,%rax
xor    %edi,%edi
nopl   0x0(%rax,%rax,1)
cmpb   $0x0,(%rsi,%rdi,1)
je     1400 <read_nul_sep+0x290>
add    $0x1,%rdi
cmp    %rdi,%rax
jne    1430 <read_nul_sep+0x2c0>
mov    %ebx,%edx
jmp    1402 <read_nul_sep+0x292>
mov    %r15,%rax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
pxor   %xmm0,%xmm0
xor    %edi,%edi
pxor   %xmm1,%xmm1
test   $0x1,%bpl
jne    12fb <read_nul_sep+0x18b>
jmp    133c <read_nul_sep+0x1cc>

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

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