int machine_next_step(char *program, int *tape, int *match_arr,
                      int *cmd_pointer, int *tape_pointer, int *output,
                      int program_len, int tape_len) {
  switch (program[*cmd_pointer]) {
  case '+':
    tape[*tape_pointer]++;
    if (*cmd_pointer >= program_len - 1) {
      return 0;
    }
    (*cmd_pointer)++;
    return 2;
  case '-':
    tape[*tape_pointer]--;
    if (*cmd_pointer >= program_len - 1) {
      return 0;
    }
    (*cmd_pointer)++;
    return 2;
  case '>':
    if (*tape_pointer < tape_len - 1) {
      (*tape_pointer)++;
    } else {
      return 0;
    }
    if (*cmd_pointer >= program_len - 1) {
      return 0;
    }
    (*cmd_pointer)++;
    return 2;
  case '<':
    if (*tape_pointer > 0) {
      (*tape_pointer)--;
    } else {
      return 0;
    }
    if (*cmd_pointer >= program_len - 1) {
      return 0;
    }
    (*cmd_pointer)++;
    return 2;
  case '.':
    *output = tape[*tape_pointer];
    (*cmd_pointer)++;
    return 1;
  case '[':
    if (tape[*tape_pointer] == 0) {
      *cmd_pointer = match_arr[*cmd_pointer];
      return 2;
    }
    if (*cmd_pointer >= program_len - 1) {
      return 0;
    }
    (*cmd_pointer)++;
    return 2;
  case ']':
    if (tape[*tape_pointer] != 0) {
      *cmd_pointer = match_arr[*cmd_pointer];
      return 2;
    }
    if (*cmd_pointer >= program_len - 1) {
      return 0;
    }
    (*cmd_pointer)++;
    return 2;
  }
}


x86 assembly (clang, -O0):
<machine_next_step>:
push   %rbp
mov    %rsp,%rbp
mov    0x18(%rbp),%eax
mov    0x10(%rbp),%eax
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8,-0x30(%rbp)
mov    %r9,-0x38(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
movslq (%rcx),%rcx
movsbl (%rax,%rcx,1),%eax
add    $0xffffffd5,%eax
mov    %eax,%ecx
mov    %rcx,-0x40(%rbp)
sub    $0x32,%eax
ja     13b2 <machine_next_step+0x2b2>
mov    -0x40(%rbp),%rax
lea    0xeb2(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%rcx
movslq (%rcx),%rcx
mov    (%rax,%rcx,4),%edx
add    $0x1,%edx
mov    %edx,(%rax,%rcx,4)
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
mov    0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jl     118b <machine_next_step+0x8b>
movl   $0x0,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movl   $0x2,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%rcx
movslq (%rcx),%rcx
mov    (%rax,%rcx,4),%edx
add    $0xffffffff,%edx
mov    %edx,(%rax,%rcx,4)
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
mov    0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jl     11d6 <machine_next_step+0xd6>
movl   $0x0,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movl   $0x2,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x30(%rbp),%rax
mov    (%rax),%eax
mov    0x18(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1211 <machine_next_step+0x111>
mov    -0x30(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
jmp    121d <machine_next_step+0x11d>
movl   $0x0,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
mov    0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jl     123d <machine_next_step+0x13d>
movl   $0x0,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movl   $0x2,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x30(%rbp),%rax
cmpl   $0x0,(%rax)
jle    1271 <machine_next_step+0x171>
mov    -0x30(%rbp),%rax
mov    (%rax),%ecx
add    $0xffffffff,%ecx
mov    %ecx,(%rax)
jmp    127d <machine_next_step+0x17d>
movl   $0x0,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
mov    0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jl     129d <machine_next_step+0x19d>
movl   $0x0,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movl   $0x2,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%rcx
movslq (%rcx),%rcx
mov    (%rax,%rcx,4),%ecx
mov    -0x38(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movl   $0x1,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%rcx
movslq (%rcx),%rcx
cmpl   $0x0,(%rax,%rcx,4)
jne    1314 <machine_next_step+0x214>
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
movslq (%rcx),%rcx
mov    (%rax,%rcx,4),%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
movl   $0x2,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
mov    0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jl     1334 <machine_next_step+0x234>
movl   $0x0,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movl   $0x2,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x18(%rbp),%rax
mov    -0x30(%rbp),%rcx
movslq (%rcx),%rcx
cmpl   $0x0,(%rax,%rcx,4)
je     1380 <machine_next_step+0x280>
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
movslq (%rcx),%rcx
mov    (%rax,%rcx,4),%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
movl   $0x2,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
mov    0x10(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jl     13a0 <machine_next_step+0x2a0>
movl   $0x0,-0x4(%rbp)
jmp    13b2 <machine_next_step+0x2b2>
mov    -0x28(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
movl   $0x2,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<machine_next_step>:
movslq (%rcx),%r10
movsbl (%rdi,%r10,1),%edi
add    $0xffffffd5,%edi
cmp    $0x32,%edi
ja     1176 <machine_next_step+0x76>
mov    0x8(%rsp),%r11d
lea    0xee4(%rip),%rax
movslq (%rax,%rdi,4),%rdi
add    %rax,%rdi
jmp    *%rdi
movslq (%r8),%rax
addl   $0x1,(%rsi,%rax,4)
mov    (%rcx),%r10d
jmp    116b <machine_next_step+0x6b>
movslq (%r8),%rax
addl   $0xffffffff,(%rsi,%rax,4)
mov    (%rcx),%r10d
jmp    116b <machine_next_step+0x6b>
movslq (%r8),%rax
mov    (%rsi,%rax,4),%eax
mov    %eax,(%r9)
mov    (%rcx),%r10d
add    $0x1,%r10d
mov    $0x1,%eax
jmp    11b1 <machine_next_step+0xb1>
mov    (%r8),%edx
xor    %eax,%eax
test   %edx,%edx
jle    1176 <machine_next_step+0x76>
add    $0xffffffff,%edx
jmp    1199 <machine_next_step+0x99>
movslq (%r8),%rax
cmpl   $0x0,(%rsi,%rax,4)
je     1180 <machine_next_step+0x80>
add    $0xffffffff,%r11d
xor    %eax,%eax
cmp    %r11d,%r10d
jl     11a8 <machine_next_step+0xa8>
ret
movslq (%r8),%rax
cmpl   $0x0,(%rsi,%rax,4)
je     116b <machine_next_step+0x6b>
mov    (%rdx,%r10,4),%r10d
jmp    11ac <machine_next_step+0xac>
mov    0x10(%rsp),%esi
mov    (%r8),%edx
add    $0xffffffff,%esi
xor    %eax,%eax
cmp    %esi,%edx
jge    1176 <machine_next_step+0x76>
add    $0x1,%edx
mov    %edx,(%r8)
mov    (%rcx),%r10d
add    $0xffffffff,%r11d
cmp    %r11d,%r10d
jge    1176 <machine_next_step+0x76>
add    $0x1,%r10d
mov    $0x2,%eax
mov    %r10d,(%rcx)
ret

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

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