#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 */
typedef int uint8_t;
typedef int /*<<< orphan*/ __m128i;

/* Variables and functions */
int _SIDD_CMP_EQUAL_ANY;
int _SIDD_LEAST_SIGNIFICANT;
int _SIDD_UBYTE_OPS;
scalar_t__ _mm_cmpistrc(int /*<<< orphan*/ const, int /*<<< orphan*/ const,
                        int const);
int _mm_cmpistri(int /*<<< orphan*/ const, int /*<<< orphan*/ const, int const);
scalar_t__ _mm_cmpistrz(int /*<<< orphan*/ const, int /*<<< orphan*/ const,
                        int const);
int /*<<< orphan*/ _mm_loadu_si128(int /*<<< orphan*/ *);
int /*<<< orphan*/ _mm_setr_epi8(size_t, int /*<<< orphan*/, int /*<<< orphan*/,
                                 int /*<<< orphan*/, int /*<<< orphan*/,
                                 int /*<<< orphan*/, int /*<<< orphan*/,
                                 int /*<<< orphan*/, int /*<<< orphan*/,
                                 int /*<<< orphan*/, int /*<<< orphan*/,
                                 int /*<<< orphan*/, int /*<<< orphan*/,
                                 int /*<<< orphan*/, int /*<<< orphan*/,
                                 int /*<<< orphan*/);
