int fp_locate(unsigned char *data_buff, unsigned int data_len,
              unsigned char *find_buff, unsigned int find_len,
              unsigned char *mask_buff) {
  unsigned int s, i;
  if (find_len > data_len)
    return -1;
  for (s = 0; s < data_len - find_len; s++) {
    for (i = 0; i < find_len; i++) {
      if ((data_buff[s + i] & mask_buff[i]) != (find_buff[i] & mask_buff[i]))
        break;
    }
    if (i == find_len)
      return s;
  }
  return -1;
}


x86 assembly (clang, -O0):
<fp_locate>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %ecx,-0x24(%rbp)
mov    %r8,-0x30(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x14(%rbp),%eax
jbe    112e <fp_locate+0x2e>
movl   $0xffffffff,-0x4(%rbp)
jmp    11df <fp_locate+0xdf>
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
mov    -0x14(%rbp),%ecx
sub    -0x24(%rbp),%ecx
cmp    %ecx,%eax
jae    11d8 <fp_locate+0xd8>
movl   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%eax
cmp    -0x24(%rbp),%eax
jae    11ae <fp_locate+0xae>
mov    -0x10(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    -0x38(%rbp),%ecx
mov    %ecx,%ecx
movzbl (%rax,%rcx,1),%eax
mov    -0x30(%rbp),%rcx
mov    -0x38(%rbp),%edx
movzbl (%rcx,%rdx,1),%ecx
and    %ecx,%eax
mov    -0x20(%rbp),%rcx
mov    -0x38(%rbp),%edx
movzbl (%rcx,%rdx,1),%ecx
mov    -0x30(%rbp),%rdx
mov    -0x38(%rbp),%esi
movzbl (%rdx,%rsi,1),%edx
and    %edx,%ecx
cmp    %ecx,%eax
je     119b <fp_locate+0x9b>
jmp    11ae <fp_locate+0xae>
jmp    11a0 <fp_locate+0xa0>
mov    -0x38(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x38(%rbp)
jmp    114d <fp_locate+0x4d>
mov    -0x38(%rbp),%eax
cmp    -0x24(%rbp),%eax
jne    11c5 <fp_locate+0xc5>
mov    -0x34(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    11df <fp_locate+0xdf>
jmp    11ca <fp_locate+0xca>
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1135 <fp_locate+0x35>
movl   $0xffffffff,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<fp_locate>:
push   %rbx
sub    %ecx,%esi
jb     114d <fp_locate+0x4d>
je     114d <fp_locate+0x4d>
mov    %ecx,%r9d
xor    %eax,%eax
mov    $0x0,%r10d
test   %ecx,%ecx
je     1140 <fp_locate+0x40>
xor    %r10d,%r10d
nopl   0x0(%rax)
lea    (%rax,%r10,1),%r11d
movzbl (%rdx,%r10,1),%ebx
xor    (%rdi,%r11,1),%bl
test   %bl,(%r8,%r10,1)
jne    1140 <fp_locate+0x40>
add    $0x1,%r10
cmp    %r10,%r9
jne    1120 <fp_locate+0x20>
jmp    1152 <fp_locate+0x52>
xchg   %ax,%ax
cmp    %ecx,%r10d
je     1152 <fp_locate+0x52>
add    $0x1,%rax
cmp    %esi,%eax
jne    110c <fp_locate+0xc>
mov    $0xffffffff,%eax
pop    %rbx
ret

LLVM IR (-O0):
define i32 @fp_locate(i8* %0, i32 %1, i8* %2, i32 %3, i8* %4) {
%6 = alloca i32
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i8*
%10 = alloca i32
%11 = alloca i8*
%12 = alloca i32
%13 = alloca i32
store i8* %0, i8** %7
store i32 %1, i32* %8
store i8* %2, i8** %9
store i32 %3, i32* %10
store i8* %4, i8** %11
%14 = load i32, i32* %10
%15 = load i32, i32* %8
%16 = icmp ugt i32 %14, %15
br i1 %16, label %17, label %18
17: ; preds = %5
store i32 -1, i32* %6
br label %76
18: ; preds = %5
store i32 0, i32* %12
br label %19
19: ; preds = %72, %18
%20 = load i32, i32* %12
%21 = load i32, i32* %8
%22 = load i32, i32* %10
%23 = sub i32 %21, %22
%24 = icmp ult i32 %20, %23
br i1 %24, label %25, label %75
25: ; preds = %19
store i32 0, i32* %13
br label %26
26: ; preds = %62, %25
%27 = load i32, i32* %13
%28 = load i32, i32* %10
%29 = icmp ult i32 %27, %28
br i1 %29, label %30, label %65
30: ; preds = %26
%31 = load i8*, i8** %7
%32 = load i32, i32* %12
%33 = load i32, i32* %13
%34 = add i32 %32, %33
%35 = zext i32 %34 to i64
%36 = getelementptr inbounds i8, i8* %31, i64 %35
%37 = load i8, i8* %36
%38 = zext i8 %37 to i32
%39 = load i8*, i8** %11
%40 = load i32, i32* %13
%41 = zext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %39, i64 %41
%43 = load i8, i8* %42
%44 = zext i8 %43 to i32
%45 = and i32 %38, %44
%46 = load i8*, i8** %9
%47 = load i32, i32* %13
%48 = zext i32 %47 to i64
%49 = getelementptr inbounds i8, i8* %46, i64 %48
%50 = load i8, i8* %49
%51 = zext i8 %50 to i32
%52 = load i8*, i8** %11
%53 = load i32, i32* %13
%54 = zext i32 %53 to i64
%55 = getelementptr inbounds i8, i8* %52, i64 %54
%56 = load i8, i8* %55
%57 = zext i8 %56 to i32
%58 = and i32 %51, %57
%59 = icmp ne i32 %45, %58
br i1 %59, label %60, label %61
60: ; preds = %30
br label %65
61: ; preds = %30
br label %62
62: ; preds = %61
%63 = load i32, i32* %13
%64 = add i32 %63, 1
store i32 %64, i32* %13
br label %26
65: ; preds = %60, %26
%66 = load i32, i32* %13
%67 = load i32, i32* %10
%68 = icmp eq i32 %66, %67
br i1 %68, label %69, label %71
69: ; preds = %65
%70 = load i32, i32* %12
store i32 %70, i32* %6
br label %76
71: ; preds = %65
br label %72
72: ; preds = %71
%73 = load i32, i32* %12
%74 = add i32 %73, 1
store i32 %74, i32* %12
br label %19
75: ; preds = %19
store i32 -1, i32* %6
br label %76
76: ; preds = %75, %69, %17
%77 = load i32, i32* %6
ret i32 %77
}

LLVM IR (-O2):
define i32 @fp_locate(i8* nocapture %0, i32 %1, i8* nocapture %2, i32 %3, i8* nocapture %4) {
%6 = icmp ult i32 %1, %3
br i1 %6, label %40, label %7
7: ; preds = %5
%8 = sub i32 %1, %3
%9 = icmp eq i32 %8, 0
br i1 %9, label %40, label %10
10: ; preds = %7
%11 = icmp eq i32 %3, 0
%12 = zext i32 %3 to i64
br label %13
13: ; preds = %10, %37
%14 = phi i32 [ 0, %10 ], [ %38, %37 ]
br i1 %11, label %34, label %15
15: ; preds = %13, %29
%16 = phi i64 [ %30, %29 ], [ 0, %13 ]
%17 = trunc i64 %16 to i32
%18 = add i32 %14, %17
%19 = zext i32 %18 to i64
%20 = getelementptr inbounds i8, i8* %0, i64 %19
%21 = load i8, i8* %20
%22 = getelementptr inbounds i8, i8* %4, i64 %16
%23 = load i8, i8* %22
%24 = getelementptr inbounds i8, i8* %2, i64 %16
%25 = load i8, i8* %24
%26 = xor i8 %25, %21
%27 = and i8 %26, %23
%28 = icmp eq i8 %27, 0
br i1 %28, label %29, label %32
29: ; preds = %15
%30 = add nuw nsw i64 %16, 1
%31 = icmp eq i64 %30, %12
br i1 %31, label %40, label %15
32: ; preds = %15
%33 = trunc i64 %16 to i32
br label %34
34: ; preds = %32, %13
%35 = phi i32 [ 0, %13 ], [ %33, %32 ]
%36 = icmp eq i32 %35, %3
br i1 %36, label %40, label %37
37: ; preds = %34
%38 = add nuw i32 %14, 1
%39 = icmp eq i32 %38, %8
br i1 %39, label %40, label %13
40: ; preds = %34, %37, %29, %7, %5
%41 = phi i32 [ -1, %5 ], [ -1, %7 ], [ %14, %29 ], [ %14, %34 ], [ -1, %37 ]
ret i32 %41
}