#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*/ free(char *);
char *malloc(int);
char *realloc(char *, int);
int /*<<< orphan*/ strcpy(char *, char *);
char *string_strndup(char const *, int);
int strlen(char const *);
scalar_t__ strncmp(char const *, char const *, int);
char *strstr(char const *, char const *);
char *stub1(void *, char const *);
char *string_replace_with_callback(const char *string, const char *prefix,
                                   const char *suffix,
                                   char *(*callback)(void *data,
                                                     const char *text),
                                   void *callback_data, int *errors) {
  int length_prefix, length_suffix, length, length_value, index_string;
  int index_result;
  char *result, *result2, *key, *value;
  const char *pos_end_name;
  *errors = 0;
  if (!string || !prefix || !prefix[0] || !suffix || !suffix[0])
    return NULL;
  length_prefix = strlen(prefix);
  length_suffix = strlen(suffix);
  length = strlen(string) + 1;
  result = malloc(length);
  if (result) {
    index_string = 0;
    index_result = 0;
    while (string[index_string]) {
      if ((string[index_string] == '\\') &&
          (string[index_string + 1] == prefix[0])) {
        index_string++;
        result[index_result++] = string[index_string++];
      } else if (strncmp(string + index_string, prefix, length_prefix) == 0) {
        pos_end_name = strstr(string + index_string + length_prefix, suffix);
        if (pos_end_name) {
          key = string_strndup(string + index_string + length_prefix,
                               pos_end_name -
                                   (string + index_string + length_prefix));
          if (key) {
            value = (*callback)(callback_data, key);
            if (value) {
              length_value = strlen(value);
              length += length_value;
              result2 = realloc(result, length);
              if (!result2) {
                if (result)
                  free(result);
                free(key);
                free(value);
                return NULL;
              }
              result = result2;
              strcpy(result + index_result, value);
              index_result += length_value;
              index_string +=
                  pos_end_name - string - index_string + length_suffix;
              free(value);
            } else {
              result[index_result++] = string[index_string++];
              (*errors)++;
            }
            free(key);
          } else
            result[index_result++] = string[index_string++];
        } else
          result[index_result++] = string[index_string++];
      } else
        result[index_result++] = string[index_string++];
    }
    result[index_result] = '\0';
  }
  return result;
}


