#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 */
scalar_t__ strchr(char const *, char);
char *cpo_strtok(char *str, const char *delims) {
  static char *pos = (char *)0;
  char *start = (char *)0;
  if (str)
    pos = str;
  if (pos) {
    while (*pos && strchr(delims, *pos))
      pos++;
    if (*pos) {
      start = pos;
      while (*pos && !strchr(delims, *pos))
        pos++;
      if (*pos)
        *pos++ = '\0';
    }
  }
  return start;
}


x86 assembly (clang, -O0):
<cpo_strtok>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movq   $0x0,-0x18(%rbp)
cmpq   $0x0,-0x8(%rbp)
je     113e <cpo_strtok+0x2e>
mov    -0x8(%rbp),%rax
mov    %rax,0x2ef2(%rip)
cmpq   $0x0,0x2eea(%rip)
je     1258 <cpo_strtok+0x148>
jmp    1151 <cpo_strtok+0x41>
mov    0x2ed8(%rip),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x19(%rbp)
je     1186 <cpo_strtok+0x76>
mov    -0x10(%rbp),%rdi
mov    0x2ebc(%rip),%rax
movsbl (%rax),%esi
call   1030 <strchr@plt>
cmp    $0x0,%rax
setne  %al
mov    %al,-0x19(%rbp)
mov    -0x19(%rbp),%al
test   $0x1,%al
jne    1196 <cpo_strtok+0x86>
jmp    11ad <cpo_strtok+0x9d>
mov    0x2e93(%rip),%rax
add    $0x1,%rax
mov    %rax,0x2e88(%rip)
jmp    1151 <cpo_strtok+0x41>
mov    0x2e7c(%rip),%rax
cmpb   $0x0,(%rax)
je     1253 <cpo_strtok+0x143>
mov    0x2e6c(%rip),%rax
mov    %rax,-0x18(%rbp)
mov    0x2e61(%rip),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x1a(%rbp)
je     11ff <cpo_strtok+0xef>
mov    -0x10(%rbp),%rdi
mov    0x2e45(%rip),%rax
movsbl (%rax),%esi
call   1030 <strchr@plt>
cmp    $0x0,%rax
setne  %al
xor    $0xff,%al
mov    %al,-0x1a(%rbp)
mov    -0x1a(%rbp),%al
test   $0x1,%al
jne    120f <cpo_strtok+0xff>
jmp    1226 <cpo_strtok+0x116>
mov    0x2e1a(%rip),%rax
add    $0x1,%rax
mov    %rax,0x2e0f(%rip)
jmp    11c8 <cpo_strtok+0xb8>
mov    0x2e03(%rip),%rax
cmpb   $0x0,(%rax)
je     124e <cpo_strtok+0x13e>
mov    0x2df3(%rip),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,0x2de5(%rip)
movb   $0x0,(%rax)
jmp    1253 <cpo_strtok+0x143>
jmp    1258 <cpo_strtok+0x148>
mov    -0x18(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<cpo_strtok>:
push   %r14
push   %rbx
push   %rax
mov    %rsi,%r14
test   %rdi,%rdi
je     1125 <cpo_strtok+0x15>
mov    %rdi,0x2f0d(%rip)
jmp    1131 <cpo_strtok+0x21>
mov    0x2f04(%rip),%rdi
test   %rdi,%rdi
je     11ac <cpo_strtok+0x9c>
mov    (%rdi),%al
test   %al,%al
je     11ac <cpo_strtok+0x9c>
nopw   0x0(%rax,%rax,1)
movsbl %al,%esi
mov    %r14,%rdi
call   1030 <strchr@plt>
mov    0x2ede(%rip),%rbx
test   %rax,%rax
je     116c <cpo_strtok+0x5c>
lea    0x1(%rbx),%rax
mov    %rax,0x2ece(%rip)
movzbl 0x1(%rbx),%eax
test   %al,%al
jne    1140 <cpo_strtok+0x30>
jmp    11ac <cpo_strtok+0x9c>
mov    (%rbx),%al
test   %al,%al
je     11ac <cpo_strtok+0x9c>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsbl %al,%esi
mov    %r14,%rdi
call   1030 <strchr@plt>
mov    0x2e9e(%rip),%rcx
test   %rax,%rax
jne    11b9 <cpo_strtok+0xa9>
lea    0x1(%rcx),%rax
mov    %rax,0x2e8e(%rip)
movzbl 0x1(%rcx),%eax
test   %al,%al
jne    1180 <cpo_strtok+0x70>
jmp    11ae <cpo_strtok+0x9e>
xor    %ebx,%ebx
mov    %rbx,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret
cmpb   $0x0,(%rcx)
je     11ae <cpo_strtok+0x9e>
lea    0x1(%rcx),%rax
mov    %rax,0x2e67(%rip)
movb   $0x0,(%rcx)
jmp    11ae <cpo_strtok+0x9e>

LLVM IR (-O0):
@cpo_strtok.pos = internal global i8* null
define i8* @cpo_strtok(i8* %0, i8* %1) {
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i8*
store i8* %0, i8** %3
store i8* %1, i8** %4
store i8* null, i8** %5
%6 = load i8*, i8** %3
%7 = icmp ne i8* %6, null
br i1 %7, label %8, label %10
8: ; preds = %2
%9 = load i8*, i8** %3
store i8* %9, i8** @cpo_strtok.pos
br label %10
10: ; preds = %8, %2
%11 = load i8*, i8** @cpo_strtok.pos
%12 = icmp ne i8* %11, null
br i1 %12, label %13, label %62
13: ; preds = %10
br label %14
14: ; preds = %27, %13
%15 = load i8*, i8** @cpo_strtok.pos
%16 = load i8, i8* %15
%17 = sext i8 %16 to i32
%18 = icmp ne i32 %17, 0
br i1 %18, label %19, label %25
19: ; preds = %14
%20 = load i8*, i8** %4
%21 = load i8*, i8** @cpo_strtok.pos
%22 = load i8, i8* %21
%23 = call i64 @strchr(i8* %20, i8 signext %22)
%24 = icmp ne i64 %23, 0
br label %25
25: ; preds = %19, %14
%26 = phi i1 [ false, %14 ], [ %24, %19 ]
br i1 %26, label %27, label %30
27: ; preds = %25
%28 = load i8*, i8** @cpo_strtok.pos
%29 = getelementptr inbounds i8, i8* %28, i32 1
store i8* %29, i8** @cpo_strtok.pos
br label %14
30: ; preds = %25
%31 = load i8*, i8** @cpo_strtok.pos
%32 = load i8, i8* %31
%33 = icmp ne i8 %32, 0
br i1 %33, label %34, label %61
34: ; preds = %30
%35 = load i8*, i8** @cpo_strtok.pos
store i8* %35, i8** %5
br label %36
36: ; preds = %50, %34
%37 = load i8*, i8** @cpo_strtok.pos
%38 = load i8, i8* %37
%39 = sext i8 %38 to i32
%40 = icmp ne i32 %39, 0
br i1 %40, label %41, label %48
41: ; preds = %36
%42 = load i8*, i8** %4
%43 = load i8*, i8** @cpo_strtok.pos
%44 = load i8, i8* %43
%45 = call i64 @strchr(i8* %42, i8 signext %44)
%46 = icmp ne i64 %45, 0
%47 = xor i1 %46, true
br label %48
48: ; preds = %41, %36
%49 = phi i1 [ false, %36 ], [ %47, %41 ]
br i1 %49, label %50, label %53
50: ; preds = %48
%51 = load i8*, i8** @cpo_strtok.pos
%52 = getelementptr inbounds i8, i8* %51, i32 1
store i8* %52, i8** @cpo_strtok.pos
br label %36
53: ; preds = %48
%54 = load i8*, i8** @cpo_strtok.pos
%55 = load i8, i8* %54
%56 = icmp ne i8 %55, 0
br i1 %56, label %57, label %60
57: ; preds = %53
%58 = load i8*, i8** @cpo_strtok.pos
%59 = getelementptr inbounds i8, i8* %58, i32 1
store i8* %59, i8** @cpo_strtok.pos
store i8 0, i8* %58
br label %60
60: ; preds = %57, %53
br label %61
61: ; preds = %60, %30
br label %62
62: ; preds = %61, %10
%63 = load i8*, i8** %5
ret i8* %63
}

LLVM IR (-O2):
@cpo_strtok.pos = internal unnamed_addr global i8* null
define i8* @cpo_strtok(i8* %0, i8* %1) {
%3 = icmp eq i8* %0, null
br i1 %3, label %5, label %4
4: ; preds = %2
store i8* %0, i8** @cpo_strtok.pos
br label %8
5: ; preds = %2
%6 = load i8*, i8** @cpo_strtok.pos
%7 = icmp eq i8* %6, null
br i1 %7, label %38, label %8
8: ; preds = %4, %5
%9 = phi i8* [ %0, %4 ], [ %6, %5 ]
%10 = load i8, i8* %9
%11 = icmp eq i8 %10, 0
br i1 %11, label %38, label %12
12: ; preds = %8, %17
%13 = phi i8 [ %19, %17 ], [ %10, %8 ]
%14 = tail call i64 @strchr(i8* %1, i8 signext %13)
%15 = icmp eq i64 %14, 0
%16 = load i8*, i8** @cpo_strtok.pos
br i1 %15, label %21, label %17
17: ; preds = %12
%18 = getelementptr inbounds i8, i8* %16, i64 1
store i8* %18, i8** @cpo_strtok.pos
%19 = load i8, i8* %18
%20 = icmp eq i8 %19, 0
br i1 %20, label %38, label %12
21: ; preds = %12
%22 = load i8, i8* %16
%23 = icmp eq i8 %22, 0
br i1 %23, label %38, label %24
24: ; preds = %21, %29
%25 = phi i8 [ %31, %29 ], [ %22, %21 ]
%26 = tail call i64 @strchr(i8* %1, i8 signext %25)
%27 = icmp eq i64 %26, 0
%28 = load i8*, i8** @cpo_strtok.pos
br i1 %27, label %29, label %33
29: ; preds = %24
%30 = getelementptr inbounds i8, i8* %28, i64 1
store i8* %30, i8** @cpo_strtok.pos
%31 = load i8, i8* %30
%32 = icmp eq i8 %31, 0
br i1 %32, label %38, label %24
33: ; preds = %24
%34 = load i8, i8* %28
%35 = icmp eq i8 %34, 0
br i1 %35, label %38, label %36
36: ; preds = %33
%37 = getelementptr inbounds i8, i8* %28, i64 1
store i8* %37, i8** @cpo_strtok.pos
store i8 0, i8* %28
br label %38
38: ; preds = %17, %29, %8, %21, %36, %33, %5
%39 = phi i8* [ %16, %36 ], [ %16, %33 ], [ null, %21 ], [ null, %5 ], [ null, %8 ], [ %16, %29 ], [ null, %17 ]
ret i8* %39
}