void expand(char s1[], char s2[]) {
  int left, right, i, j;
  i = j = 0;
  while (s1[i] != '\0') {
    switch (s1[i]) {
    case '-':
      if (s1[i - 1] != ' ') {
        left = s1[i - 1];
        right = s1[i + 1];
        for (left = left + 1; left <= right; left++, j++)
          s2[j] = left;
        i = i + 2;
      } else
        i++;
      break;
    default:
      s2[j] = s1[i];
      i++;
      j++;
      break;
    }
  }
  s2[j] = s1[i];
}


x86 assembly (clang, -O0):
<expand>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x20(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
je     120e <expand+0x10e>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,1),%al
sub    $0x2d,%al
jne    11e1 <expand+0xe1>
jmp    1147 <expand+0x47>
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x20,%eax
je     11d3 <expand+0xd3>
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
mov    %eax,-0x14(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
mov    %eax,-0x18(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x18(%rbp),%eax
jg     11c5 <expand+0xc5>
mov    -0x14(%rbp),%eax
mov    %al,%dl
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    1192 <expand+0x92>
mov    -0x1c(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x1c(%rbp)
jmp    11dc <expand+0xdc>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1209 <expand+0x109>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    111a <expand+0x1a>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
pop    %rbp
ret

x86 assembly (clang, -O2):
<expand>:
push   %r15
push   %r14
push   %r12
push   %rbx
lea    0x30(%rsi),%r8
xor    %ecx,%ecx
movdqa 0xeeb(%rip),%xmm2
movdqa 0xef3(%rip),%xmm3
movdqa 0xefb(%rip),%xmm7
movdqa 0xf02(%rip),%xmm9
movdqa 0xf0a(%rip),%xmm4
pcmpeqd %xmm14,%xmm14
movdqa 0xf0c(%rip),%xmm15
movdqa 0xf13(%rip),%xmm12
movdqa 0xf1a(%rip),%xmm13
movdqa 0xf22(%rip),%xmm1
xor    %edx,%edx
movslq %ecx,%rcx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movzbl (%rdi,%rcx,1),%eax
cmp    $0x2d,%al
jne    1320 <expand+0x220>
lea    -0x1(%rcx),%eax
cltq
movsbl (%rdi,%rax,1),%eax
add    $0x1,%rcx
cmp    $0x20,%eax
je     1170 <expand+0x70>
movslq %ecx,%rbx
movsbl (%rdi,%rbx,1),%r9d
cmp    %r9b,%al
jge    135f <expand+0x25f>
movslq %edx,%rdx
mov    %eax,%r10d
not    %r10d
add    %r9d,%r10d
cmp    $0x1f,%r10d
jb     1350 <expand+0x250>
add    $0x1,%r10
mov    %r10,%r11
and    $0xffffffffffffffe0,%r11
movd   %eax,%xmm0
pshufd $0x0,%xmm0,%xmm8
movdqa %xmm8,%xmm6
paddd  %xmm2,%xmm6
movdqa %xmm8,%xmm2
paddd  %xmm3,%xmm2
movdqa %xmm8,%xmm5
movdqa %xmm7,%xmm11
paddd  %xmm7,%xmm5
movdqa %xmm9,%xmm10
paddd  %xmm9,%xmm8
lea    -0x20(%r11),%rbx
mov    %rbx,%r14
shr    $0x5,%r14
add    $0x1,%r14
test   %rbx,%rbx
je     1367 <expand+0x267>
mov    %r14,%r15
and    $0xfffffffffffffffe,%r15
lea    (%r8,%rdx,1),%r12
xor    %ebx,%ebx
nopl   0x0(%rax)
movdqa %xmm8,%xmm0
pand   %xmm4,%xmm0
movdqa %xmm5,%xmm7
pand   %xmm4,%xmm7
packuswb %xmm7,%xmm0
movdqa %xmm2,%xmm7
pand   %xmm4,%xmm7
movdqa %xmm6,%xmm3
pand   %xmm4,%xmm3
packuswb %xmm3,%xmm7
packuswb %xmm7,%xmm0
movdqa %xmm0,%xmm3
psubb  %xmm14,%xmm3
movdqa %xmm0,%xmm7
paddb  %xmm15,%xmm7
movdqu %xmm3,-0x30(%r12,%rbx,1)
movdqu %xmm7,-0x20(%r12,%rbx,1)
movdqa %xmm0,%xmm3
paddb  %xmm12,%xmm3
paddb  %xmm13,%xmm0
movdqu %xmm3,-0x10(%r12,%rbx,1)
movdqu %xmm0,(%r12,%rbx,1)
add    $0x40,%rbx
paddd  %xmm1,%xmm8
paddd  %xmm1,%xmm5
paddd  %xmm1,%xmm2
paddd  %xmm1,%xmm6
add    $0xfffffffffffffffe,%r15
jne    1220 <expand+0x120>
test   $0x1,%r14b
je     12ea <expand+0x1ea>
add    %rdx,%rbx
pand   %xmm4,%xmm8
pand   %xmm4,%xmm5
packuswb %xmm5,%xmm8
pand   %xmm4,%xmm2
pand   %xmm4,%xmm6
packuswb %xmm6,%xmm2
packuswb %xmm2,%xmm8
movdqa %xmm8,%xmm0
psubb  %xmm14,%xmm0
paddb  %xmm15,%xmm8
movdqu %xmm0,(%rsi,%rbx,1)
movdqu %xmm8,0x10(%rsi,%rbx,1)
add    %r11,%rdx
cmp    %r11,%r10
movdqa %xmm11,%xmm7
jne    1335 <expand+0x235>
movdqa 0xd01(%rip),%xmm2
movdqa 0xd09(%rip),%xmm3
movdqa %xmm10,%xmm9
add    $0x1,%ecx
jmp    1160 <expand+0x60>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movslq %edx,%rbx
test   %al,%al
je     1378 <expand+0x278>
mov    %al,(%rsi,%rbx,1)
add    $0x1,%ecx
add    $0x1,%edx
jmp    1160 <expand+0x60>
add    %r11d,%eax
movdqa 0xcc0(%rip),%xmm2
movdqa 0xcc8(%rip),%xmm3
movdqa %xmm10,%xmm9
nopl   (%rax)
add    $0x1,%eax
mov    %al,(%rsi,%rdx,1)
add    $0x1,%rdx
cmp    %eax,%r9d
jne    1350 <expand+0x250>
add    $0x1,%ecx
jmp    1160 <expand+0x60>
xor    %ebx,%ebx
test   $0x1,%r14b
jne    12ad <expand+0x1ad>
jmp    12ea <expand+0x1ea>
movb   $0x0,(%rsi,%rbx,1)
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

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

LLVM IR (-O2):
define void @expand(i8* nocapture %0, i8* nocapture writeonly %1) {
br label %3
3: ; preds = %108, %2
%4 = phi i32 [ 0, %2 ], [ %109, %108 ]
%5 = phi i32 [ 0, %2 ], [ %110, %108 ]
br label %6
6: ; preds = %3, %11
%7 = phi i32 [ %17, %11 ], [ %4, %3 ]
%8 = sext i32 %7 to i64
%9 = getelementptr inbounds i8, i8* %0, i64 %8
%10 = load i8, i8* %9
switch i8 %10, label %111 [
i8 0, label %116
i8 45, label %11
]
11: ; preds = %6
%12 = add nsw i32 %7, -1
%13 = sext i32 %12 to i64
%14 = getelementptr inbounds i8, i8* %0, i64 %13
%15 = load i8, i8* %14
%16 = icmp eq i8 %15, 32
%17 = add nsw i32 %7, 1
br i1 %16, label %6, label %18
18: ; preds = %11
%19 = sext i32 %17 to i64
%20 = getelementptr inbounds i8, i8* %0, i64 %19
%21 = load i8, i8* %20
%22 = sext i8 %21 to i32
%23 = icmp slt i8 %15, %21
br i1 %23, label %24, label %105
24: ; preds = %18
%25 = sext i8 %15 to i32
%26 = sext i32 %5 to i64
%27 = xor i32 %25, -1
%28 = add nsw i32 %27, %22
%29 = zext i32 %28 to i64
%30 = add nuw nsw i64 %29, 1
%31 = icmp ult i32 %28, 31
br i1 %31, label %91, label %32
32: ; preds = %24
%33 = and i64 %30, 8589934560
%34 = add nsw i64 %33, %26
%35 = trunc i64 %33 to i32
%36 = add i32 %25, %35
%37 = insertelement <16 x i32> poison, i32 %25, i64 0
%38 = shufflevector <16 x i32> %37, <16 x i32> poison, <16 x i32> zeroinitializer
%39 = add <16 x i32> %38, <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
%40 = add nsw i64 %33, -32
%41 = lshr exact i64 %40, 5
%42 = add nuw nsw i64 %41, 1
%43 = and i64 %42, 1
%44 = icmp eq i64 %40, 0
br i1 %44, label %75, label %45
45: ; preds = %32
%46 = and i64 %42, 1152921504606846974
br label %47
47: ; preds = %47, %45
%48 = phi i64 [ 0, %45 ], [ %71, %47 ]
%49 = phi <16 x i32> [ %39, %45 ], [ %72, %47 ]
%50 = phi i64 [ 0, %45 ], [ %73, %47 ]
%51 = add i64 %48, %26
%52 = trunc <16 x i32> %49 to <16 x i8>
%53 = add <16 x i8> %52, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
%54 = trunc <16 x i32> %49 to <16 x i8>
%55 = add <16 x i8> %54, <i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17>
%56 = getelementptr inbounds i8, i8* %1, i64 %51
%57 = bitcast i8* %56 to <16 x i8>*
store <16 x i8> %53, <16 x i8>* %57
%58 = getelementptr inbounds i8, i8* %56, i64 16
%59 = bitcast i8* %58 to <16 x i8>*
store <16 x i8> %55, <16 x i8>* %59
%60 = or i64 %48, 32
%61 = add <16 x i32> %49, <i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32, i32 32>
%62 = add i64 %60, %26
%63 = trunc <16 x i32> %61 to <16 x i8>
%64 = add <16 x i8> %63, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
%65 = trunc <16 x i32> %61 to <16 x i8>
%66 = add <16 x i8> %65, <i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17>
%67 = getelementptr inbounds i8, i8* %1, i64 %62
%68 = bitcast i8* %67 to <16 x i8>*
store <16 x i8> %64, <16 x i8>* %68
%69 = getelementptr inbounds i8, i8* %67, i64 16
%70 = bitcast i8* %69 to <16 x i8>*
store <16 x i8> %66, <16 x i8>* %70
%71 = add nuw i64 %48, 64
%72 = add <16 x i32> %49, <i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64, i32 64>
%73 = add i64 %50, 2
%74 = icmp eq i64 %73, %46
br i1 %74, label %75, label %47
75: ; preds = %47, %32
%76 = phi i64 [ 0, %32 ], [ %71, %47 ]
%77 = phi <16 x i32> [ %39, %32 ], [ %72, %47 ]
%78 = icmp eq i64 %43, 0
br i1 %78, label %89, label %79
79: ; preds = %75
%80 = add i64 %76, %26
%81 = trunc <16 x i32> %77 to <16 x i8>
%82 = add <16 x i8> %81, <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
%83 = trunc <16 x i32> %77 to <16 x i8>
%84 = add <16 x i8> %83, <i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17, i8 17>
%85 = getelementptr inbounds i8, i8* %1, i64 %80
%86 = bitcast i8* %85 to <16 x i8>*
store <16 x i8> %82, <16 x i8>* %86
%87 = getelementptr inbounds i8, i8* %85, i64 16
%88 = bitcast i8* %87 to <16 x i8>*
store <16 x i8> %84, <16 x i8>* %88
br label %89
89: ; preds = %75, %79
%90 = icmp eq i64 %30, %33
br i1 %90, label %102, label %91
91: ; preds = %24, %89
%92 = phi i64 [ %26, %24 ], [ %34, %89 ]
%93 = phi i32 [ %25, %24 ], [ %36, %89 ]
br label %94
94: ; preds = %91, %94
%95 = phi i64 [ %100, %94 ], [ %92, %91 ]
%96 = phi i32 [ %97, %94 ], [ %93, %91 ]
%97 = add nsw i32 %96, 1
%98 = trunc i32 %97 to i8
%99 = getelementptr inbounds i8, i8* %1, i64 %95
store i8 %98, i8* %99
%100 = add nsw i64 %95, 1
%101 = icmp eq i32 %97, %22
br i1 %101, label %102, label %94
102: ; preds = %94, %89
%103 = phi i64 [ %34, %89 ], [ %100, %94 ]
%104 = trunc i64 %103 to i32
br label %105
105: ; preds = %102, %18
%106 = phi i32 [ %5, %18 ], [ %104, %102 ]
%107 = add nsw i32 %7, 2
br label %108
108: ; preds = %105, %111
%109 = phi i32 [ %114, %111 ], [ %107, %105 ]
%110 = phi i32 [ %115, %111 ], [ %106, %105 ]
br label %3
111: ; preds = %6
%112 = sext i32 %5 to i64
%113 = getelementptr inbounds i8, i8* %1, i64 %112
store i8 %10, i8* %113
%114 = add nsw i32 %7, 1
%115 = add nsw i32 %5, 1
br label %108
116: ; preds = %6
%117 = sext i32 %5 to i64
%118 = getelementptr inbounds i8, i8* %1, i64 %117
store i8 0, i8* %118
ret void
}