int romanToInt(char *s) {
  char *p = s, *np;
  int n = 0;
  while (*p) {
    if (*p == 'I') {
      np = p + 1;
      if (*np) {
        if (*np == 'V') {
          n += 4;
          p++;
        } else if (*np == 'X') {
          n += 9;
          p++;
        } else {
          n += 1;
        }
      } else {
        n += 1;
      }
    } else if (*p == 'X') {
      np = p + 1;
      if (*np) {
        if (*np == 'L') {
          n += 40;
          p++;
        } else if (*np == 'C') {
          n += 90;
          p++;
        } else {
          n += 10;
        }
      } else {
        n += 10;
      }
    } else if (*p == 'C') {
      np = p + 1;
      if (*np) {
        if (*np == 'D') {
          n += 400;
          p++;
        } else if (*np == 'M') {
          n += 900;
          p++;
        } else {
          n += 100;
        }
      } else {
        n += 100;
      }
    } else if (*p == 'V') {
      n += 5;
    } else if (*p == 'L') {
      n += 50;
    } else if (*p == 'D') {
      n += 500;
    } else if (*p == 'M') {
      n += 1000;
    }
    p++;
  }
  return n;
}


x86 assembly (clang, -O0):
<romanToInt>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x10(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
cmpb   $0x0,(%rax)
je     13a8 <romanToInt+0x2a8>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x49,%eax
jne    11c2 <romanToInt+0xc2>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     11b4 <romanToInt+0xb4>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x56,%eax
jne    1177 <romanToInt+0x77>
mov    -0x1c(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    11af <romanToInt+0xaf>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x58,%eax
jne    11a1 <romanToInt+0xa1>
mov    -0x1c(%rbp),%eax
add    $0x9,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    11aa <romanToInt+0xaa>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    11af <romanToInt+0xaf>
jmp    11bd <romanToInt+0xbd>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1397 <romanToInt+0x297>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x58,%eax
jne    1260 <romanToInt+0x160>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     1252 <romanToInt+0x152>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x4c,%eax
jne    1215 <romanToInt+0x115>
mov    -0x1c(%rbp),%eax
add    $0x28,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    124d <romanToInt+0x14d>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x43,%eax
jne    123f <romanToInt+0x13f>
mov    -0x1c(%rbp),%eax
add    $0x5a,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1248 <romanToInt+0x148>
mov    -0x1c(%rbp),%eax
add    $0xa,%eax
mov    %eax,-0x1c(%rbp)
jmp    124d <romanToInt+0x14d>
jmp    125b <romanToInt+0x15b>
mov    -0x1c(%rbp),%eax
add    $0xa,%eax
mov    %eax,-0x1c(%rbp)
jmp    1392 <romanToInt+0x292>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x43,%eax
jne    1302 <romanToInt+0x202>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     12f4 <romanToInt+0x1f4>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x44,%eax
jne    12b5 <romanToInt+0x1b5>
mov    -0x1c(%rbp),%eax
add    $0x190,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    12ef <romanToInt+0x1ef>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x4d,%eax
jne    12e1 <romanToInt+0x1e1>
mov    -0x1c(%rbp),%eax
add    $0x384,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    12ea <romanToInt+0x1ea>
mov    -0x1c(%rbp),%eax
add    $0x64,%eax
mov    %eax,-0x1c(%rbp)
jmp    12ef <romanToInt+0x1ef>
jmp    12fd <romanToInt+0x1fd>
mov    -0x1c(%rbp),%eax
add    $0x64,%eax
mov    %eax,-0x1c(%rbp)
jmp    138d <romanToInt+0x28d>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x56,%eax
jne    1320 <romanToInt+0x220>
mov    -0x1c(%rbp),%eax
add    $0x5,%eax
mov    %eax,-0x1c(%rbp)
jmp    1388 <romanToInt+0x288>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x4c,%eax
jne    133e <romanToInt+0x23e>
mov    -0x1c(%rbp),%eax
add    $0x32,%eax
mov    %eax,-0x1c(%rbp)
jmp    1383 <romanToInt+0x283>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x44,%eax
jne    135e <romanToInt+0x25e>
mov    -0x1c(%rbp),%eax
add    $0x1f4,%eax
mov    %eax,-0x1c(%rbp)
jmp    137e <romanToInt+0x27e>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x4d,%eax
jne    1379 <romanToInt+0x279>
mov    -0x1c(%rbp),%eax
add    $0x3e8,%eax
mov    %eax,-0x1c(%rbp)
jmp    137e <romanToInt+0x27e>
jmp    1383 <romanToInt+0x283>
jmp    1388 <romanToInt+0x288>
jmp    138d <romanToInt+0x28d>
jmp    1392 <romanToInt+0x292>
jmp    1397 <romanToInt+0x297>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1117 <romanToInt+0x17>
mov    -0x1c(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<romanToInt>:
xor    %eax,%eax
lea    0xef7(%rip),%rcx
jmp    1114 <romanToInt+0x14>
add    $0x3e8,%eax
add    $0x1,%rdi
movzbl (%rdi),%edx
lea    -0x43(%rdx),%esi
cmp    $0x15,%sil
ja     11cf <romanToInt+0xcf>
movzbl %sil,%edx
movslq (%rcx,%rdx,4),%rdx
add    %rcx,%rdx
jmp    *%rdx
movzbl 0x1(%rdi),%edx
test   %dl,%dl
je     11d9 <romanToInt+0xd9>
lea    0x1(%rdi),%rsi
cmp    $0x4d,%dl
je     11fd <romanToInt+0xfd>
cmp    $0x44,%dl
jne    11d9 <romanToInt+0xd9>
add    $0x190,%eax
mov    %rsi,%rdi
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
add    $0x1f4,%eax
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
movzbl 0x1(%rdi),%edx
test   %dl,%dl
je     11e5 <romanToInt+0xe5>
lea    0x1(%rdi),%rsi
cmp    $0x58,%dl
je     120e <romanToInt+0x10e>
cmp    $0x56,%dl
jne    11e5 <romanToInt+0xe5>
add    $0x4,%eax
mov    %rsi,%rdi
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
add    $0x32,%eax
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
add    $0x5,%eax
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
movzbl 0x1(%rdi),%edx
test   %dl,%dl
je     11f1 <romanToInt+0xf1>
lea    0x1(%rdi),%rsi
cmp    $0x43,%dl
je     121d <romanToInt+0x11d>
cmp    $0x4c,%dl
jne    11f1 <romanToInt+0xf1>
add    $0x28,%eax
mov    %rsi,%rdi
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
test   %dl,%dl
jne    1110 <romanToInt+0x10>
jmp    122c <romanToInt+0x12c>
add    $0x64,%eax
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
add    $0x1,%eax
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
add    $0xa,%eax
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
add    $0x384,%eax
mov    %rsi,%rdi
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
add    $0x9,%eax
mov    %rsi,%rdi
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
add    $0x5a,%eax
mov    %rsi,%rdi
add    $0x1,%rdi
jmp    1114 <romanToInt+0x14>
ret

LLVM IR (-O0):
define i32 @romanToInt(i8* %0) {
%2 = alloca i8*
%3 = alloca i8*
%4 = alloca i8*
%5 = alloca i32
store i8* %0, i8** %2
%6 = load i8*, i8** %2
store i8* %6, i8** %3
store i32 0, i32* %5
br label %7
7: ; preds = %169, %1
%8 = load i8*, i8** %3
%9 = load i8, i8* %8
%10 = icmp ne i8 %9, 0
br i1 %10, label %11, label %172
11: ; preds = %7
%12 = load i8*, i8** %3
%13 = load i8, i8* %12
%14 = sext i8 %13 to i32
%15 = icmp eq i32 %14, 73
br i1 %15, label %16, label %51
16: ; preds = %11
%17 = load i8*, i8** %3
%18 = getelementptr inbounds i8, i8* %17, i64 1
store i8* %18, i8** %4
%19 = load i8*, i8** %4
%20 = load i8, i8* %19
%21 = icmp ne i8 %20, 0
br i1 %21, label %22, label %47
22: ; preds = %16
%23 = load i8*, i8** %4
%24 = load i8, i8* %23
%25 = sext i8 %24 to i32
%26 = icmp eq i32 %25, 86
br i1 %26, label %27, label %32
27: ; preds = %22
%28 = load i32, i32* %5
%29 = add nsw i32 %28, 4
store i32 %29, i32* %5
%30 = load i8*, i8** %3
%31 = getelementptr inbounds i8, i8* %30, i32 1
store i8* %31, i8** %3
br label %46
32: ; preds = %22
%33 = load i8*, i8** %4
%34 = load i8, i8* %33
%35 = sext i8 %34 to i32
%36 = icmp eq i32 %35, 88
br i1 %36, label %37, label %42
37: ; preds = %32
%38 = load i32, i32* %5
%39 = add nsw i32 %38, 9
store i32 %39, i32* %5
%40 = load i8*, i8** %3
%41 = getelementptr inbounds i8, i8* %40, i32 1
store i8* %41, i8** %3
br label %45
42: ; preds = %32
%43 = load i32, i32* %5
%44 = add nsw i32 %43, 1
store i32 %44, i32* %5
br label %45
45: ; preds = %42, %37
br label %46
46: ; preds = %45, %27
br label %50
47: ; preds = %16
%48 = load i32, i32* %5
%49 = add nsw i32 %48, 1
store i32 %49, i32* %5
br label %50
50: ; preds = %47, %46
br label %169
51: ; preds = %11
%52 = load i8*, i8** %3
%53 = load i8, i8* %52
%54 = sext i8 %53 to i32
%55 = icmp eq i32 %54, 88
br i1 %55, label %56, label %91
56: ; preds = %51
%57 = load i8*, i8** %3
%58 = getelementptr inbounds i8, i8* %57, i64 1
store i8* %58, i8** %4
%59 = load i8*, i8** %4
%60 = load i8, i8* %59
%61 = icmp ne i8 %60, 0
br i1 %61, label %62, label %87
62: ; preds = %56
%63 = load i8*, i8** %4
%64 = load i8, i8* %63
%65 = sext i8 %64 to i32
%66 = icmp eq i32 %65, 76
br i1 %66, label %67, label %72
67: ; preds = %62
%68 = load i32, i32* %5
%69 = add nsw i32 %68, 40
store i32 %69, i32* %5
%70 = load i8*, i8** %3
%71 = getelementptr inbounds i8, i8* %70, i32 1
store i8* %71, i8** %3
br label %86
72: ; preds = %62
%73 = load i8*, i8** %4
%74 = load i8, i8* %73
%75 = sext i8 %74 to i32
%76 = icmp eq i32 %75, 67
br i1 %76, label %77, label %82
77: ; preds = %72
%78 = load i32, i32* %5
%79 = add nsw i32 %78, 90
store i32 %79, i32* %5
%80 = load i8*, i8** %3
%81 = getelementptr inbounds i8, i8* %80, i32 1
store i8* %81, i8** %3
br label %85
82: ; preds = %72
%83 = load i32, i32* %5
%84 = add nsw i32 %83, 10
store i32 %84, i32* %5
br label %85
85: ; preds = %82, %77
br label %86
86: ; preds = %85, %67
br label %90
87: ; preds = %56
%88 = load i32, i32* %5
%89 = add nsw i32 %88, 10
store i32 %89, i32* %5
br label %90
90: ; preds = %87, %86
br label %168
91: ; preds = %51
%92 = load i8*, i8** %3
%93 = load i8, i8* %92
%94 = sext i8 %93 to i32
%95 = icmp eq i32 %94, 67
br i1 %95, label %96, label %131
96: ; preds = %91
%97 = load i8*, i8** %3
%98 = getelementptr inbounds i8, i8* %97, i64 1
store i8* %98, i8** %4
%99 = load i8*, i8** %4
%100 = load i8, i8* %99
%101 = icmp ne i8 %100, 0
br i1 %101, label %102, label %127
102: ; preds = %96
%103 = load i8*, i8** %4
%104 = load i8, i8* %103
%105 = sext i8 %104 to i32
%106 = icmp eq i32 %105, 68
br i1 %106, label %107, label %112
107: ; preds = %102
%108 = load i32, i32* %5
%109 = add nsw i32 %108, 400
store i32 %109, i32* %5
%110 = load i8*, i8** %3
%111 = getelementptr inbounds i8, i8* %110, i32 1
store i8* %111, i8** %3
br label %126
112: ; preds = %102
%113 = load i8*, i8** %4
%114 = load i8, i8* %113
%115 = sext i8 %114 to i32
%116 = icmp eq i32 %115, 77
br i1 %116, label %117, label %122
117: ; preds = %112
%118 = load i32, i32* %5
%119 = add nsw i32 %118, 900
store i32 %119, i32* %5
%120 = load i8*, i8** %3
%121 = getelementptr inbounds i8, i8* %120, i32 1
store i8* %121, i8** %3
br label %125
122: ; preds = %112
%123 = load i32, i32* %5
%124 = add nsw i32 %123, 100
store i32 %124, i32* %5
br label %125
125: ; preds = %122, %117
br label %126
126: ; preds = %125, %107
br label %130
127: ; preds = %96
%128 = load i32, i32* %5
%129 = add nsw i32 %128, 100
store i32 %129, i32* %5
br label %130
130: ; preds = %127, %126
br label %167
131: ; preds = %91
%132 = load i8*, i8** %3
%133 = load i8, i8* %132
%134 = sext i8 %133 to i32
%135 = icmp eq i32 %134, 86
br i1 %135, label %136, label %139
136: ; preds = %131
%137 = load i32, i32* %5
%138 = add nsw i32 %137, 5
store i32 %138, i32* %5
br label %166
139: ; preds = %131
%140 = load i8*, i8** %3
%141 = load i8, i8* %140
%142 = sext i8 %141 to i32
%143 = icmp eq i32 %142, 76
br i1 %143, label %144, label %147
144: ; preds = %139
%145 = load i32, i32* %5
%146 = add nsw i32 %145, 50
store i32 %146, i32* %5
br label %165
147: ; preds = %139
%148 = load i8*, i8** %3
%149 = load i8, i8* %148
%150 = sext i8 %149 to i32
%151 = icmp eq i32 %150, 68
br i1 %151, label %152, label %155
152: ; preds = %147
%153 = load i32, i32* %5
%154 = add nsw i32 %153, 500
store i32 %154, i32* %5
br label %164
155: ; preds = %147
%156 = load i8*, i8** %3
%157 = load i8, i8* %156
%158 = sext i8 %157 to i32
%159 = icmp eq i32 %158, 77
br i1 %159, label %160, label %163
160: ; preds = %155
%161 = load i32, i32* %5
%162 = add nsw i32 %161, 1000
store i32 %162, i32* %5
br label %163
163: ; preds = %160, %155
br label %164
164: ; preds = %163, %152
br label %165
165: ; preds = %164, %144
br label %166
166: ; preds = %165, %136
br label %167
167: ; preds = %166, %130
br label %168
168: ; preds = %167, %90
br label %169
169: ; preds = %168, %50
%170 = load i8*, i8** %3
%171 = getelementptr inbounds i8, i8* %170, i32 1
store i8* %171, i8** %3
br label %7
172: ; preds = %7
%173 = load i32, i32* %5
ret i32 %173
}

LLVM IR (-O2):
define i32 @romanToInt(i8* %0) {
br label %2
2: ; preds = %47, %1
%3 = phi i8* [ %0, %1 ], [ %50, %47 ]
%4 = phi i32 [ 0, %1 ], [ %49, %47 ]
%5 = load i8, i8* %3
switch i8 %5, label %47 [
i8 0, label %51
i8 73, label %6
i8 88, label %17
i8 67, label %28
i8 86, label %39
i8 76, label %41
i8 68, label %43
i8 77, label %45
]
6: ; preds = %2
%7 = getelementptr inbounds i8, i8* %3, i64 1
%8 = load i8, i8* %7
switch i8 %8, label %13 [
i8 0, label %15
i8 86, label %9
i8 88, label %11
]
9: ; preds = %6
%10 = add nsw i32 %4, 4
br label %47
11: ; preds = %6
%12 = add nsw i32 %4, 9
br label %47
13: ; preds = %6
%14 = add nsw i32 %4, 1
br label %47
15: ; preds = %6
%16 = add nsw i32 %4, 1
br label %47
17: ; preds = %2
%18 = getelementptr inbounds i8, i8* %3, i64 1
%19 = load i8, i8* %18
switch i8 %19, label %24 [
i8 0, label %26
i8 76, label %20
i8 67, label %22
]
20: ; preds = %17
%21 = add nsw i32 %4, 40
br label %47
22: ; preds = %17
%23 = add nsw i32 %4, 90
br label %47
24: ; preds = %17
%25 = add nsw i32 %4, 10
br label %47
26: ; preds = %17
%27 = add nsw i32 %4, 10
br label %47
28: ; preds = %2
%29 = getelementptr inbounds i8, i8* %3, i64 1
%30 = load i8, i8* %29
switch i8 %30, label %35 [
i8 0, label %37
i8 68, label %31
i8 77, label %33
]
31: ; preds = %28
%32 = add nsw i32 %4, 400
br label %47
33: ; preds = %28
%34 = add nsw i32 %4, 900
br label %47
35: ; preds = %28
%36 = add nsw i32 %4, 100
br label %47
37: ; preds = %28
%38 = add nsw i32 %4, 100
br label %47
39: ; preds = %2
%40 = add nsw i32 %4, 5
br label %47
41: ; preds = %2
%42 = add nsw i32 %4, 50
br label %47
43: ; preds = %2
%44 = add nsw i32 %4, 500
br label %47
45: ; preds = %2
%46 = add nsw i32 %4, 1000
br label %47
47: ; preds = %2, %20, %24, %22, %26, %39, %43, %45, %41, %37, %33, %35, %31, %15, %11, %13, %9
%48 = phi i8* [ %7, %9 ], [ %7, %11 ], [ %3, %13 ], [ %3, %15 ], [ %18, %20 ], [ %18, %22 ], [ %3, %24 ], [ %3, %26 ], [ %29, %31 ], [ %29, %33 ], [ %3, %35 ], [ %3, %37 ], [ %3, %39 ], [ %3, %41 ], [ %3, %43 ], [ %3, %45 ], [ %3, %2 ]
%49 = phi i32 [ %10, %9 ], [ %12, %11 ], [ %14, %13 ], [ %16, %15 ], [ %21, %20 ], [ %23, %22 ], [ %25, %24 ], [ %27, %26 ], [ %32, %31 ], [ %34, %33 ], [ %36, %35 ], [ %38, %37 ], [ %40, %39 ], [ %42, %41 ], [ %44, %43 ], [ %46, %45 ], [ %4, %2 ]
%50 = getelementptr inbounds i8, i8* %48, i64 1
br label %2
51: ; preds = %2
ret i32 %4
}