void mul2(char *in, char *out) {
  int nval = 0, aval, i = 0;
  if (((*in - '0') * 2) >= 10) {
    *out = '1';
    ++out;
  }
  while (*in != '\0') {
    ++in;
    ++out;
    ++i;
  }
  *out = '\0';
  while (i) {
    --in;
    --out;
    --i;
    aval = nval;
    if (((*in - '0') * 2) >= 10) {
      *out = (*in - '5') * 2 + aval + '0';
      nval = 1;
    } else {
      *out = (*in - '0') * 2 + aval + '0';
      nval = 0;
    }
  }
  return;
}


x86 assembly (clang, -O0):
<mul2>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
sub    $0x30,%eax
shl    $0x1,%eax
cmp    $0xa,%eax
jl     1143 <mul2+0x43>
mov    -0x10(%rbp),%rax
movb   $0x31,(%rax)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1148 <mul2+0x48>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x0,%eax
je     117e <mul2+0x7e>
mov    -0x8(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1148 <mul2+0x48>
mov    -0x10(%rbp),%rax
movb   $0x0,(%rax)
cmpl   $0x0,-0x1c(%rbp)
je     121a <mul2+0x11a>
mov    -0x8(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x8(%rbp)
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x10(%rbp)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
sub    $0x30,%eax
shl    $0x1,%eax
cmp    $0xa,%eax
jl     11f3 <mul2+0xf3>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
sub    $0x35,%eax
shl    $0x1,%eax
add    -0x18(%rbp),%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
movl   $0x1,-0x14(%rbp)
jmp    1215 <mul2+0x115>
mov    -0x8(%rbp),%rax
movsbl (%rax),%eax
sub    $0x30,%eax
shl    $0x1,%eax
add    -0x18(%rbp),%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x10(%rbp),%rax
mov    %cl,(%rax)
movl   $0x0,-0x14(%rbp)
jmp    1185 <mul2+0x85>
pop    %rbp
ret

x86 assembly (clang, -O2):
<mul2>:
push   %r14
push   %rbx
mov    (%rdi),%al
cmp    $0x35,%al
jl     1112 <mul2+0x12>
movb   $0x31,(%rsi)
add    $0x1,%rsi
mov    (%rdi),%al
test   %al,%al
je     1170 <mul2+0x70>
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
cmpb   $0x0,0x1(%rdi,%rcx,1)
lea    0x1(%rcx),%rcx
jne    1120 <mul2+0x20>
lea    (%rsi,%rcx,1),%r14
movb   $0x0,(%rsi,%rcx,1)
lea    -0x1(%rcx),%eax
add    %rcx,%rdi
cmp    $0xe,%eax
jbe    1154 <mul2+0x54>
mov    %r14,%rax
sub    %rcx,%rax
mov    %rdi,%r10
sub    %rcx,%r10
cmp    %rdi,%rax
jae    1178 <mul2+0x78>
cmp    %r14,%r10
jae    1178 <mul2+0x78>
xor    %edx,%edx
test   $0x1,%cl
jne    12f1 <mul2+0x1f1>
mov    %ecx,%r8d
cmp    $0x1,%ecx
jne    132e <mul2+0x22e>
jmp    1392 <mul2+0x292>
movb   $0x0,(%rsi)
jmp    1392 <mul2+0x292>
mov    %ecx,%r9d
and    $0xfffffff0,%r9d
mov    %r9d,%r8d
neg    %r8d
add    %rcx,%r8
mov    %r9,%r11
neg    %r11
mov    %r10,%rdi
sub    %r9,%rdi
add    %rcx,%rdi
mov    %rsi,%r14
sub    %r9,%r14
add    %rcx,%r14
pxor   %xmm0,%xmm0
xor    %edx,%edx
movdqa 0xe51(%rip),%xmm8
movdqa 0xe58(%rip),%xmm9
movdqa 0xe5f(%rip),%xmm10
movdqa 0xe67(%rip),%xmm4
movdqa 0xe6f(%rip),%xmm5
pxor   %xmm6,%xmm6
cs nopw 0x0(%rax,%rax,1)
nop
movdqa %xmm6,%xmm7
lea    (%r10,%rdx,1),%rax
movdqu -0x10(%rcx,%rax,1),%xmm1
movdqa %xmm1,%xmm6
punpcklbw %xmm0,%xmm6
pshufd $0x4e,%xmm6,%xmm6
pshuflw $0x1b,%xmm6,%xmm6
pshufhw $0x1b,%xmm6,%xmm2
movdqa %xmm1,%xmm6
punpckhbw %xmm0,%xmm6
pshufd $0x4e,%xmm6,%xmm6
pshuflw $0x1b,%xmm6,%xmm6
pshufhw $0x1b,%xmm6,%xmm6
packuswb %xmm2,%xmm6
pcmpgtb %xmm8,%xmm6
paddb  %xmm1,%xmm1
movdqa %xmm1,%xmm2
punpcklbw %xmm0,%xmm2
pshufd $0x4e,%xmm2,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
punpckhbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
packuswb %xmm2,%xmm1
movdqa %xmm6,%xmm2
pandn  %xmm9,%xmm2
movdqa %xmm6,%xmm3
pand   %xmm10,%xmm3
por    %xmm2,%xmm3
paddb  %xmm1,%xmm3
pand   %xmm4,%xmm6
movdqa %xmm6,%xmm1
pslldq $0x1,%xmm1
psrldq $0xf,%xmm7
por    %xmm1,%xmm7
por    %xmm5,%xmm7
paddb  %xmm3,%xmm7
movdqa %xmm7,%xmm1
punpcklbw %xmm0,%xmm1
pshufd $0x4e,%xmm1,%xmm1
pshuflw $0x1b,%xmm1,%xmm1
pshufhw $0x1b,%xmm1,%xmm1
punpckhbw %xmm0,%xmm7
pshufd $0x4e,%xmm7,%xmm2
pshuflw $0x1b,%xmm2,%xmm2
pshufhw $0x1b,%xmm2,%xmm2
packuswb %xmm1,%xmm2
lea    (%rsi,%rdx,1),%rax
movdqu %xmm2,-0x10(%rcx,%rax,1)
add    $0xfffffffffffffff0,%rdx
cmp    %rdx,%r11
jne    11e0 <mul2+0xe0>
cmp    %r9,%rcx
je     1392 <mul2+0x292>
pextrw $0x7,%xmm6,%edx
shr    $0x8,%edx
mov    %r8d,%ecx
test   $0x1,%cl
je     115f <mul2+0x5f>
mov    -0x1(%rdi),%al
add    $0xffffffffffffffff,%rdi
lea    (%rax,%rax,1),%esi
cmp    $0x35,%al
setge  %r9b
mov    $0x96,%r8d
mov    $0xa0,%eax
cmovge %r8d,%eax
or     %dl,%sil
add    %al,%sil
add    $0x30,%sil
mov    %sil,-0x1(%r14)
add    $0xffffffffffffffff,%r14
lea    -0x1(%rcx),%r8d
mov    %r9d,%edx
cmp    $0x1,%ecx
je     1392 <mul2+0x292>
neg    %r8d
xor    %ecx,%ecx
mov    $0x96,%r9d
nopl   0x0(%rax)
movzbl -0x1(%rdi,%rcx,1),%ebx
lea    (%rbx,%rbx,1),%esi
cmp    $0x35,%bl
setge  %bl
mov    $0xa0,%eax
cmovge %r9d,%eax
or     $0x30,%dl
add    %sil,%dl
add    %al,%dl
mov    %dl,-0x1(%r14,%rcx,1)
movzbl -0x2(%rdi,%rcx,1),%eax
lea    (%rax,%rax,1),%esi
cmp    $0x35,%al
setge  %dl
mov    $0xa0,%eax
cmovge %r9d,%eax
or     %bl,%sil
add    %al,%sil
add    $0x30,%sil
mov    %sil,-0x2(%r14,%rcx,1)
add    $0xfffffffffffffffe,%rcx
cmp    %ecx,%r8d
jne    1340 <mul2+0x240>
pop    %rbx
pop    %r14
ret

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

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