void b_leftShiftDigits(unsigned *digits, int size, int n) {
  if (n >= size)
    return;
  int i = n;
  for (; i < size; i++)
    digits[i - n] = digits[i];
  for (i = size - n; i < size; i++)
    digits[i] = 0;
}


x86 assembly (clang, -O0):
<b_leftShiftDigits>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0xc(%rbp),%eax
jl     111f <b_leftShiftDigits+0x1f>
jmp    118c <b_leftShiftDigits+0x8c>
mov    -0x10(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    115a <b_leftShiftDigits+0x5a>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
sub    -0x10(%rbp),%ecx
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1125 <b_leftShiftDigits+0x25>
mov    -0xc(%rbp),%eax
sub    -0x10(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    118c <b_leftShiftDigits+0x8c>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
movl   $0x0,(%rax,%rcx,4)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1163 <b_leftShiftDigits+0x63>
pop    %rbp
ret

x86 assembly (clang, -O2):
<b_leftShiftDigits>:
push   %r15
push   %r14
push   %rbx
mov    %esi,%r8d
sub    %edx,%r8d
jle    12cf <b_leftShiftDigits+0x1bf>
movslq %edx,%r9
movslq %esi,%r14
mov    %r14,%r10
sub    %r9,%r10
mov    %r9,%rax
cmp    $0x8,%r10
jb     1229 <b_leftShiftDigits+0x119>
lea    (%rdi,%r14,4),%rax
cmp    %rdi,%rax
jbe    1157 <b_leftShiftDigits+0x47>
lea    (%rdi,%r10,4),%rcx
lea    (%rdi,%r9,4),%rbx
mov    %r9,%rax
cmp    %rcx,%rbx
jb     1229 <b_leftShiftDigits+0x119>
mov    %r10,%rax
and    $0xfffffffffffffff8,%rax
lea    -0x8(%rax),%rcx
mov    %rcx,%r15
shr    $0x3,%r15
add    $0x1,%r15
mov    %r15d,%r11d
and    $0x3,%r11d
cmp    $0x18,%rcx
jae    117e <b_leftShiftDigits+0x6e>
xor    %ecx,%ecx
jmp    11e8 <b_leftShiftDigits+0xd8>
and    $0xfffffffffffffffc,%r15
lea    (%rdi,%r9,4),%rbx
add    $0x70,%rbx
xor    %ecx,%ecx
nopl   0x0(%rax)
movups -0x70(%rbx,%rcx,4),%xmm0
movups -0x60(%rbx,%rcx,4),%xmm1
movups %xmm0,(%rdi,%rcx,4)
movups %xmm1,0x10(%rdi,%rcx,4)
movups -0x50(%rbx,%rcx,4),%xmm0
movups -0x40(%rbx,%rcx,4),%xmm1
movups %xmm0,0x20(%rdi,%rcx,4)
movups %xmm1,0x30(%rdi,%rcx,4)
movups -0x30(%rbx,%rcx,4),%xmm0
movups -0x20(%rbx,%rcx,4),%xmm1
movups %xmm0,0x40(%rdi,%rcx,4)
movups %xmm1,0x50(%rdi,%rcx,4)
movups -0x10(%rbx,%rcx,4),%xmm0
movups (%rbx,%rcx,4),%xmm1
movups %xmm0,0x60(%rdi,%rcx,4)
movups %xmm1,0x70(%rdi,%rcx,4)
add    $0x20,%rcx
add    $0xfffffffffffffffc,%r15
jne    1190 <b_leftShiftDigits+0x80>
test   %r11,%r11
je     121d <b_leftShiftDigits+0x10d>
lea    (%rdi,%rcx,4),%r15
add    $0x10,%r15
lea    (%r15,%r9,4),%rbx
shl    $0x5,%r11
xor    %ecx,%ecx
nop
movups -0x10(%rbx,%rcx,1),%xmm0
movups (%rbx,%rcx,1),%xmm1
movups %xmm0,-0x10(%r15,%rcx,1)
movups %xmm1,(%r15,%rcx,1)
add    $0x20,%rcx
cmp    %rcx,%r11
jne    1200 <b_leftShiftDigits+0xf0>
cmp    %rax,%r10
je     12a7 <b_leftShiftDigits+0x197>
add    %r9,%rax
mov    %esi,%ebx
sub    %eax,%ebx
mov    %rax,%r10
not    %r10
add    %r14,%r10
and    $0x3,%rbx
je     1261 <b_leftShiftDigits+0x151>
lea    0x0(,%r9,4),%r11
mov    %rdi,%r15
sub    %r11,%r15
nopw   0x0(%rax,%rax,1)
mov    (%rdi,%rax,4),%ecx
mov    %ecx,(%r15,%rax,4)
add    $0x1,%rax
add    $0xffffffffffffffff,%rbx
jne    1250 <b_leftShiftDigits+0x140>
cmp    $0x3,%r10
jb     12a7 <b_leftShiftDigits+0x197>
mov    $0x3,%ecx
sub    %r9,%rcx
lea    (%rdi,%rcx,4),%rcx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    (%rdi,%rax,4),%ebx
mov    %ebx,-0xc(%rcx,%rax,4)
mov    0x4(%rdi,%rax,4),%ebx
mov    %ebx,-0x8(%rcx,%rax,4)
mov    0x8(%rdi,%rax,4),%ebx
mov    %ebx,-0x4(%rcx,%rax,4)
mov    0xc(%rdi,%rax,4),%ebx
mov    %ebx,(%rcx,%rax,4)
add    $0x4,%rax
cmp    %rax,%r14
jne    1280 <b_leftShiftDigits+0x170>
test   %edx,%edx
jle    12cf <b_leftShiftDigits+0x1bf>
movslq %r8d,%rax
lea    (%rdi,%rax,4),%rdi
add    $0x1,%eax
cmp    %eax,%esi
cmovg  %esi,%eax
add    %edx,%eax
not    %esi
add    %eax,%esi
lea    0x4(,%rsi,4),%rdx
xor    %esi,%esi
call   1030 <memset@plt>
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @b_leftShiftDigits(i32* %0, i32 %1, i32 %2) {
%4 = alloca i32*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
store i32* %0, i32** %4
store i32 %1, i32* %5
store i32 %2, i32* %6
%8 = load i32, i32* %6
%9 = load i32, i32* %5
%10 = icmp sge i32 %8, %9
br i1 %10, label %11, label %12
11: ; preds = %3
br label %49
12: ; preds = %3
%13 = load i32, i32* %6
store i32 %13, i32* %7
br label %14
14: ; preds = %30, %12
%15 = load i32, i32* %7
%16 = load i32, i32* %5
%17 = icmp slt i32 %15, %16
br i1 %17, label %18, label %33
18: ; preds = %14
%19 = load i32*, i32** %4
%20 = load i32, i32* %7
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds i32, i32* %19, i64 %21
%23 = load i32, i32* %22
%24 = load i32*, i32** %4
%25 = load i32, i32* %7
%26 = load i32, i32* %6
%27 = sub nsw i32 %25, %26
%28 = sext i32 %27 to i64
%29 = getelementptr inbounds i32, i32* %24, i64 %28
store i32 %23, i32* %29
br label %30
30: ; preds = %18
%31 = load i32, i32* %7
%32 = add nsw i32 %31, 1
store i32 %32, i32* %7
br label %14
33: ; preds = %14
%34 = load i32, i32* %5
%35 = load i32, i32* %6
%36 = sub nsw i32 %34, %35
store i32 %36, i32* %7
br label %37
37: ; preds = %46, %33
%38 = load i32, i32* %7
%39 = load i32, i32* %5
%40 = icmp slt i32 %38, %39
br i1 %40, label %41, label %49
41: ; preds = %37
%42 = load i32*, i32** %4
%43 = load i32, i32* %7
%44 = sext i32 %43 to i64
%45 = getelementptr inbounds i32, i32* %42, i64 %44
store i32 0, i32* %45
br label %46
46: ; preds = %41
%47 = load i32, i32* %7
%48 = add nsw i32 %47, 1
store i32 %48, i32* %7
br label %37
49: ; preds = %11, %37
ret void
}

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