char *Q_StrReplace(char *haystack, char *needle, char *newp) {
  static char final[1024] = {""};
  char dest[1024] = {""};
  char newStr[1024] = {""};
  char *destp;
  int needle_len = 0;
  int new_len = 0;
  if (!*haystack) {
    return final;
  }
  if (!*needle) {
    Q_strncpyz(final, haystack, sizeof(final));
    return final;
  }
  if (*newp) {
    Q_strncpyz(newStr, newp, sizeof(newStr));
  }
  dest[0] = '\0';
  needle_len = strlen(needle);
  new_len = strlen(newStr);
  destp = &dest[0];
  while (*haystack) {
    if (!Q_stricmpn(haystack, needle, needle_len)) {
      Q_strcat(dest, sizeof(dest), newStr);
      haystack += needle_len;
      destp += new_len;
      continue;
    }
    if (1024 > (strlen(dest) + 1)) {
      *destp = *haystack;
      *++destp = '\0';
    }
    haystack++;
  }
  Q_strncpyz(final, dest, sizeof(final));
  return final;
}


x86 assembly (clang, -O0):
<Q_StrReplace>:
push   %rbp
mov    %rsp,%rbp
sub    $0x830,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
lea    -0x420(%rbp),%rdi
xor    %esi,%esi
mov    $0x400,%edx
call   1050 <memset@plt>
lea    -0x820(%rbp),%rdi
xor    %esi,%esi
mov    $0x400,%edx
call   1050 <memset@plt>
movl   $0x0,-0x82c(%rbp)
movl   $0x0,-0x830(%rbp)
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
jne    11be <Q_StrReplace+0x6e>
lea    0x2eab(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    1343 <Q_StrReplace+0x1f3>
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
jne    11f2 <Q_StrReplace+0xa2>
mov    -0x10(%rbp),%rsi
lea    0x2e8a(%rip),%rdi
mov    $0x400,%edx
mov    $0x0,%al
call   1070 <Q_strncpyz@plt>
lea    0x2e77(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    1343 <Q_StrReplace+0x1f3>
mov    -0x20(%rbp),%rax
cmpb   $0x0,(%rax)
je     1216 <Q_StrReplace+0xc6>
lea    -0x820(%rbp),%rdi
mov    -0x20(%rbp),%rsi
mov    $0x400,%edx
mov    $0x0,%al
call   1070 <Q_strncpyz@plt>
movb   $0x0,-0x420(%rbp)
mov    -0x18(%rbp),%rdi
call   1040 <strlen@plt>
mov    %eax,-0x82c(%rbp)
lea    -0x820(%rbp),%rdi
call   1040 <strlen@plt>
mov    %eax,-0x830(%rbp)
lea    -0x420(%rbp),%rax
mov    %rax,-0x828(%rbp)
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
je     131e <Q_StrReplace+0x1ce>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x82c(%rbp),%edx
mov    $0x0,%al
call   1030 <Q_stricmpn@plt>
cmp    $0x0,%eax
jne    12c4 <Q_StrReplace+0x174>
lea    -0x420(%rbp),%rdi
lea    -0x820(%rbp),%rdx
mov    $0x400,%esi
mov    $0x0,%al
call   1060 <Q_strcat@plt>
mov    -0x82c(%rbp),%ecx
mov    -0x10(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x10(%rbp)
mov    -0x830(%rbp),%ecx
mov    -0x828(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
mov    %rax,-0x828(%rbp)
jmp    124c <Q_StrReplace+0xfc>
lea    -0x420(%rbp),%rdi
call   1040 <strlen@plt>
mov    %rax,%rcx
add    $0x1,%rcx
mov    $0x400,%eax
cmp    %rcx,%rax
jbe    130d <Q_StrReplace+0x1bd>
mov    -0x10(%rbp),%rax
mov    (%rax),%cl
mov    -0x828(%rbp),%rax
mov    %cl,(%rax)
mov    -0x828(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x828(%rbp)
movb   $0x0,0x1(%rax)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    124c <Q_StrReplace+0xfc>
lea    -0x420(%rbp),%rsi
lea    0x2d34(%rip),%rdi
mov    $0x400,%edx
mov    $0x0,%al
call   1070 <Q_strncpyz@plt>
lea    0x2d21(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x830,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Q_StrReplace>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x808,%rsp
mov    %rdx,%r12
mov    %rsi,%r14
mov    %rdi,%rbx
mov    %rsp,%rdi
mov    $0x400,%edx
xor    %esi,%esi
call   1050 <memset@plt>
lea    0x400(%rsp),%rdi
mov    $0x400,%edx
xor    %esi,%esi
call   1050 <memset@plt>
cmpb   $0x0,(%rbx)
je     1288 <Q_StrReplace+0x138>
cmpb   $0x0,(%r14)
je     11d3 <Q_StrReplace+0x83>
cmpb   $0x0,(%r12)
je     11e7 <Q_StrReplace+0x97>
lea    0x400(%rsp),%rdi
mov    $0x400,%edx
mov    %r12,%rsi
xor    %eax,%eax
call   1070 <Q_strncpyz@plt>
mov    (%rbx),%bpl
movb   $0x0,(%rsp)
mov    %r14,%rdi
call   1040 <strlen@plt>
test   %bpl,%bpl
jne    11f3 <Q_StrReplace+0xa3>
jmp    1272 <Q_StrReplace+0x122>
lea    0x2e86(%rip),%rdi
mov    $0x400,%edx
mov    %rbx,%rsi
jmp    1281 <Q_StrReplace+0x131>
movb   $0x0,(%rsp)
mov    %r14,%rdi
call   1040 <strlen@plt>
mov    %rax,%r12
lea    0x400(%rsp),%rdi
call   1040 <strlen@plt>
movslq %r12d,%rbp
movslq %eax,%r13
mov    %rsp,%r15
jmp    1232 <Q_StrReplace+0xe2>
xchg   %ax,%ax
mov    $0x400,%esi
mov    %rsp,%rdi
lea    0x400(%rsp),%rdx
xor    %eax,%eax
call   1060 <Q_strcat@plt>
add    %rbp,%rbx
add    %r13,%r15
cmpb   $0x0,(%rbx)
je     1272 <Q_StrReplace+0x122>
mov    %rbx,%rdi
mov    %r14,%rsi
mov    %r12d,%edx
xor    %eax,%eax
call   1030 <Q_stricmpn@plt>
test   %eax,%eax
je     1210 <Q_StrReplace+0xc0>
mov    %rsp,%rdi
call   1040 <strlen@plt>
add    $0x1,%rax
cmp    $0x3ff,%rax
ja     1269 <Q_StrReplace+0x119>
movzbl (%rbx),%eax
mov    %al,(%r15)
movb   $0x0,0x1(%r15)
add    $0x1,%r15
add    $0x1,%rbx
cmpb   $0x0,(%rbx)
jne    1232 <Q_StrReplace+0xe2>
lea    0x2de7(%rip),%rdi
mov    %rsp,%rsi
mov    $0x400,%edx
xor    %eax,%eax
call   1070 <Q_strncpyz@plt>
lea    0x2dd1(%rip),%rax
add    $0x808,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@Q_StrReplace.final = internal global [1024 x i8] zeroinitializer
define i8* @Q_StrReplace(i8* %0, i8* %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca [1024 x i8]
%9 = alloca [1024 x i8]
%10 = alloca i8*
%11 = alloca i32
%12 = alloca i32
store i8* %0, i8** %5
store i8* %1, i8** %6
store i8* %2, i8** %7
%13 = bitcast [1024 x i8]* %8 to i8*
%14 = bitcast [1024 x i8]* %9 to i8*
store i32 0, i32* %11
store i32 0, i32* %12
%15 = load i8*, i8** %5
%16 = load i8, i8* %15
%17 = icmp ne i8 %16, 0
br i1 %17, label %19, label %18
18: ; preds = %3
store i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @Q_StrReplace.final, i64 0, i64 0), i8** %4
br label %82
19: ; preds = %3
%20 = load i8*, i8** %6
%21 = load i8, i8* %20
%22 = icmp ne i8 %21, 0
br i1 %22, label %26, label %23
23: ; preds = %19
%24 = load i8*, i8** %5
%25 = call i32 (i8*, i8*, i64, ...) bitcast (i32 (...)* @Q_strncpyz to i32 (i8*, i8*, i64, ...)*)(i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @Q_StrReplace.final, i64 0, i64 0), i8* %24, i64 1024)
store i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @Q_StrReplace.final, i64 0, i64 0), i8** %4
br label %82
26: ; preds = %19
%27 = load i8*, i8** %7
%28 = load i8, i8* %27
%29 = icmp ne i8 %28, 0
br i1 %29, label %30, label %34
30: ; preds = %26
%31 = getelementptr inbounds [1024 x i8], [1024 x i8]* %9, i64 0, i64 0
%32 = load i8*, i8** %7
%33 = call i32 (i8*, i8*, i64, ...) bitcast (i32 (...)* @Q_strncpyz to i32 (i8*, i8*, i64, ...)*)(i8* %31, i8* %32, i64 1024)
br label %34
34: ; preds = %30, %26
%35 = getelementptr inbounds [1024 x i8], [1024 x i8]* %8, i64 0, i64 0
store i8 0, i8* %35
%36 = load i8*, i8** %6
%37 = call i64 @strlen(i8* %36)
%38 = trunc i64 %37 to i32
store i32 %38, i32* %11
%39 = getelementptr inbounds [1024 x i8], [1024 x i8]* %9, i64 0, i64 0
%40 = call i64 @strlen(i8* %39)
%41 = trunc i64 %40 to i32
store i32 %41, i32* %12
%42 = getelementptr inbounds [1024 x i8], [1024 x i8]* %8, i64 0, i64 0
store i8* %42, i8** %10
br label %43
43: ; preds = %76, %53, %34
%44 = load i8*, i8** %5
%45 = load i8, i8* %44
%46 = icmp ne i8 %45, 0
br i1 %46, label %47, label %79
47: ; preds = %43
%48 = load i8*, i8** %5
%49 = load i8*, i8** %6
%50 = load i32, i32* %11
%51 = call i32 (i8*, i8*, i32, ...) bitcast (i32 (...)* @Q_stricmpn to i32 (i8*, i8*, i32, ...)*)(i8* %48, i8* %49, i32 %50)
%52 = icmp ne i32 %51, 0
br i1 %52, label %65, label %53
53: ; preds = %47
%54 = getelementptr inbounds [1024 x i8], [1024 x i8]* %8, i64 0, i64 0
%55 = getelementptr inbounds [1024 x i8], [1024 x i8]* %9, i64 0, i64 0
%56 = call i32 (i8*, i64, i8*, ...) bitcast (i32 (...)* @Q_strcat to i32 (i8*, i64, i8*, ...)*)(i8* %54, i64 1024, i8* %55)
%57 = load i32, i32* %11
%58 = load i8*, i8** %5
%59 = sext i32 %57 to i64
%60 = getelementptr inbounds i8, i8* %58, i64 %59
store i8* %60, i8** %5
%61 = load i32, i32* %12
%62 = load i8*, i8** %10
%63 = sext i32 %61 to i64
%64 = getelementptr inbounds i8, i8* %62, i64 %63
store i8* %64, i8** %10
br label %43
65: ; preds = %47
%66 = getelementptr inbounds [1024 x i8], [1024 x i8]* %8, i64 0, i64 0
%67 = call i64 @strlen(i8* %66)
%68 = add i64 %67, 1
%69 = icmp ugt i64 1024, %68
br i1 %69, label %70, label %76
70: ; preds = %65
%71 = load i8*, i8** %5
%72 = load i8, i8* %71
%73 = load i8*, i8** %10
store i8 %72, i8* %73
%74 = load i8*, i8** %10
%75 = getelementptr inbounds i8, i8* %74, i32 1
store i8* %75, i8** %10
store i8 0, i8* %75
br label %76
76: ; preds = %70, %65
%77 = load i8*, i8** %5
%78 = getelementptr inbounds i8, i8* %77, i32 1
store i8* %78, i8** %5
br label %43
79: ; preds = %43
%80 = getelementptr inbounds [1024 x i8], [1024 x i8]* %8, i64 0, i64 0
%81 = call i32 (i8*, i8*, i64, ...) bitcast (i32 (...)* @Q_strncpyz to i32 (i8*, i8*, i64, ...)*)(i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @Q_StrReplace.final, i64 0, i64 0), i8* %80, i64 1024)
store i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @Q_StrReplace.final, i64 0, i64 0), i8** %4
br label %82
82: ; preds = %79, %23, %18
%83 = load i8*, i8** %4
ret i8* %83
}

LLVM IR (-O2):
@Q_StrReplace.final = internal global [1024 x i8] zeroinitializer
define i8* @Q_StrReplace(i8* %0, i8* %1, i8* %2) {
%4 = alloca [1024 x i8]
%5 = alloca [1024 x i8]
%6 = getelementptr inbounds [1024 x i8], [1024 x i8]* %4, i64 0, i64 0
%7 = getelementptr inbounds [1024 x i8], [1024 x i8]* %5, i64 0, i64 0
%8 = load i8, i8* %0
%9 = icmp eq i8 %8, 0
br i1 %9, label %59, label %10
10: ; preds = %3
%11 = load i8, i8* %1
%12 = icmp eq i8 %11, 0
br i1 %12, label %13, label %15
13: ; preds = %10
%14 = tail call i32 (i8*, i8*, i64, ...) bitcast (i32 (...)* @Q_strncpyz to i32 (i8*, i8*, i64, ...)*)(i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @Q_StrReplace.final, i64 0, i64 0), i8* %0, i64 1024)
br label %59
15: ; preds = %10
%16 = load i8, i8* %2
%17 = icmp eq i8 %16, 0
br i1 %17, label %18, label %20
18: ; preds = %15
store i8 0, i8* %6
%19 = call i64 @strlen(i8* %1)
br label %25
20: ; preds = %15
%21 = call i32 (i8*, i8*, i64, ...) bitcast (i32 (...)* @Q_strncpyz to i32 (i8*, i8*, i64, ...)*)(i8* %7, i8* %2, i64 1024)
%22 = load i8, i8* %0
%23 = icmp eq i8 %22, 0
store i8 0, i8* %6
%24 = call i64 @strlen(i8* %1)
br i1 %23, label %57, label %25
25: ; preds = %18, %20
%26 = phi i64 [ %19, %18 ], [ %24, %20 ]
%27 = trunc i64 %26 to i32
%28 = call i64 @strlen(i8* %7)
%29 = shl i64 %26, 32
%30 = ashr exact i64 %29, 32
%31 = shl i64 %28, 32
%32 = ashr exact i64 %31, 32
br label %33
33: ; preds = %25, %42
%34 = phi i8* [ %6, %25 ], [ %44, %42 ]
%35 = phi i8* [ %0, %25 ], [ %43, %42 ]
%36 = call i32 (i8*, i8*, i32, ...) bitcast (i32 (...)* @Q_stricmpn to i32 (i8*, i8*, i32, ...)*)(i8* %35, i8* %1, i32 %27)
%37 = icmp eq i32 %36, 0
br i1 %37, label %38, label %47
38: ; preds = %33
%39 = call i32 (i8*, i64, i8*, ...) bitcast (i32 (...)* @Q_strcat to i32 (i8*, i64, i8*, ...)*)(i8* %6, i64 1024, i8* %7)
%40 = getelementptr inbounds i8, i8* %35, i64 %30
%41 = getelementptr inbounds i8, i8* %34, i64 %32
br label %42
42: ; preds = %38, %54
%43 = phi i8* [ %56, %54 ], [ %40, %38 ]
%44 = phi i8* [ %55, %54 ], [ %41, %38 ]
%45 = load i8, i8* %43
%46 = icmp eq i8 %45, 0
br i1 %46, label %57, label %33
47: ; preds = %33
%48 = call i64 @strlen(i8* %6)
%49 = add i64 %48, 1
%50 = icmp ult i64 %49, 1024
br i1 %50, label %51, label %54
51: ; preds = %47
%52 = load i8, i8* %35
store i8 %52, i8* %34
%53 = getelementptr inbounds i8, i8* %34, i64 1
store i8 0, i8* %53
br label %54
54: ; preds = %51, %47
%55 = phi i8* [ %53, %51 ], [ %34, %47 ]
%56 = getelementptr inbounds i8, i8* %35, i64 1
br label %42
57: ; preds = %42, %20
%58 = call i32 (i8*, i8*, i64, ...) bitcast (i32 (...)* @Q_strncpyz to i32 (i8*, i8*, i64, ...)*)(i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @Q_StrReplace.final, i64 0, i64 0), i8* %6, i64 1024)
br label %59
59: ; preds = %3, %57, %13
ret i8* getelementptr inbounds ([1024 x i8], [1024 x i8]* @Q_StrReplace.final, i64 0, i64 0)
}