#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 */
char **dss_malloc(size_t);
size_t strcspn(char *, char const *);
int strspn(char *, char const *);
unsigned split_args(char *args, char ***const argv_ptr, const char *delim) {
  char *p = args;
  char **argv;
  size_t n = 0, i, j;
  p = args + strspn(args, delim);
  for (;;) {
    i = strcspn(p, delim);
    if (!i)
      break;
    p += i;
    n++;
    p += strspn(p, delim);
  }
  *argv_ptr = dss_malloc((n + 1) * sizeof(char *));
  argv = *argv_ptr;
  i = 0;
  p = args + strspn(args, delim);
  while (p) {
    argv[i] = p;
    j = strcspn(p, delim);
    if (!j)
      break;
    p += strcspn(p, delim);
    if (*p) {
      *p = '\0';
      p++;
      p += strspn(p, delim);
    }
    i++;
  }
  argv[n] = NULL;
  return n;
}


x86 assembly (clang, -O0):
<split_args>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
movq   $0x0,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x48(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <strspn@plt>
mov    %eax,%ecx
mov    -0x48(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1050 <strcspn@plt>
mov    %rax,-0x38(%rbp)
cmpq   $0x0,-0x38(%rbp)
jne    119a <split_args+0x6a>
jmp    11d4 <split_args+0xa4>
mov    -0x38(%rbp),%rax
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <strspn@plt>
mov    %eax,%ecx
mov    -0x20(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
jmp    1179 <split_args+0x49>
mov    -0x30(%rbp),%rdi
add    $0x1,%rdi
shl    $0x3,%rdi
call   1030 <dss_malloc@plt>
mov    %rax,%rcx
mov    -0x10(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
movq   $0x0,-0x38(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <strspn@plt>
mov    %eax,%ecx
mov    -0x50(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
je     12c6 <split_args+0x196>
mov    -0x20(%rbp),%rdx
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x20(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1050 <strcspn@plt>
mov    %rax,-0x40(%rbp)
cmpq   $0x0,-0x40(%rbp)
jne    1263 <split_args+0x133>
jmp    12c6 <split_args+0x196>
mov    -0x20(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1050 <strcspn@plt>
add    -0x20(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmpb   $0x0,(%rax)
je     12b5 <split_args+0x185>
mov    -0x20(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <strspn@plt>
mov    %eax,%ecx
mov    -0x20(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    1227 <split_args+0xf7>
mov    -0x28(%rbp),%rax
mov    -0x30(%rbp),%rcx
movq   $0x0,(%rax,%rcx,8)
mov    -0x30(%rbp),%rax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<split_args>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rdx,%r14
mov    %rsi,%r12
mov    %rdi,%r15
mov    %rdx,%rsi
call   1040 <strspn@plt>
movslq %eax,%rbx
add    %r15,%rbx
mov    %rbx,%rdi
mov    %r14,%rsi
call   1050 <strcspn@plt>
test   %rax,%rax
je     119d <split_args+0x6d>
mov    %rax,%rbp
xor    %r13d,%r13d
nopl   0x0(%rax,%rax,1)
add    %rbx,%rbp
add    $0x1,%r13
mov    %rbp,%rdi
mov    %r14,%rsi
call   1040 <strspn@plt>
movslq %eax,%rbx
add    %rbp,%rbx
mov    %rbx,%rdi
mov    %r14,%rsi
call   1050 <strcspn@plt>
mov    %rax,%rbp
test   %rax,%rax
jne    1170 <split_args+0x40>
jmp    11a0 <split_args+0x70>
xor    %r13d,%r13d
lea    0x8(,%r13,8),%rdi
call   1030 <dss_malloc@plt>
mov    %rax,(%rsp)
mov    %rax,(%r12)
test   %r15,%r15
je     1230 <split_args+0x100>
mov    %r15,%rdi
mov    %r14,%rsi
call   1040 <strspn@plt>
movslq %eax,%r12
add    %r15,%r12
mov    (%rsp),%rax
mov    %r12,(%rax)
mov    %r12,%rdi
mov    %r14,%rsi
call   1050 <strcspn@plt>
test   %rax,%rax
je     1230 <split_args+0x100>
mov    (%rsp),%rbp
add    $0x8,%rbp
jmp    120b <split_args+0xdb>
nopl   0x0(%rax)
mov    %rbx,0x0(%rbp)
mov    %rbx,%rdi
mov    %r14,%rsi
call   1050 <strcspn@plt>
add    $0x8,%rbp
mov    %rbx,%r12
test   %rax,%rax
je     1230 <split_args+0x100>
lea    (%r12,%rax,1),%rbx
cmpb   $0x0,(%r12,%rax,1)
je     11f0 <split_args+0xc0>
movb   $0x0,(%rbx)
lea    0x1(%rbx),%rdi
mov    %r14,%rsi
call   1040 <strspn@plt>
cltq
add    %rax,%rbx
add    $0x1,%rbx
jmp    11f0 <split_args+0xc0>
mov    (%rsp),%rax
movq   $0x0,(%rax,%r13,8)
mov    %r13d,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @split_args(i8* %0, i8*** %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8***
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i8**
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
store i8* %0, i8** %4
store i8*** %1, i8**** %5
store i8* %2, i8** %6
%12 = load i8*, i8** %4
store i8* %12, i8** %7
store i64 0, i64* %9
%13 = load i8*, i8** %4
%14 = load i8*, i8** %4
%15 = load i8*, i8** %6
%16 = call i32 @strspn(i8* %14, i8* %15)
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds i8, i8* %13, i64 %17
store i8* %18, i8** %7
br label %19
19: ; preds = %26, %3
%20 = load i8*, i8** %7
%21 = load i8*, i8** %6
%22 = call i64 @strcspn(i8* %20, i8* %21)
store i64 %22, i64* %10
%23 = load i64, i64* %10
%24 = icmp ne i64 %23, 0
br i1 %24, label %26, label %25
25: ; preds = %19
br label %38
26: ; preds = %19
%27 = load i64, i64* %10
%28 = load i8*, i8** %7
%29 = getelementptr inbounds i8, i8* %28, i64 %27
store i8* %29, i8** %7
%30 = load i64, i64* %9
%31 = add i64 %30, 1
store i64 %31, i64* %9
%32 = load i8*, i8** %7
%33 = load i8*, i8** %6
%34 = call i32 @strspn(i8* %32, i8* %33)
%35 = load i8*, i8** %7
%36 = sext i32 %34 to i64
%37 = getelementptr inbounds i8, i8* %35, i64 %36
store i8* %37, i8** %7
br label %19
38: ; preds = %25
%39 = load i64, i64* %9
%40 = add i64 %39, 1
%41 = mul i64 %40, 8
%42 = call i8** @dss_malloc(i64 %41)
%43 = load i8***, i8**** %5
store i8** %42, i8*** %43
%44 = load i8***, i8**** %5
%45 = load i8**, i8*** %44
store i8** %45, i8*** %8
store i64 0, i64* %10
%46 = load i8*, i8** %4
%47 = load i8*, i8** %4
%48 = load i8*, i8** %6
%49 = call i32 @strspn(i8* %47, i8* %48)
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds i8, i8* %46, i64 %50
store i8* %51, i8** %7
br label %52
52: ; preds = %85, %38
%53 = load i8*, i8** %7
%54 = icmp ne i8* %53, null
br i1 %54, label %55, label %88
55: ; preds = %52
%56 = load i8*, i8** %7
%57 = load i8**, i8*** %8
%58 = load i64, i64* %10
%59 = getelementptr inbounds i8*, i8** %57, i64 %58
store i8* %56, i8** %59
%60 = load i8*, i8** %7
%61 = load i8*, i8** %6
%62 = call i64 @strcspn(i8* %60, i8* %61)
store i64 %62, i64* %11
%63 = load i64, i64* %11
%64 = icmp ne i64 %63, 0
br i1 %64, label %66, label %65
65: ; preds = %55
br label %88
66: ; preds = %55
%67 = load i8*, i8** %7
%68 = load i8*, i8** %6
%69 = call i64 @strcspn(i8* %67, i8* %68)
%70 = load i8*, i8** %7
%71 = getelementptr inbounds i8, i8* %70, i64 %69
store i8* %71, i8** %7
%72 = load i8*, i8** %7
%73 = load i8, i8* %72
%74 = icmp ne i8 %73, 0
br i1 %74, label %75, label %85
75: ; preds = %66
%76 = load i8*, i8** %7
store i8 0, i8* %76
%77 = load i8*, i8** %7
%78 = getelementptr inbounds i8, i8* %77, i32 1
store i8* %78, i8** %7
%79 = load i8*, i8** %7
%80 = load i8*, i8** %6
%81 = call i32 @strspn(i8* %79, i8* %80)
%82 = load i8*, i8** %7
%83 = sext i32 %81 to i64
%84 = getelementptr inbounds i8, i8* %82, i64 %83
store i8* %84, i8** %7
br label %85
85: ; preds = %75, %66
%86 = load i64, i64* %10
%87 = add i64 %86, 1
store i64 %87, i64* %10
br label %52
88: ; preds = %65, %52
%89 = load i8**, i8*** %8
%90 = load i64, i64* %9
%91 = getelementptr inbounds i8*, i8** %89, i64 %90
store i8* null, i8** %91
%92 = load i64, i64* %9
%93 = trunc i64 %92 to i32
ret i32 %93
}

LLVM IR (-O2):
define i32 @split_args(i8* %0, i8*** nocapture writeonly %1, i8* nocapture %2) {
%4 = tail call i32 @strspn(i8* %0, i8* %2)
%5 = sext i32 %4 to i64
%6 = getelementptr inbounds i8, i8* %0, i64 %5
%7 = tail call i64 @strcspn(i8* %6, i8* %2)
%8 = icmp eq i64 %7, 0
br i1 %8, label %20, label %9
9: ; preds = %3, %9
%10 = phi i64 [ %18, %9 ], [ %7, %3 ]
%11 = phi i8* [ %17, %9 ], [ %6, %3 ]
%12 = phi i64 [ %14, %9 ], [ 0, %3 ]
%13 = getelementptr inbounds i8, i8* %11, i64 %10
%14 = add i64 %12, 1
%15 = tail call i32 @strspn(i8* %13, i8* %2)
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds i8, i8* %13, i64 %16
%18 = tail call i64 @strcspn(i8* %17, i8* %2)
%19 = icmp eq i64 %18, 0
br i1 %19, label %20, label %9
20: ; preds = %9, %3
%21 = phi i64 [ 0, %3 ], [ %14, %9 ]
%22 = shl i64 %21, 3
%23 = add i64 %22, 8
%24 = tail call i8** @dss_malloc(i64 %23)
store i8** %24, i8*** %1
%25 = icmp eq i8* %0, null
br i1 %25, label %50, label %26
26: ; preds = %20
%27 = tail call i32 @strspn(i8* %0, i8* %2)
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds i8, i8* %0, i64 %28
store i8* %29, i8** %24
%30 = tail call i64 @strcspn(i8* %29, i8* %2)
%31 = icmp eq i64 %30, 0
br i1 %31, label %50, label %32
32: ; preds = %26, %44
%33 = phi i64 [ %48, %44 ], [ %30, %26 ]
%34 = phi i64 [ %46, %44 ], [ 0, %26 ]
%35 = phi i8* [ %45, %44 ], [ %29, %26 ]
%36 = getelementptr inbounds i8, i8* %35, i64 %33
%37 = load i8, i8* %36
%38 = icmp eq i8 %37, 0
br i1 %38, label %44, label %39
39: ; preds = %32
store i8 0, i8* %36
%40 = getelementptr inbounds i8, i8* %36, i64 1
%41 = tail call i32 @strspn(i8* %40, i8* %2)
%42 = sext i32 %41 to i64
%43 = getelementptr inbounds i8, i8* %40, i64 %42
br label %44
44: ; preds = %39, %32
%45 = phi i8* [ %43, %39 ], [ %36, %32 ]
%46 = add i64 %34, 1
%47 = getelementptr inbounds i8*, i8** %24, i64 %46
store i8* %45, i8** %47
%48 = tail call i64 @strcspn(i8* %45, i8* %2)
%49 = icmp eq i64 %48, 0
br i1 %49, label %50, label %32
50: ; preds = %44, %26, %20
%51 = getelementptr inbounds i8*, i8** %24, i64 %21
store i8* null, i8** %51
%52 = trunc i64 %21 to i32
ret i32 %52
}