int /*<<< orphan*/ assert(int);
int strnchr_sse42(const char *str, size_t c, size_t size) {
  assert(c >= 0);
  assert(c < 256);
  __m128i *bits = (__m128i *)str;
  const __m128i buf =
      _mm_setr_epi8(c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  const uint8_t mode =
      _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT;
  size--;
  while (size) {
    const __m128i chunk = _mm_loadu_si128(bits);
    if (_mm_cmpistrc(buf, chunk, mode)) {
      const int idx = _mm_cmpistri(buf, chunk, mode);
      return (int)(((char *)bits + idx) - str - 2);
      break;
    } else if (_mm_cmpistrz(buf, chunk, mode))
      break;
    bits++;
    size--;
  }
  return 0;
}


x86 assembly (clang, -O0):
<strnchr_sse42>:
push   %rbp
mov    %rsp,%rbp
sub    $0x90,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
cmpq   $0x0,-0x18(%rbp)
setae  %al
and    $0x1,%al
movzbl %al,%edi
call   1060 <assert@plt>
cmpq   $0x100,-0x18(%rbp)
setb   %al
and    $0x1,%al
movzbl %al,%edi
call   1060 <assert@plt>
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rdi
xor    %r9d,%r9d
mov    %r9d,%esi
mov    %r9d,%edx
mov    %r9d,%ecx
mov    %r9d,%r8d
movl   $0x0,(%rsp)
movl   $0x0,0x8(%rsp)
movl   $0x0,0x10(%rsp)
movl   $0x0,0x18(%rsp)
movl   $0x0,0x20(%rsp)
movl   $0x0,0x28(%rsp)
movl   $0x0,0x30(%rsp)
movl   $0x0,0x38(%rsp)
movl   $0x0,0x40(%rsp)
movl   $0x0,0x48(%rsp)
call   1030 <_mm_setr_epi8@plt>
mov    %eax,-0x2c(%rbp)
mov    0x2dc1(%rip),%rax
mov    (%rax),%eax
mov    0x2dd0(%rip),%rcx
or     (%rcx),%eax
mov    0x2db7(%rip),%rcx
or     (%rcx),%eax
mov    %eax,-0x30(%rbp)
mov    -0x20(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
je     12d7 <strnchr_sse42+0x177>
mov    -0x28(%rbp),%rdi
call   1070 <_mm_loadu_si128@plt>
mov    %eax,-0x34(%rbp)
mov    -0x2c(%rbp),%edi
mov    -0x34(%rbp),%esi
mov    -0x30(%rbp),%edx
call   1040 <_mm_cmpistrc@plt>
cmp    $0x0,%rax
je     1298 <strnchr_sse42+0x138>
mov    -0x2c(%rbp),%edi
mov    -0x34(%rbp),%esi
mov    -0x30(%rbp),%edx
call   1050 <_mm_cmpistri@plt>
mov    %eax,-0x38(%rbp)
mov    -0x28(%rbp),%rax
movslq -0x38(%rbp),%rcx
add    %rcx,%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
sub    $0x2,%rax
mov    %eax,-0x4(%rbp)
jmp    12de <strnchr_sse42+0x17e>
mov    -0x2c(%rbp),%edi
mov    -0x34(%rbp),%esi
mov    -0x30(%rbp),%edx
call   1080 <_mm_cmpistrz@plt>
cmp    $0x0,%rax
je     12b5 <strnchr_sse42+0x155>
jmp    12d7 <strnchr_sse42+0x177>
jmp    12ba <strnchr_sse42+0x15a>
mov    -0x28(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x20(%rbp)
jmp    123a <strnchr_sse42+0xda>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x90,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<strnchr_sse42>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rdx,%r14
mov    %rsi,%rbp
mov    %rdi,%rbx
mov    $0x1,%edi
call   1060 <assert@plt>
xor    %edi,%edi
cmp    $0x100,%rbp
setb   %dil
call   1060 <assert@plt>
xor    %r13d,%r13d
mov    %rbp,%rdi
xor    %esi,%esi
xor    %edx,%edx
xor    %ecx,%ecx
xor    %r8d,%r8d
xor    %r9d,%r9d
push   $0x0
push   $0x0
push   $0x0
push   $0x0
push   $0x0
push   $0x0
push   $0x0
push   $0x0
push   $0x0
push   $0x0
call   1030 <_mm_setr_epi8@plt>
add    $0x50,%rsp
cmp    $0x1,%r14
je     1259 <strnchr_sse42+0xf9>
mov    %eax,%r12d
mov    0x2e05(%rip),%rax
mov    0x2e16(%rip),%rcx
mov    (%rcx),%r13d
or     (%rax),%r13d
mov    0x2df9(%rip),%rax
or     (%rax),%r13d
add    $0xfffffffffffffffe,%r14
mov    $0x2,%r15d
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    %rbx,%rdi
call   1070 <_mm_loadu_si128@plt>
mov    %eax,%ebp
mov    %r12d,%edi
mov    %eax,%esi
mov    %r13d,%edx
call   1040 <_mm_cmpistrc@plt>
test   %rax,%rax
jne    1246 <strnchr_sse42+0xe6>
mov    %r12d,%edi
mov    %ebp,%esi
mov    %r13d,%edx
call   1080 <_mm_cmpistrz@plt>
sub    $0x1,%r14
setb   %cl
test   %rax,%rax
jne    1241 <strnchr_sse42+0xe1>
add    $0x4,%rbx
add    $0xfffffffc,%r15d
test   %cl,%cl
je     1200 <strnchr_sse42+0xa0>
xor    %r13d,%r13d
jmp    1259 <strnchr_sse42+0xf9>
mov    %r12d,%edi
mov    %ebp,%esi
mov    %r13d,%edx
call   1050 <_mm_cmpistri@plt>
mov    %eax,%r13d
sub    %r15d,%r13d
mov    %r13d,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
@_SIDD_UBYTE_OPS = global i32 0
@_SIDD_CMP_EQUAL_ANY = global i32 0
@_SIDD_LEAST_SIGNIFICANT = global i32 0
define i32 @strnchr_sse42(i8* %0, i64 %1, i64 %2) {
%4 = tail call i32 @assert(i32 1)
%5 = icmp ult i64 %1, 256
%6 = zext i1 %5 to i32
%7 = tail call i32 @assert(i32 %6)
%8 = tail call i32 @_mm_setr_epi8(i64 %1, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
%9 = load i32, i32* @_SIDD_UBYTE_OPS
%10 = load i32, i32* @_SIDD_CMP_EQUAL_ANY
%11 = or i32 %10, %9
%12 = load i32, i32* @_SIDD_LEAST_SIGNIFICANT
%13 = or i32 %11, %12
%14 = add i64 %2, -1
%15 = icmp eq i64 %14, 0
br i1 %15, label %41, label %16
16: ; preds = %3
%17 = bitcast i8* %0 to i32*
br label %18
18: ; preds = %16, %34
%19 = phi i64 [ %38, %34 ], [ %14, %16 ]
%20 = phi i32* [ %37, %34 ], [ %17, %16 ]
%21 = tail call i32 @_mm_loadu_si128(i32* %20)
%22 = tail call i64 @_mm_cmpistrc(i32 %8, i32 %21, i32 %13)
%23 = icmp eq i64 %22, 0
br i1 %23, label %34, label %24
24: ; preds = %18
%25 = tail call i32 @_mm_cmpistri(i32 %8, i32 %21, i32 %13)
%26 = bitcast i32* %20 to i8*
%27 = sext i32 %25 to i64
%28 = getelementptr inbounds i8, i8* %26, i64 %27
%29 = ptrtoint i8* %28 to i64
%30 = ptrtoint i8* %0 to i64
%31 = sub i64 %29, %30
%32 = trunc i64 %31 to i32
%33 = add i32 %32, -2
br label %41
34: ; preds = %18
%35 = tail call i64 @_mm_cmpistrz(i32 %8, i32 %21, i32 %13)
%36 = icmp ne i64 %35, 0
%37 = getelementptr inbounds i32, i32* %20, i64 1
%38 = add i64 %19, -1
%39 = icmp eq i64 %38, 0
%40 = select i1 %36, i1 true, i1 %39
br i1 %40, label %41, label %18
41: ; preds = %34, %3, %24
%42 = phi i32 [ %33, %24 ], [ 0, %3 ], [ 0, %34 ]
ret i32 %42
}