int shiftleft(unsigned char *a, int a_len) {
  int i, front, lastfront;
  if (a_len == 0 && ((a[0] & 0x80) != 0x80)) {
    a[0] <<= 1;
    return 0;
  }
  if (a[0] & 0x80)
    lastfront = 1;
  else
    lastfront = 0;
  a[0] <<= 1;
  for (i = 1; i <= a_len; i++) {
    if (a[i] & 0x80)
      front = 1;
    else
      front = 0;
    a[i] <<= 1;
    if (lastfront == 1)
      a[i] |= 0x1;
    lastfront = front;
  }
  if (front) {
    a[i] = 1;
    a_len++;
  }
  return a_len;
}


x86 assembly (clang, -O0):
<shiftleft>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jne    1144 <shiftleft+0x44>
mov    -0x10(%rbp),%rax
movzbl (%rax),%eax
and    $0x80,%eax
cmp    $0x80,%eax
je     1144 <shiftleft+0x44>
mov    -0x10(%rbp),%rax
movzbl (%rax),%ecx
shl    $0x1,%ecx
mov    %cl,(%rax)
movl   $0x0,-0x4(%rbp)
jmp    121f <shiftleft+0x11f>
mov    -0x10(%rbp),%rax
movzbl (%rax),%eax
and    $0x80,%eax
cmp    $0x0,%eax
je     1165 <shiftleft+0x65>
movl   $0x1,-0x20(%rbp)
jmp    116c <shiftleft+0x6c>
movl   $0x0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movzbl (%rax),%ecx
shl    $0x1,%ecx
mov    %cl,(%rax)
movl   $0x1,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     11fa <shiftleft+0xfa>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0x80,%eax
cmp    $0x0,%eax
je     11b1 <shiftleft+0xb1>
movl   $0x1,-0x1c(%rbp)
jmp    11b8 <shiftleft+0xb8>
movl   $0x0,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
movzbl (%rax,%rcx,1),%edx
shl    $0x1,%edx
mov    %dl,(%rax,%rcx,1)
cmpl   $0x1,-0x20(%rbp)
jne    11e6 <shiftleft+0xe6>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
movzbl (%rax,%rcx,1),%edx
or     $0x1,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
mov    %eax,-0x20(%rbp)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    117f <shiftleft+0x7f>
cmpl   $0x0,-0x1c(%rbp)
je     1219 <shiftleft+0x119>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
movb   $0x1,(%rax,%rcx,1)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<shiftleft>:
mov    (%rdi),%r10b
test   %esi,%esi
je     1205 <shiftleft+0x105>
lea    (%r10,%r10,1),%eax
mov    %al,(%rdi)
test   %esi,%esi
jle    1213 <shiftleft+0x113>
mov    %esi,%r8d
lea    0x1(%r8),%r9
mov    $0x1,%ecx
cmp    $0x20,%esi
jb     11ce <shiftleft+0xce>
mov    %r8d,%eax
and    $0xffffffe0,%eax
lea    0x1(%rax),%rcx
movzbl %r10b,%edx
movd   %edx,%xmm1
pslldq $0xf,%xmm1
xor    %edx,%edx
movdqa 0xeb1(%rip),%xmm0
nop
movdqu 0x1(%rdi,%rdx,1),%xmm2
movdqa %xmm2,%xmm3
pslldq $0x1,%xmm3
psrldq $0xf,%xmm1
por    %xmm3,%xmm1
movdqa %xmm2,%xmm3
psrlw  $0x7,%xmm1
pand   %xmm0,%xmm1
paddb  %xmm2,%xmm2
por    %xmm1,%xmm2
movdqu 0x11(%rdi,%rdx,1),%xmm1
psrldq $0xf,%xmm3
movdqa %xmm1,%xmm4
pslldq $0x1,%xmm4
por    %xmm3,%xmm4
psrlw  $0x7,%xmm4
pand   %xmm0,%xmm4
movdqa %xmm1,%xmm3
paddb  %xmm1,%xmm3
por    %xmm4,%xmm3
movdqu %xmm2,0x1(%rdi,%rdx,1)
movdqu %xmm3,0x11(%rdi,%rdx,1)
add    $0x20,%rdx
cmp    %rdx,%rax
jne    1150 <shiftleft+0x50>
pextrw $0x7,%xmm1,%r10d
shr    $0x8,%r10d
cmp    %rax,%r8
je     11fd <shiftleft+0xfd>
mov    %r10d,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movzbl (%rdi,%rcx,1),%r10d
lea    (%r10,%r10,1),%edx
shr    $0x7,%al
or     %dl,%al
mov    %al,(%rdi,%rcx,1)
add    $0x1,%rcx
mov    %r10d,%eax
cmp    %rcx,%r9
jne    11e0 <shiftleft+0xe0>
test   %r10b,%r10b
js     121a <shiftleft+0x11a>
mov    %esi,%eax
ret
lea    (%r10,%r10,1),%ecx
xor    %eax,%eax
mov    %cl,(%rdi)
test   %r10b,%r10b
js     1213 <shiftleft+0x113>
ret
mov    $0x1,%eax
jmp    121d <shiftleft+0x11d>
mov    %r9d,%eax
movb   $0x1,(%rdi,%rax,1)
add    $0x1,%esi
mov    %esi,%eax
ret

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