x86 assembly (clang, -O0):
<string_replace_with_callback>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
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    -0x38(%rbp),%rax
movl   $0x0,(%rax)
cmpq   $0x0,-0x10(%rbp)
je     11e8 <string_replace_with_callback+0x68>
cmpq   $0x0,-0x18(%rbp)
je     11e8 <string_replace_with_callback+0x68>
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     11e8 <string_replace_with_callback+0x68>
cmpq   $0x0,-0x20(%rbp)
je     11e8 <string_replace_with_callback+0x68>
mov    -0x20(%rbp),%rax
cmpb   $0x0,(%rax)
jne    11f5 <string_replace_with_callback+0x75>
movq   $0x0,-0x8(%rbp)
jmp    150b <string_replace_with_callback+0x38b>
mov    -0x18(%rbp),%rdi
call   1060 <strlen@plt>
mov    %eax,-0x3c(%rbp)
mov    -0x20(%rbp),%rdi
call   1060 <strlen@plt>
mov    %eax,-0x40(%rbp)
mov    -0x10(%rbp),%rdi
call   1060 <strlen@plt>
add    $0x1,%eax
mov    %eax,-0x44(%rbp)
mov    -0x44(%rbp),%edi
call   1070 <malloc@plt>
mov    %rax,-0x58(%rbp)
cmpq   $0x0,-0x58(%rbp)
je     1503 <string_replace_with_callback+0x383>
movl   $0x0,-0x4c(%rbp)
movl   $0x0,-0x50(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x4c(%rbp),%rcx
cmpb   $0x0,(%rax,%rcx,1)
je     14f7 <string_replace_with_callback+0x377>
mov    -0x10(%rbp),%rax
movslq -0x4c(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x5c,%eax
jne    12c0 <string_replace_with_callback+0x140>
mov    -0x10(%rbp),%rax
mov    -0x4c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
mov    -0x18(%rbp),%rcx
movsbl (%rcx),%ecx
cmp    %ecx,%eax
jne    12c0 <string_replace_with_callback+0x140>
mov    -0x4c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x4c(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x4c(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x4c(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x58(%rbp),%rax
mov    -0x50(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x50(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    14f2 <string_replace_with_callback+0x372>
mov    -0x10(%rbp),%rdi
movslq -0x4c(%rbp),%rax
add    %rax,%rdi
mov    -0x18(%rbp),%rsi
mov    -0x3c(%rbp),%edx
call   1040 <strncmp@plt>
cmp    $0x0,%rax
jne    14c3 <string_replace_with_callback+0x343>
mov    -0x10(%rbp),%rdi
movslq -0x4c(%rbp),%rax
add    %rax,%rdi
movslq -0x3c(%rbp),%rax
add    %rax,%rdi
mov    -0x20(%rbp),%rsi
call   10a0 <strstr@plt>
mov    %rax,-0x78(%rbp)
cmpq   $0x0,-0x78(%rbp)
je     1494 <string_replace_with_callback+0x314>
mov    -0x10(%rbp),%rdi
movslq -0x4c(%rbp),%rax
add    %rax,%rdi
movslq -0x3c(%rbp),%rax
add    %rax,%rdi
mov    -0x78(%rbp),%rax
mov    -0x10(%rbp),%rcx
movslq -0x4c(%rbp),%rdx
add    %rdx,%rcx
movslq -0x3c(%rbp),%rdx
add    %rdx,%rcx
sub    %rcx,%rax
mov    %eax,%esi
call   1090 <string_strndup@plt>
mov    %rax,-0x68(%rbp)
cmpq   $0x0,-0x68(%rbp)
je     1465 <string_replace_with_callback+0x2e5>
mov    -0x28(%rbp),%rax
mov    -0x30(%rbp),%rdi
mov    -0x68(%rbp),%rsi
call   *%rax
mov    %rax,-0x70(%rbp)
cmpq   $0x0,-0x70(%rbp)
je     1422 <string_replace_with_callback+0x2a2>
mov    -0x70(%rbp),%rdi
call   1060 <strlen@plt>
mov    %eax,-0x48(%rbp)
mov    -0x48(%rbp),%eax
add    -0x44(%rbp),%eax
mov    %eax,-0x44(%rbp)
mov    -0x58(%rbp),%rdi
mov    -0x44(%rbp),%esi
call   1080 <realloc@plt>
mov    %rax,-0x60(%rbp)
cmpq   $0x0,-0x60(%rbp)
jne    13cc <string_replace_with_callback+0x24c>
cmpq   $0x0,-0x58(%rbp)
je     13ad <string_replace_with_callback+0x22d>
mov    -0x58(%rbp),%rdi
call   1030 <free@plt>
mov    -0x68(%rbp),%rdi
call   1030 <free@plt>
mov    -0x70(%rbp),%rdi
call   1030 <free@plt>
movq   $0x0,-0x8(%rbp)
jmp    150b <string_replace_with_callback+0x38b>
mov    -0x60(%rbp),%rax
mov    %rax,-0x58(%rbp)
mov    -0x58(%rbp),%rdi
movslq -0x50(%rbp),%rax
add    %rax,%rdi
mov    -0x70(%rbp),%rsi
call   1050 <strcpy@plt>
mov    -0x48(%rbp),%eax
add    -0x50(%rbp),%eax
mov    %eax,-0x50(%rbp)
mov    -0x78(%rbp),%rcx
mov    -0x10(%rbp),%rax
sub    %rax,%rcx
movslq -0x4c(%rbp),%rax
sub    %rax,%rcx
movslq -0x40(%rbp),%rax
add    %rax,%rcx
movslq -0x4c(%rbp),%rax
add    %rcx,%rax
mov    %eax,-0x4c(%rbp)
mov    -0x70(%rbp),%rdi
call   1030 <free@plt>
jmp    1457 <string_replace_with_callback+0x2d7>
mov    -0x10(%rbp),%rax
mov    -0x4c(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x4c(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x58(%rbp),%rax
mov    -0x50(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x50(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x38(%rbp),%rax
mov    (%rax),%ecx
add    $0x1,%ecx
mov    %ecx,(%rax)
mov    -0x68(%rbp),%rdi
call   1030 <free@plt>
jmp    148f <string_replace_with_callback+0x30f>
mov    -0x10(%rbp),%rax
mov    -0x4c(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x4c(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x58(%rbp),%rax
mov    -0x50(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x50(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    14be <string_replace_with_callback+0x33e>
mov    -0x10(%rbp),%rax
mov    -0x4c(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x4c(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x58(%rbp),%rax
mov    -0x50(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x50(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    14ed <string_replace_with_callback+0x36d>
mov    -0x10(%rbp),%rax
mov    -0x4c(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x4c(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x58(%rbp),%rax
mov    -0x50(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x50(%rbp)
movslq %ecx,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    14f2 <string_replace_with_callback+0x372>
jmp    1241 <string_replace_with_callback+0xc1>
mov    -0x58(%rbp),%rax
movslq -0x50(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x58(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<string_replace_with_callback>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x58,%rsp
movl   $0x0,(%r9)
xor    %eax,%eax
mov    %rax,(%rsp)
test   %rdi,%rdi
je     13ef <string_replace_with_callback+0x26f>
mov    %rsi,0x10(%rsp)
test   %rsi,%rsi
je     13ef <string_replace_with_callback+0x26f>
mov    %rdx,%r13
xor    %eax,%eax
mov    %rax,(%rsp)
test   %rdx,%rdx
je     13ef <string_replace_with_callback+0x26f>
mov    0x10(%rsp),%rax
cmpb   $0x0,(%rax)
je     13ef <string_replace_with_callback+0x26f>
cmpb   $0x0,0x0(%r13)
je     13e9 <string_replace_with_callback+0x269>
mov    %r9,%rbx
mov    %r8,%r14
mov    %rcx,%rbp
mov    %rdi,%r15
mov    0x10(%rsp),%rdi
call   1060 <strlen@plt>
mov    %eax,0xc(%rsp)
mov    %r13,%rdi
call   1060 <strlen@plt>
mov    %eax,0x24(%rsp)
mov    %r15,%rdi
call   1060 <strlen@plt>
add    $0x1,%eax
mov    %eax,0x1c(%rsp)
mov    %eax,%edi
call   1070 <malloc@plt>
xor    %r12d,%r12d
test   %rax,%rax
je     13e9 <string_replace_with_callback+0x269>
mov    %rax,%rcx
mov    %r13,0x50(%rsp)
mov    %rbp,0x38(%rsp)
mov    %r14,0x40(%rsp)
mov    %rbx,0x30(%rsp)
mov    0xc(%rsp),%edx
movslq %edx,%rax
mov    %rax,0x48(%rsp)
xor    %r14d,%r14d
mov    %rcx,%rbp
movslq %r12d,%r12
mov    0x10(%rsp),%rbx
mov    %rbp,%rax
mov    %rbp,(%rsp)
jmp    1276 <string_replace_with_callback+0xf6>
nop
add    $0x1,%r14d
movzbl 0x0(%r13),%eax
mov    %al,0x0(%rbp,%r12,1)
add    $0x1,%r12
mov    0xc(%rsp),%edx
movslq %r14d,%r13
movzbl (%r15,%r13,1),%eax
cmp    $0x5c,%al
je     1290 <string_replace_with_callback+0x110>
test   %al,%al
jne    12b0 <string_replace_with_callback+0x130>
jmp    13bf <string_replace_with_callback+0x23f>
nopl   0x0(%rax,%rax,1)
movzbl 0x1(%r13,%r15,1),%eax
cmp    (%rbx),%al
jne    12b0 <string_replace_with_callback+0x130>
add    $0x2,%r14d
mov    %al,0x0(%rbp,%r12,1)
add    $0x1,%r12
jmp    1276 <string_replace_with_callback+0xf6>
nopl   0x0(%rax)
add    %r15,%r13
mov    %r13,%rdi
mov    %rbx,%rsi
call   1040 <strncmp@plt>
test   %rax,%rax
jne    1260 <string_replace_with_callback+0xe0>
mov    0x48(%rsp),%rax
lea    (%rax,%r13,1),%rbx
mov    %rbx,%rdi
mov    0x50(%rsp),%rsi
call   10a0 <strstr@plt>
test   %rax,%rax
je     12f2 <string_replace_with_callback+0x172>
mov    %rax,%rbp
mov    %ebp,%esi
sub    %ebx,%esi
mov    %rbx,%rdi
call   1090 <string_strndup@plt>
test   %rax,%rax
jne    1316 <string_replace_with_callback+0x196>
add    $0x1,%r14d
movzbl 0x0(%r13),%eax
mov    (%rsp),%rbp
mov    %al,0x0(%rbp,%r12,1)
add    $0x1,%r12
mov    0x10(%rsp),%rbx
mov    0xc(%rsp),%edx
jmp    1276 <string_replace_with_callback+0xf6>
mov    %rax,%rbx
mov    0x40(%rsp),%rdi
mov    %rax,%rsi
call   *0x38(%rsp)
test   %rax,%rax
je     138d <string_replace_with_callback+0x20d>
mov    %rax,%rdi
mov    %rax,0x28(%rsp)
call   1060 <strlen@plt>
mov    0x1c(%rsp),%esi
mov    %eax,0x20(%rsp)
add    %eax,%esi
mov    (%rsp),%r13
mov    %r13,%rdi
mov    %esi,0x1c(%rsp)
call   1080 <realloc@plt>
test   %rax,%rax
je     13c7 <string_replace_with_callback+0x247>
mov    %rax,%rdi
add    %r12,%rdi
mov    0x28(%rsp),%r13
mov    %r13,%rsi
mov    %rax,(%rsp)
call   1050 <strcpy@plt>
sub    %r14d,%ebp
sub    %r15d,%ebp
add    0x24(%rsp),%r14d
add    %ebp,%r14d
mov    %r13,%rdi
call   1030 <free@plt>
mov    (%rsp),%rbp
mov    0x20(%rsp),%eax
jmp    13ab <string_replace_with_callback+0x22b>
add    $0x1,%r14d
mov    0x0(%r13),%al
mov    (%rsp),%rbp
mov    %al,0x0(%rbp,%r12,1)
mov    0x30(%rsp),%rax
addl   $0x1,(%rax)
mov    $0x1,%eax
add    %eax,%r12d
mov    %rbx,%rdi
call   1030 <free@plt>
mov    0xc(%rsp),%edx
jmp    124e <string_replace_with_callback+0xce>
movb   $0x0,0x0(%rbp,%r12,1)
jmp    13ef <string_replace_with_callback+0x26f>
mov    0x28(%rsp),%rbp
test   %r13,%r13
je     13d9 <string_replace_with_callback+0x259>
mov    %r13,%rdi
call   1030 <free@plt>
mov    %rbx,%rdi
call   1030 <free@plt>
mov    %rbp,%rdi
call   1030 <free@plt>
xor    %eax,%eax
mov    %rax,(%rsp)
mov    (%rsp),%rax
add    $0x58,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i8* @string_replace_with_callback(i8* %0, i8* %1, i8* %2, i8* (i8*, i8*)* %3, i8* %4, i32* %5) {
%7 = alloca i8*
%8 = alloca i8*
%9 = alloca i8*
%10 = alloca i8*
%11 = alloca i8* (i8*, i8*)*
%12 = alloca i8*
%13 = alloca i32*
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
%18 = alloca i32
%19 = alloca i32
%20 = alloca i8*
%21 = alloca i8*
%22 = alloca i8*
%23 = alloca i8*
%24 = alloca i8*
store i8* %0, i8** %8
store i8* %1, i8** %9
store i8* %2, i8** %10
store i8* (i8*, i8*)* %3, i8* (i8*, i8*)** %11
store i8* %4, i8** %12
store i32* %5, i32** %13
%25 = load i32*, i32** %13
store i32 0, i32* %25
%26 = load i8*, i8** %8
%27 = icmp ne i8* %26, null
br i1 %27, label %28, label %44
28: ; preds = %6
%29 = load i8*, i8** %9
%30 = icmp ne i8* %29, null
br i1 %30, label %31, label %44
31: ; preds = %28
%32 = load i8*, i8** %9
%33 = getelementptr inbounds i8, i8* %32, i64 0
%34 = load i8, i8* %33
%35 = icmp ne i8 %34, 0
br i1 %35, label %36, label %44
36: ; preds = %31
%37 = load i8*, i8** %10
%38 = icmp ne i8* %37, null
br i1 %38, label %39, label %44
39: ; preds = %36
%40 = load i8*, i8** %10
%41 = getelementptr inbounds i8, i8* %40, i64 0
%42 = load i8, i8* %41
%43 = icmp ne i8 %42, 0
br i1 %43, label %45, label %44
44: ; preds = %39, %36, %31, %28, %6
store i8* null, i8** %7
br label %266
45: ; preds = %39
%46 = load i8*, i8** %9
%47 = call i32 @strlen(i8* %46)
store i32 %47, i32* %14
%48 = load i8*, i8** %10
%49 = call i32 @strlen(i8* %48)
store i32 %49, i32* %15
%50 = load i8*, i8** %8
%51 = call i32 @strlen(i8* %50)
%52 = add nsw i32 %51, 1
store i32 %52, i32* %16
%53 = load i32, i32* %16
%54 = call i8* @malloc(i32 %53)
store i8* %54, i8** %20
%55 = load i8*, i8** %20
%56 = icmp ne i8* %55, null
br i1 %56, label %57, label %264
57: ; preds = %45
store i32 0, i32* %18
store i32 0, i32* %19
br label %58
58: ; preds = %258, %57
%59 = load i8*, i8** %8
%60 = load i32, i32* %18
%61 = sext i32 %60 to i64
%62 = getelementptr inbounds i8, i8* %59, i64 %61
%63 = load i8, i8* %62
%64 = icmp ne i8 %63, 0
br i1 %64, label %65, label %259
65: ; preds = %58
%66 = load i8*, i8** %8
%67 = load i32, i32* %18
%68 = sext i32 %67 to i64
%69 = getelementptr inbounds i8, i8* %66, i64 %68
%70 = load i8, i8* %69
%71 = sext i8 %70 to i32
%72 = icmp eq i32 %71, 92
br i1 %72, label %73, label %100
73: ; preds = %65
%74 = load i8*, i8** %8
%75 = load i32, i32* %18
%76 = add nsw i32 %75, 1
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds i8, i8* %74, i64 %77
%79 = load i8, i8* %78
%80 = sext i8 %79 to i32
%81 = load i8*, i8** %9
%82 = getelementptr inbounds i8, i8* %81, i64 0
%83 = load i8, i8* %82
%84 = sext i8 %83 to i32
%85 = icmp eq i32 %80, %84
br i1 %85, label %86, label %100
86: ; preds = %73
%87 = load i32, i32* %18
%88 = add nsw i32 %87, 1
store i32 %88, i32* %18
%89 = load i8*, i8** %8
%90 = load i32, i32* %18
%91 = add nsw i32 %90, 1
store i32 %91, i32* %18
%92 = sext i32 %90 to i64
%93 = getelementptr inbounds i8, i8* %89, i64 %92
%94 = load i8, i8* %93
%95 = load i8*, i8** %20
%96 = load i32, i32* %19
%97 = add nsw i32 %96, 1
store i32 %97, i32* %19
%98 = sext i32 %96 to i64
%99 = getelementptr inbounds i8, i8* %95, i64 %98
store i8 %94, i8* %99
br label %258
100: ; preds = %73, %65
%101 = load i8*, i8** %8
%102 = load i32, i32* %18
%103 = sext i32 %102 to i64
%104 = getelementptr inbounds i8, i8* %101, i64 %103
%105 = load i8*, i8** %9
%106 = load i32, i32* %14
%107 = call i64 @strncmp(i8* %104, i8* %105, i32 %106)
%108 = icmp eq i64 %107, 0
br i1 %108, label %109, label %245
109: ; preds = %100
%110 = load i8*, i8** %8
%111 = load i32, i32* %18
%112 = sext i32 %111 to i64
%113 = getelementptr inbounds i8, i8* %110, i64 %112
%114 = load i32, i32* %14
%115 = sext i32 %114 to i64
%116 = getelementptr inbounds i8, i8* %113, i64 %115
%117 = load i8*, i8** %10
%118 = call i8* @strstr(i8* %116, i8* %117)
store i8* %118, i8** %24
%119 = load i8*, i8** %24
%120 = icmp ne i8* %119, null
br i1 %120, label %121, label %232
121: ; preds = %109
%122 = load i8*, i8** %8
%123 = load i32, i32* %18
%124 = sext i32 %123 to i64
%125 = getelementptr inbounds i8, i8* %122, i64 %124
%126 = load i32, i32* %14
%127 = sext i32 %126 to i64
%128 = getelementptr inbounds i8, i8* %125, i64 %127
%129 = load i8*, i8** %24
%130 = load i8*, i8** %8
%131 = load i32, i32* %18
%132 = sext i32 %131 to i64
%133 = getelementptr inbounds i8, i8* %130, i64 %132
%134 = load i32, i32* %14
%135 = sext i32 %134 to i64
%136 = getelementptr inbounds i8, i8* %133, i64 %135
%137 = ptrtoint i8* %129 to i64
%138 = ptrtoint i8* %136 to i64
%139 = sub i64 %137, %138
%140 = trunc i64 %139 to i32
%141 = call i8* @string_strndup(i8* %128, i32 %140)
store i8* %141, i8** %22
%142 = load i8*, i8** %22
%143 = icmp ne i8* %142, null
br i1 %143, label %144, label %219
144: ; preds = %121
%145 = load i8* (i8*, i8*)*, i8* (i8*, i8*)** %11
%146 = load i8*, i8** %12
%147 = load i8*, i8** %22
%148 = call i8* %145(i8* %146, i8* %147)
store i8* %148, i8** %23
%149 = load i8*, i8** %23
%150 = icmp ne i8* %149, null
br i1 %150, label %151, label %201
151: ; preds = %144
%152 = load i8*, i8** %23
%153 = call i32 @strlen(i8* %152)
store i32 %153, i32* %17
%154 = load i32, i32* %17
%155 = load i32, i32* %16
%156 = add nsw i32 %155, %154
store i32 %156, i32* %16
%157 = load i8*, i8** %20
%158 = load i32, i32* %16
%159 = call i8* @realloc(i8* %157, i32 %158)
store i8* %159, i8** %21
%160 = load i8*, i8** %21
%161 = icmp ne i8* %160, null
br i1 %161, label %173, label %162
162: ; preds = %151
%163 = load i8*, i8** %20
%164 = icmp ne i8* %163, null
br i1 %164, label %165, label %168
165: ; preds = %162
%166 = load i8*, i8** %20
%167 = call i32 @free(i8* %166)
br label %168
168: ; preds = %165, %162
%169 = load i8*, i8** %22
%170 = call i32 @free(i8* %169)
%171 = load i8*, i8** %23
%172 = call i32 @free(i8* %171)
store i8* null, i8** %7
br label %266
173: ; preds = %151
%174 = load i8*, i8** %21
store i8* %174, i8** %20
%175 = load i8*, i8** %20
%176 = load i32, i32* %19
%177 = sext i32 %176 to i64
%178 = getelementptr inbounds i8, i8* %175, i64 %177
%179 = load i8*, i8** %23
%180 = call i32 @strcpy(i8* %178, i8* %179)
%181 = load i32, i32* %17
%182 = load i32, i32* %19
%183 = add nsw i32 %182, %181
store i32 %183, i32* %19
%184 = load i8*, i8** %24
%185 = load i8*, i8** %8
%186 = ptrtoint i8* %184 to i64
%187 = ptrtoint i8* %185 to i64
%188 = sub i64 %186, %187
%189 = load i32, i32* %18
%190 = sext i32 %189 to i64
%191 = sub nsw i64 %188, %190
%192 = load i32, i32* %15
%193 = sext i32 %192 to i64
%194 = add nsw i64 %191, %193
%195 = load i32, i32* %18
%196 = sext i32 %195 to i64
%197 = add nsw i64 %196, %194
%198 = trunc i64 %197 to i32
store i32 %198, i32* %18
%199 = load i8*, i8** %23
%200 = call i32 @free(i8* %199)
br label %216
201: ; preds = %144
%202 = load i8*, i8** %8
%203 = load i32, i32* %18
%204 = add nsw i32 %203, 1
store i32 %204, i32* %18
%205 = sext i32 %203 to i64
%206 = getelementptr inbounds i8, i8* %202, i64 %205
%207 = load i8, i8* %206
%208 = load i8*, i8** %20
%209 = load i32, i32* %19
%210 = add nsw i32 %209, 1
store i32 %210, i32* %19
%211 = sext i32 %209 to i64
%212 = getelementptr inbounds i8, i8* %208, i64 %211
store i8 %207, i8* %212
%213 = load i32*, i32** %13
%214 = load i32, i32* %213
%215 = add nsw i32 %214, 1
store i32 %215, i32* %213
br label %216
216: ; preds = %201, %173
%217 = load i8*, i8** %22
%218 = call i32 @free(i8* %217)
br label %231
219: ; preds = %121
%220 = load i8*, i8** %8
%221 = load i32, i32* %18
%222 = add nsw i32 %221, 1
store i32 %222, i32* %18
%223 = sext i32 %221 to i64
%224 = getelementptr inbounds i8, i8* %220, i64 %223
%225 = load i8, i8* %224
%226 = load i8*, i8** %20
%227 = load i32, i32* %19
%228 = add nsw i32 %227, 1
store i32 %228, i32* %19
%229 = sext i32 %227 to i64
%230 = getelementptr inbounds i8, i8* %226, i64 %229
store i8 %225, i8* %230
br label %231
231: ; preds = %219, %216
br label %244
232: ; preds = %109
%233 = load i8*, i8** %8
%234 = load i32, i32* %18
%235 = add nsw i32 %234, 1
store i32 %235, i32* %18
%236 = sext i32 %234 to i64
%237 = getelementptr inbounds i8, i8* %233, i64 %236
%238 = load i8, i8* %237
%239 = load i8*, i8** %20
%240 = load i32, i32* %19
%241 = add nsw i32 %240, 1
store i32 %241, i32* %19
%242 = sext i32 %240 to i64
%243 = getelementptr inbounds i8, i8* %239, i64 %242
store i8 %238, i8* %243
br label %244
244: ; preds = %232, %231
br label %257
245: ; preds = %100
%246 = load i8*, i8** %8
%247 = load i32, i32* %18
%248 = add nsw i32 %247, 1
store i32 %248, i32* %18
%249 = sext i32 %247 to i64
%250 = getelementptr inbounds i8, i8* %246, i64 %249
%251 = load i8, i8* %250
%252 = load i8*, i8** %20
%253 = load i32, i32* %19
%254 = add nsw i32 %253, 1
store i32 %254, i32* %19
%255 = sext i32 %253 to i64
%256 = getelementptr inbounds i8, i8* %252, i64 %255
store i8 %251, i8* %256
br label %257
257: ; preds = %245, %244
br label %258
258: ; preds = %257, %86
br label %58
259: ; preds = %58
%260 = load i8*, i8** %20
%261 = load i32, i32* %19
%262 = sext i32 %261 to i64
%263 = getelementptr inbounds i8, i8* %260, i64 %262
store i8 0, i8* %263
br label %264
264: ; preds = %259, %45
%265 = load i8*, i8** %20
store i8* %265, i8** %7
br label %266
266: ; preds = %264, %168, %44
%267 = load i8*, i8** %7
ret i8* %267
}

LLVM IR (-O2):
define i8* @string_replace_with_callback(i8* %0, i8* %1, i8* %2, i8* (i8*, i8*)* nocapture %3, i8* %4, i32* nocapture %5) {
store i32 0, i32* %5
%7 = icmp ne i8* %0, null
%8 = icmp ne i8* %1, null
%9 = and i1 %7, %8
br i1 %9, label %10, label %125
10: ; preds = %6
%11 = load i8, i8* %1
%12 = icmp ne i8 %11, 0
%13 = icmp ne i8* %2, null
%14 = and i1 %13, %12
br i1 %14, label %15, label %125
15: ; preds = %10
%16 = load i8, i8* %2
%17 = icmp eq i8 %16, 0
br i1 %17, label %125, label %18
18: ; preds = %15
%19 = tail call i32 @strlen(i8* %1)
%20 = tail call i32 @strlen(i8* %2)
%21 = tail call i32 @strlen(i8* %0)
%22 = add nsw i32 %21, 1
%23 = tail call i8* @malloc(i32 %22)
%24 = icmp eq i8* %23, null
br i1 %24, label %125, label %25
25: ; preds = %18
%26 = sext i32 %19 to i64
%27 = ptrtoint i8* %0 to i64
br label %28
28: ; preds = %97, %25
%29 = phi i8* [ %98, %97 ], [ %23, %25 ]
%30 = phi i32 [ %102, %97 ], [ 0, %25 ]
%31 = phi i32 [ %100, %97 ], [ 0, %25 ]
%32 = phi i32 [ %101, %97 ], [ %22, %25 ]
br label %33
33: ; preds = %119, %28
%34 = phi i32 [ %30, %28 ], [ %121, %119 ]
%35 = phi i32 [ %31, %28 ], [ %120, %119 ]
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds i8, i8* %0, i64 %36
%38 = load i8, i8* %37
switch i8 %38, label %50 [
i8 0, label %122
i8 92, label %39
]
39: ; preds = %33
%40 = add nsw i32 %35, 1
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %0, i64 %41
%43 = load i8, i8* %42
%44 = load i8, i8* %1
%45 = icmp eq i8 %43, %44
br i1 %45, label %46, label %50
46: ; preds = %39
%47 = add nsw i32 %35, 2
%48 = sext i32 %34 to i64
%49 = getelementptr inbounds i8, i8* %29, i64 %48
store i8 %43, i8* %49
br label %119
50: ; preds = %33, %39
%51 = tail call i64 @strncmp(i8* %37, i8* %1, i32 %19)
%52 = icmp eq i64 %51, 0
br i1 %52, label %53, label %114
53: ; preds = %50
%54 = getelementptr inbounds i8, i8* %37, i64 %26
%55 = tail call i8* @strstr(i8* %54, i8* %2)
%56 = icmp eq i8* %55, null
br i1 %56, label %109, label %57
57: ; preds = %53
%58 = ptrtoint i8* %55 to i64
%59 = ptrtoint i8* %54 to i64
%60 = sub i64 %58, %59
%61 = trunc i64 %60 to i32
%62 = tail call i8* @string_strndup(i8* %54, i32 %61)
%63 = icmp eq i8* %62, null
br i1 %63, label %104, label %64
64: ; preds = %57
%65 = ptrtoint i8* %55 to i64
%66 = tail call i8* %3(i8* %4, i8* %62)
%67 = icmp eq i8* %66, null
br i1 %67, label %90, label %68
68: ; preds = %64
%69 = tail call i32 @strlen(i8* %66)
%70 = add nsw i32 %69, %32
%71 = tail call i8* @realloc(i8* %29, i32 %70)
%72 = icmp eq i8* %71, null
br i1 %72, label %73, label %80
73: ; preds = %68
%74 = icmp eq i8* %29, null
br i1 %74, label %77, label %75
75: ; preds = %73
%76 = tail call i32 @free(i8* %29)
br label %77
77: ; preds = %75, %73
%78 = tail call i32 @free(i8* %62)
%79 = tail call i32 @free(i8* %66)
br label %125
80: ; preds = %68
%81 = sext i32 %34 to i64
%82 = getelementptr inbounds i8, i8* %71, i64 %81
%83 = tail call i32 @strcpy(i8* %82, i8* %66)
%84 = add i64 %36, %27
%85 = sub i64 %65, %84
%86 = trunc i64 %85 to i32
%87 = add i32 %35, %20
%88 = add i32 %87, %86
%89 = tail call i32 @free(i8* %66)
br label %97
90: ; preds = %64
%91 = add nsw i32 %35, 1
%92 = load i8, i8* %37
%93 = sext i32 %34 to i64
%94 = getelementptr inbounds i8, i8* %29, i64 %93
store i8 %92, i8* %94
%95 = load i32, i32* %5
%96 = add nsw i32 %95, 1
store i32 %96, i32* %5
br label %97
97: ; preds = %90, %80
%98 = phi i8* [ %71, %80 ], [ %29, %90 ]
%99 = phi i32 [ %69, %80 ], [ 1, %90 ]
%100 = phi i32 [ %88, %80 ], [ %91, %90 ]
%101 = phi i32 [ %70, %80 ], [ %32, %90 ]
%102 = add nsw i32 %99, %34
%103 = tail call i32 @free(i8* %62)
br label %28
104: ; preds = %57
%105 = add nsw i32 %35, 1
%106 = load i8, i8* %37
%107 = sext i32 %34 to i64
%108 = getelementptr inbounds i8, i8* %29, i64 %107
store i8 %106, i8* %108
br label %119
109: ; preds = %53
%110 = add nsw i32 %35, 1
%111 = load i8, i8* %37
%112 = sext i32 %34 to i64
%113 = getelementptr inbounds i8, i8* %29, i64 %112
store i8 %111, i8* %113
br label %119
114: ; preds = %50
%115 = add nsw i32 %35, 1
%116 = load i8, i8* %37
%117 = sext i32 %34 to i64
%118 = getelementptr inbounds i8, i8* %29, i64 %117
store i8 %116, i8* %118
br label %119
119: ; preds = %114, %104, %109, %46
%120 = phi i32 [ %47, %46 ], [ %105, %104 ], [ %110, %109 ], [ %115, %114 ]
%121 = add nsw i32 %34, 1
br label %33
122: ; preds = %33
%123 = sext i32 %34 to i64
%124 = getelementptr inbounds i8, i8* %29, i64 %123
store i8 0, i8* %124
br label %125
125: ; preds = %18, %122, %6, %10, %15, %77
%126 = phi i8* [ null, %77 ], [ null, %15 ], [ null, %10 ], [ null, %6 ], [ %29, %122 ], [ null, %18 ]
ret i8* %126
}