int file_is_canonical(const char *z) {
  int i;
  if (z[0] != '/')
    return 0;
  for (i = 0; z[i]; i++) {
    if (z[i] == '\\')
      return 0;
    if (z[i] == '/') {
      if (z[i + 1] == '.') {
        if (z[i + 2] == '/' || z[i + 2] == 0)
          return 0;
        if (z[i + 2] == '.' && (z[i + 3] == '/' || z[i + 3] == 0))
          return 0;
      }
    }
  }
  return 1;
}


x86 assembly (clang, -O0):
<file_is_canonical>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
je     1124 <file_is_canonical+0x24>
movl   $0x0,-0x4(%rbp)
jmp    124b <file_is_canonical+0x14b>
movl   $0x0,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
cmpb   $0x0,(%rax,%rcx,1)
je     1244 <file_is_canonical+0x144>
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x5c,%eax
jne    115e <file_is_canonical+0x5e>
movl   $0x0,-0x4(%rbp)
jmp    124b <file_is_canonical+0x14b>
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2f,%eax
jne    1231 <file_is_canonical+0x131>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2e,%eax
jne    122c <file_is_canonical+0x12c>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2f,%eax
je     11c1 <file_is_canonical+0xc1>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
jne    11cd <file_is_canonical+0xcd>
movl   $0x0,-0x4(%rbp)
jmp    124b <file_is_canonical+0x14b>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2e,%eax
jne    1227 <file_is_canonical+0x127>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x2f,%eax
je     121b <file_is_canonical+0x11b>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
jne    1227 <file_is_canonical+0x127>
movl   $0x0,-0x4(%rbp)
jmp    124b <file_is_canonical+0x14b>
jmp    122c <file_is_canonical+0x12c>
jmp    1231 <file_is_canonical+0x131>
jmp    1236 <file_is_canonical+0x136>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    112b <file_is_canonical+0x2b>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<file_is_canonical>:
xor    %eax,%eax
cmpb   $0x2f,(%rdi)
jne    1169 <file_is_canonical+0x69>
mov    $0x2f,%cl
xor    %eax,%eax
xor    %edx,%edx
nopl   (%rax)
mov    %rdx,%rsi
cmp    $0x2f,%cl
je     1130 <file_is_canonical+0x30>
test   %cl,%cl
je     116a <file_is_canonical+0x6a>
cmp    $0x5c,%cl
je     1169 <file_is_canonical+0x69>
movzbl 0x1(%rdi,%rsi,1),%ecx
add    $0x1,%rsi
mov    %rsi,%rdx
jmp    1110 <file_is_canonical+0x10>
nop
lea    0x1(%rsi),%rdx
movzbl 0x1(%rdi,%rsi,1),%ecx
cmp    $0x2e,%cl
jne    1110 <file_is_canonical+0x10>
movzbl 0x2(%rsi,%rdi,1),%r8d
mov    $0x2e,%cl
cmp    $0x2e,%r8b
je     1159 <file_is_canonical+0x59>
test   %r8b,%r8b
je     1169 <file_is_canonical+0x69>
cmp    $0x2f,%r8b
jne    1110 <file_is_canonical+0x10>
jmp    1169 <file_is_canonical+0x69>
movzbl 0x3(%rsi,%rdi,1),%esi
test   %sil,%sil
je     1169 <file_is_canonical+0x69>
cmp    $0x2f,%sil
jne    1110 <file_is_canonical+0x10>
ret
mov    $0x1,%eax
ret