LLVM IR (-O2):
define i32 @shiftleft(i8* nocapture %0, i32 %1) {
%3 = icmp eq i32 %1, 0
%4 = load i8, i8* %0
br i1 %3, label %5, label %8
5: ; preds = %2
%6 = icmp sgt i8 %4, -1
%7 = shl i8 %4, 1
store i8 %7, i8* %0
br i1 %6, label %61, label %57
8: ; preds = %2
%9 = shl i8 %4, 1
store i8 %9, i8* %0
%10 = icmp slt i32 %1, 1
br i1 %10, label %57, label %11
11: ; preds = %8
%12 = add nuw i32 %1, 1
%13 = zext i32 %12 to i64
%14 = add nsw i64 %13, -1
%15 = icmp ult i64 %14, 32
br i1 %15, label %42, label %16
16: ; preds = %11
%17 = and i64 %14, -32
%18 = or i64 %17, 1
%19 = insertelement <16 x i8> poison, i8 %4, i64 15
br label %20
20: ; preds = %20, %16
%21 = phi i64 [ 0, %16 ], [ %36, %20 ]
%22 = phi <16 x i8> [ %19, %16 ], [ %29, %20 ]
%23 = or i64 %21, 1
%24 = getelementptr inbounds i8, i8* %0, i64 %23
%25 = bitcast i8* %24 to <16 x i8>*
%26 = load <16 x i8>, <16 x i8>* %25
%27 = getelementptr inbounds i8, i8* %24, i64 16
%28 = bitcast i8* %27 to <16 x i8>*
%29 = load <16 x i8>, <16 x i8>* %28
%30 = shufflevector <16 x i8> %22, <16 x i8> %26, <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>
%31 = shufflevector <16 x i8> %26, <16 x i8> %29, <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>
%32 = call <16 x i8> @llvm.fshl.v16i8(<16 x i8> %26, <16 x i8> %30, <16 x i8> <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>)
%33 = call <16 x i8> @llvm.fshl.v16i8(<16 x i8> %29, <16 x i8> %31, <16 x i8> <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>)
%34 = bitcast i8* %24 to <16 x i8>*
store <16 x i8> %32, <16 x i8>* %34
%35 = bitcast i8* %27 to <16 x i8>*
store <16 x i8> %33, <16 x i8>* %35
%36 = add nuw i64 %21, 32
%37 = icmp eq i64 %36, %17
br i1 %37, label %38, label %20
38: ; preds = %20
%39 = icmp eq i64 %14, %17
%40 = extractelement <16 x i8> %29, i64 15
%41 = extractelement <16 x i8> %29, i64 15
br i1 %39, label %53, label %42
42: ; preds = %11, %38
%43 = phi i64 [ %18, %38 ], [ 1, %11 ]
%44 = phi i8 [ %40, %38 ], [ %4, %11 ]
br label %45
45: ; preds = %42, %45
%46 = phi i64 [ %51, %45 ], [ %43, %42 ]
%47 = phi i8 [ %49, %45 ], [ %44, %42 ]
%48 = getelementptr inbounds i8, i8* %0, i64 %46
%49 = load i8, i8* %48
%50 = call i8 @llvm.fshl.i8(i8 %49, i8 %47, i8 1)
store i8 %50, i8* %48
%51 = add nuw nsw i64 %46, 1
%52 = icmp eq i64 %51, %13
br i1 %52, label %53, label %45
53: ; preds = %45, %38
%54 = phi i8 [ %41, %38 ], [ %49, %45 ]
%55 = icmp sgt i8 %54, -1
%56 = zext i32 %12 to i64
br i1 %55, label %61, label %57
57: ; preds = %5, %8, %53
%58 = phi i64 [ %56, %53 ], [ 1, %8 ], [ 1, %5 ]
%59 = getelementptr inbounds i8, i8* %0, i64 %58
store i8 1, i8* %59
%60 = add nsw i32 %1, 1
br label %61
61: ; preds = %5, %53, %57
%62 = phi i32 [ %60, %57 ], [ %1, %53 ], [ 0, %5 ]
ret i32 %62
}