const char *match_one_of(const char *p, const char *s, char *result) {
  if (!p)
    return 0;
  for (; *s; ++s)
    if (*p == *s) {
      *result = *p;
      return ++p;
    }
  return 0;
}


x86 assembly (clang, -O0):
<match_one_of>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    1128 <match_one_of+0x28>
movq   $0x0,-0x8(%rbp)
jmp    118f <match_one_of+0x8f>
jmp    112d <match_one_of+0x2d>
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     1187 <match_one_of+0x87>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
mov    -0x18(%rbp),%rcx
movsbl (%rcx),%ecx
cmp    %ecx,%eax
jne    1171 <match_one_of+0x71>
mov    -0x10(%rbp),%rax
mov    (%rax),%cl
mov    -0x20(%rbp),%rax
mov    %cl,(%rax)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    %rax,-0x8(%rbp)
jmp    118f <match_one_of+0x8f>
jmp    1176 <match_one_of+0x76>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    112d <match_one_of+0x2d>
movq   $0x0,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<match_one_of>:
test   %rdi,%rdi
je     1131 <match_one_of+0x31>
mov    (%rsi),%cl
test   %cl,%cl
je     1131 <match_one_of+0x31>
mov    (%rdi),%r8b
add    $0x1,%rsi
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
cmp    %cl,%r8b
je     1134 <match_one_of+0x34>
movzbl (%rsi),%ecx
add    $0x1,%rsi
test   %cl,%cl
jne    1120 <match_one_of+0x20>
ret
xor    %eax,%eax
ret
mov    %r8b,(%rdx)
add    $0x1,%rdi
mov    %rdi,%rax
ret

LLVM IR (-O0):
define i8* @match_one_of(i8* %0, i8* %1, i8* %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i8*
store i8* %0, i8** %5
store i8* %1, i8** %6
store i8* %2, i8** %7
%8 = load i8*, i8** %5
%9 = icmp ne i8* %8, null
br i1 %9, label %11, label %10
10: ; preds = %3
store i8* null, i8** %4
br label %35
11: ; preds = %3
br label %12
12: ; preds = %31, %11
%13 = load i8*, i8** %6
%14 = load i8, i8* %13
%15 = icmp ne i8 %14, 0
br i1 %15, label %16, label %34
16: ; preds = %12
%17 = load i8*, i8** %5
%18 = load i8, i8* %17
%19 = sext i8 %18 to i32
%20 = load i8*, i8** %6
%21 = load i8, i8* %20
%22 = sext i8 %21 to i32
%23 = icmp eq i32 %19, %22
br i1 %23, label %24, label %30
24: ; preds = %16
%25 = load i8*, i8** %5
%26 = load i8, i8* %25
%27 = load i8*, i8** %7
store i8 %26, i8* %27
%28 = load i8*, i8** %5
%29 = getelementptr inbounds i8, i8* %28, i32 1
store i8* %29, i8** %5
store i8* %29, i8** %4
br label %35
30: ; preds = %16
br label %31
31: ; preds = %30
%32 = load i8*, i8** %6
%33 = getelementptr inbounds i8, i8* %32, i32 1
store i8* %33, i8** %6
br label %12
34: ; preds = %12
store i8* null, i8** %4
br label %35
35: ; preds = %34, %24, %10
%36 = load i8*, i8** %4
ret i8* %36
}

LLVM IR (-O2):
define i8* @match_one_of(i8* %0, i8* nocapture %1, i8* nocapture writeonly %2) {
%4 = icmp eq i8* %0, null
br i1 %4, label %20, label %5
5: ; preds = %3
%6 = load i8, i8* %1
%7 = icmp eq i8 %6, 0
br i1 %7, label %20, label %8
8: ; preds = %5
%9 = load i8, i8* %0
br label %13
10: ; preds = %13
%11 = load i8, i8* %17
%12 = icmp eq i8 %11, 0
br i1 %12, label %20, label %13
13: ; preds = %8, %10
%14 = phi i8 [ %6, %8 ], [ %11, %10 ]
%15 = phi i8* [ %1, %8 ], [ %17, %10 ]
%16 = icmp eq i8 %9, %14
%17 = getelementptr inbounds i8, i8* %15, i64 1
br i1 %16, label %18, label %10
18: ; preds = %13
store i8 %9, i8* %2
%19 = getelementptr inbounds i8, i8* %0, i64 1
br label %20
20: ; preds = %10, %5, %3, %18
%21 = phi i8* [ %19, %18 ], [ null, %3 ], [ null, %5 ], [ null, %10 ]
ret i8* %21
}