LLVM IR (-O0):
define i32 @file_is_canonical(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i32
store i8* %0, i8** %3
%5 = load i8*, i8** %3
%6 = getelementptr inbounds i8, i8* %5, i64 0
%7 = load i8, i8* %6
%8 = sext i8 %7 to i32
%9 = icmp ne i32 %8, 47
br i1 %9, label %10, label %11
10: ; preds = %1
store i32 0, i32* %2
br label %99
11: ; preds = %1
store i32 0, i32* %4
br label %12
12: ; preds = %95, %11
%13 = load i8*, i8** %3
%14 = load i32, i32* %4
%15 = sext i32 %14 to i64
%16 = getelementptr inbounds i8, i8* %13, i64 %15
%17 = load i8, i8* %16
%18 = icmp ne i8 %17, 0
br i1 %18, label %19, label %98
19: ; preds = %12
%20 = load i8*, i8** %3
%21 = load i32, i32* %4
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds i8, i8* %20, i64 %22
%24 = load i8, i8* %23
%25 = sext i8 %24 to i32
%26 = icmp eq i32 %25, 92
br i1 %26, label %27, label %28
27: ; preds = %19
store i32 0, i32* %2
br label %99
28: ; preds = %19
%29 = load i8*, i8** %3
%30 = load i32, i32* %4
%31 = sext i32 %30 to i64
%32 = getelementptr inbounds i8, i8* %29, i64 %31
%33 = load i8, i8* %32
%34 = sext i8 %33 to i32
%35 = icmp eq i32 %34, 47
br i1 %35, label %36, label %94
36: ; preds = %28
%37 = load i8*, i8** %3
%38 = load i32, i32* %4
%39 = add nsw i32 %38, 1
%40 = sext i32 %39 to i64
%41 = getelementptr inbounds i8, i8* %37, i64 %40
%42 = load i8, i8* %41
%43 = sext i8 %42 to i32
%44 = icmp eq i32 %43, 46
br i1 %44, label %45, label %93
45: ; preds = %36
%46 = load i8*, i8** %3
%47 = load i32, i32* %4
%48 = add nsw i32 %47, 2
%49 = sext i32 %48 to i64
%50 = getelementptr inbounds i8, i8* %46, i64 %49
%51 = load i8, i8* %50
%52 = sext i8 %51 to i32
%53 = icmp eq i32 %52, 47
br i1 %53, label %63, label %54
54: ; preds = %45
%55 = load i8*, i8** %3
%56 = load i32, i32* %4
%57 = add nsw i32 %56, 2
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds i8, i8* %55, i64 %58
%60 = load i8, i8* %59
%61 = sext i8 %60 to i32
%62 = icmp eq i32 %61, 0
br i1 %62, label %63, label %64
63: ; preds = %54, %45
store i32 0, i32* %2
br label %99
64: ; preds = %54
%65 = load i8*, i8** %3
%66 = load i32, i32* %4
%67 = add nsw i32 %66, 2
%68 = sext i32 %67 to i64
%69 = getelementptr inbounds i8, i8* %65, i64 %68
%70 = load i8, i8* %69
%71 = sext i8 %70 to i32
%72 = icmp eq i32 %71, 46
br i1 %72, label %73, label %92
73: ; preds = %64
%74 = load i8*, i8** %3
%75 = load i32, i32* %4
%76 = add nsw i32 %75, 3
%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 = icmp eq i32 %80, 47
br i1 %81, label %91, label %82
82: ; preds = %73
%83 = load i8*, i8** %3
%84 = load i32, i32* %4
%85 = add nsw i32 %84, 3
%86 = sext i32 %85 to i64
%87 = getelementptr inbounds i8, i8* %83, i64 %86
%88 = load i8, i8* %87
%89 = sext i8 %88 to i32
%90 = icmp eq i32 %89, 0
br i1 %90, label %91, label %92
91: ; preds = %82, %73
store i32 0, i32* %2
br label %99
92: ; preds = %82, %64
br label %93
93: ; preds = %92, %36
br label %94
94: ; preds = %93, %28
br label %95
95: ; preds = %94
%96 = load i32, i32* %4
%97 = add nsw i32 %96, 1
store i32 %97, i32* %4
br label %12
98: ; preds = %12
store i32 1, i32* %2
br label %99
99: ; preds = %98, %91, %63, %27, %10
%100 = load i32, i32* %2
ret i32 %100
}

LLVM IR (-O2):
define i32 @file_is_canonical(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = icmp eq i8 %2, 47
br i1 %3, label %4, label %28
4: ; preds = %1, %11
%5 = phi i8 [ %12, %11 ], [ 47, %1 ]
%6 = phi i64 [ %13, %11 ], [ 0, %1 ]
switch i8 %5, label %7 [
i8 0, label %28
i8 92, label %27
i8 47, label %14
]
7: ; preds = %4
%8 = add nuw i64 %6, 1
%9 = getelementptr inbounds i8, i8* %0, i64 %8
%10 = load i8, i8* %9
br label %11
11: ; preds = %7, %23, %19, %14
%12 = phi i8 [ %10, %7 ], [ 46, %23 ], [ 46, %19 ], [ %17, %14 ]
%13 = phi i64 [ %8, %7 ], [ %15, %23 ], [ %15, %19 ], [ %15, %14 ]
br label %4
14: ; preds = %4
%15 = add nuw i64 %6, 1
%16 = getelementptr inbounds i8, i8* %0, i64 %15
%17 = load i8, i8* %16
%18 = icmp eq i8 %17, 46
br i1 %18, label %19, label %11
19: ; preds = %14
%20 = add nuw nsw i64 %6, 2
%21 = getelementptr inbounds i8, i8* %0, i64 %20
%22 = load i8, i8* %21
switch i8 %22, label %11 [
i8 47, label %27
i8 0, label %27
i8 46, label %23
]
23: ; preds = %19
%24 = add nuw nsw i64 %6, 3
%25 = getelementptr inbounds i8, i8* %0, i64 %24
%26 = load i8, i8* %25
switch i8 %26, label %11 [
i8 47, label %27
i8 0, label %27
]
27: ; preds = %4, %19, %19, %23, %23
br label %28
28: ; preds = %4, %27, %1
%29 = phi i32 [ 0, %1 ], [ 0, %27 ], [ 1, %4 ]
ret i32 %29
}