int stbi__shiftsigned(int v, int shift, int bits) {
  int result;
  int z = 0;
  if (shift < 0)
    v <<= -shift;
  else
    v >>= shift;
  result = v;
  z = bits;
  while (z < 8) {
    result += v >> z;
    z += bits;
  }
  return result;
}


x86 assembly (clang, -O0):
<stbi__shiftsigned>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
movl   $0x0,-0x14(%rbp)
cmpl   $0x0,-0x8(%rbp)
jge    1130 <stbi__shiftsigned+0x30>
xor    %ecx,%ecx
sub    -0x8(%rbp),%ecx
mov    -0x4(%rbp),%eax
shl    %cl,%eax
mov    %eax,-0x4(%rbp)
jmp    113b <stbi__shiftsigned+0x3b>
mov    -0x8(%rbp),%ecx
mov    -0x4(%rbp),%eax
sar    %cl,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x8,-0x14(%rbp)
jge    116d <stbi__shiftsigned+0x6d>
mov    -0x4(%rbp),%eax
mov    -0x14(%rbp),%ecx
sar    %cl,%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0xc(%rbp),%eax
add    -0x14(%rbp),%eax
mov    %eax,-0x14(%rbp)
jmp    1147 <stbi__shiftsigned+0x47>
mov    -0x10(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<stbi__shiftsigned>:
mov    %esi,%eax
mov    %eax,%ecx
neg    %cl
mov    %edi,%esi
shl    %cl,%esi
mov    %eax,%ecx
sar    %cl,%edi
test   %eax,%eax
cmovs  %esi,%edi
cmp    $0x7,%edx
jg     140f <stbi__shiftsigned+0x30f>
mov    %edx,%r10d
lea    (%r10,%r10,1),%ecx
cmp    $0x9,%ecx
mov    $0x8,%eax
cmovge %ecx,%eax
xor    %esi,%esi
cmp    $0x8,%ecx
setl   %sil
lea    (%rsi,%r10,2),%ecx
sub    %ecx,%eax
xor    %edx,%edx
div    %r10d
lea    (%rax,%rsi,1),%r8d
add    $0x1,%r8d
mov    %r10d,%ecx
mov    %edi,%eax
cmp    $0x8,%r8d
jb     1400 <stbi__shiftsigned+0x300>
mov    %r8d,%ecx
and    $0xfffffff8,%ecx
movd   %r10d,%xmm0
pshufd $0x0,%xmm0,%xmm8
movdqa 0xe8e(%rip),%xmm1
pmuludq %xmm8,%xmm1
pshufd $0xe8,%xmm1,%xmm1
movdqa 0xe8c(%rip),%xmm2
pmuludq %xmm8,%xmm2
pshufd $0xe8,%xmm2,%xmm4
punpckldq %xmm1,%xmm4
paddd  %xmm8,%xmm4
pslld  $0x2,%xmm8
movd   %edi,%xmm2
pshufd $0x0,%xmm2,%xmm10
lea    -0x8(%rcx),%eax
mov    %eax,%r9d
shr    $0x3,%r9d
add    $0x1,%r9d
test   %eax,%eax
je     1412 <stbi__shiftsigned+0x312>
mov    %r9d,%eax
and    $0xfffffffe,%eax
xor    %edx,%edx
pxor   %xmm3,%xmm3
nopl   0x0(%rax)
pshuflw $0xfe,%xmm4,%xmm5
movdqa %xmm10,%xmm6
psrad  %xmm5,%xmm6
pshuflw $0x54,%xmm4,%xmm7
movdqa %xmm10,%xmm5
psrad  %xmm7,%xmm5
pshufd $0xee,%xmm4,%xmm7
pshuflw $0xfe,%xmm7,%xmm9
movdqa %xmm10,%xmm1
psrad  %xmm9,%xmm1
paddd  %xmm8,%xmm4
pshuflw $0x54,%xmm7,%xmm7
movdqa %xmm10,%xmm0
psrad  %xmm7,%xmm0
punpcklqdq %xmm6,%xmm5
punpckhqdq %xmm1,%xmm0
shufps $0xcc,%xmm0,%xmm5
paddd  %xmm2,%xmm5
pshuflw $0xfe,%xmm4,%xmm0
movdqa %xmm10,%xmm1
psrad  %xmm0,%xmm1
pshuflw $0x54,%xmm4,%xmm0
movdqa %xmm10,%xmm6
psrad  %xmm0,%xmm6
punpcklqdq %xmm1,%xmm6
pshufd $0xee,%xmm4,%xmm0
pshuflw $0xfe,%xmm0,%xmm1
movdqa %xmm10,%xmm2
psrad  %xmm1,%xmm2
pshuflw $0x54,%xmm0,%xmm0
movdqa %xmm10,%xmm1
psrad  %xmm0,%xmm1
punpckhqdq %xmm2,%xmm1
shufps $0xcc,%xmm1,%xmm6
paddd  %xmm8,%xmm4
pshuflw $0xfe,%xmm4,%xmm0
movdqa %xmm10,%xmm1
psrad  %xmm0,%xmm1
paddd  %xmm3,%xmm6
pshuflw $0x54,%xmm4,%xmm0
movdqa %xmm10,%xmm2
psrad  %xmm0,%xmm2
pshufd $0xee,%xmm4,%xmm0
pshuflw $0xfe,%xmm0,%xmm3
movdqa %xmm10,%xmm7
psrad  %xmm3,%xmm7
pshuflw $0x54,%xmm0,%xmm0
movdqa %xmm10,%xmm3
psrad  %xmm0,%xmm3
paddd  %xmm8,%xmm4
punpcklqdq %xmm1,%xmm2
punpckhqdq %xmm7,%xmm3
shufps $0xcc,%xmm3,%xmm2
paddd  %xmm5,%xmm2
pshuflw $0xfe,%xmm4,%xmm0
movdqa %xmm10,%xmm1
psrad  %xmm0,%xmm1
pshuflw $0x54,%xmm4,%xmm0
movdqa %xmm10,%xmm3
psrad  %xmm0,%xmm3
punpcklqdq %xmm1,%xmm3
pshufd $0xee,%xmm4,%xmm0
pshuflw $0xfe,%xmm0,%xmm1
movdqa %xmm10,%xmm5
psrad  %xmm1,%xmm5
pshuflw $0x54,%xmm0,%xmm0
movdqa %xmm10,%xmm1
psrad  %xmm0,%xmm1
punpckhqdq %xmm5,%xmm1
shufps $0xcc,%xmm1,%xmm3
paddd  %xmm6,%xmm3
paddd  %xmm8,%xmm4
add    $0x2,%edx
cmp    %eax,%edx
jne    11d0 <stbi__shiftsigned+0xd0>
test   $0x1,%r9b
je     13cf <stbi__shiftsigned+0x2cf>
pshuflw $0xfe,%xmm4,%xmm0
movdqa %xmm10,%xmm1
psrad  %xmm0,%xmm1
paddd  %xmm4,%xmm8
pshuflw $0x54,%xmm4,%xmm0
movdqa %xmm10,%xmm5
psrad  %xmm0,%xmm5
pshufd $0xee,%xmm4,%xmm0
pshuflw $0xfe,%xmm0,%xmm4
movdqa %xmm10,%xmm6
psrad  %xmm4,%xmm6
punpcklqdq %xmm1,%xmm5
pshuflw $0x54,%xmm0,%xmm0
movdqa %xmm10,%xmm1
psrad  %xmm0,%xmm1
punpckhqdq %xmm6,%xmm1
pshuflw $0xfe,%xmm8,%xmm0
movdqa %xmm10,%xmm4
psrad  %xmm0,%xmm4
shufps $0xcc,%xmm1,%xmm5
pshuflw $0x54,%xmm8,%xmm0
movdqa %xmm10,%xmm1
psrad  %xmm0,%xmm1
pshufd $0xee,%xmm8,%xmm0
pshuflw $0xfe,%xmm0,%xmm6
movdqa %xmm10,%xmm7
psrad  %xmm6,%xmm7
paddd  %xmm5,%xmm2
pshuflw $0x54,%xmm0,%xmm0
psrad  %xmm0,%xmm10
punpcklqdq %xmm4,%xmm1
punpckhqdq %xmm7,%xmm10
shufps $0xcc,%xmm10,%xmm1
paddd  %xmm1,%xmm3
paddd  %xmm3,%xmm2
pshufd $0xee,%xmm2,%xmm0
paddd  %xmm2,%xmm0
pshufd $0x55,%xmm0,%xmm1
paddd  %xmm0,%xmm1
movd   %xmm1,%eax
cmp    %ecx,%r8d
je     140e <stbi__shiftsigned+0x30e>
imul   %r10d,%ecx
add    %r10d,%ecx
cs nopw 0x0(%rax,%rax,1)
nop
mov    %edi,%edx
sar    %cl,%edx
add    %edx,%eax
add    %r10d,%ecx
cmp    $0x8,%ecx
jl     1400 <stbi__shiftsigned+0x300>
ret
mov    %edi,%eax
ret
pxor   %xmm3,%xmm3
test   $0x1,%r9b
jne    132f <stbi__shiftsigned+0x22f>
jmp    13cf <stbi__shiftsigned+0x2cf>

LLVM IR (-O0):
define i32 @stbi__shiftsigned(i32 %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i32 %0, i32* %4
store i32 %1, i32* %5
store i32 %2, i32* %6
store i32 0, i32* %8
%9 = load i32, i32* %5
%10 = icmp slt i32 %9, 0
br i1 %10, label %11, label %16
11: ; preds = %3
%12 = load i32, i32* %5
%13 = sub nsw i32 0, %12
%14 = load i32, i32* %4
%15 = shl i32 %14, %13
store i32 %15, i32* %4
br label %20
16: ; preds = %3
%17 = load i32, i32* %5
%18 = load i32, i32* %4
%19 = ashr i32 %18, %17
store i32 %19, i32* %4
br label %20
20: ; preds = %16, %11
%21 = load i32, i32* %4
store i32 %21, i32* %7
%22 = load i32, i32* %6
store i32 %22, i32* %8
br label %23
23: ; preds = %26, %20
%24 = load i32, i32* %8
%25 = icmp slt i32 %24, 8
br i1 %25, label %26, label %35
26: ; preds = %23
%27 = load i32, i32* %4
%28 = load i32, i32* %8
%29 = ashr i32 %27, %28
%30 = load i32, i32* %7
%31 = add nsw i32 %30, %29
store i32 %31, i32* %7
%32 = load i32, i32* %6
%33 = load i32, i32* %8
%34 = add nsw i32 %33, %32
store i32 %34, i32* %8
br label %23
35: ; preds = %23
%36 = load i32, i32* %7
ret i32 %36
}

LLVM IR (-O2):
define i32 @stbi__shiftsigned(i32 %0, i32 %1, i32 %2) {
%4 = icmp slt i32 %1, 0
%5 = sub nsw i32 0, %1
%6 = shl i32 %0, %5
%7 = ashr i32 %0, %1
%8 = select i1 %4, i32 %6, i32 %7
%9 = icmp slt i32 %2, 8
br i1 %9, label %10, label %94
10: ; preds = %3
%11 = shl i32 %2, 1
%12 = call i32 @llvm.smax.i32(i32 %11, i32 8)
%13 = icmp slt i32 %11, 8
%14 = zext i1 %13 to i32
%15 = or i32 %11, %14
%16 = sub i32 %12, %15
%17 = udiv i32 %16, %2
%18 = add i32 %17, %14
%19 = add i32 %18, 1
%20 = icmp ult i32 %19, 8
br i1 %20, label %84, label %21
21: ; preds = %10
%22 = and i32 %19, -8
%23 = mul i32 %22, %2
%24 = add i32 %23, %2
%25 = insertelement <4 x i32> poison, i32 %2, i64 0
%26 = shufflevector <4 x i32> %25, <4 x i32> poison, <4 x i32> zeroinitializer
%27 = insertelement <4 x i32> poison, i32 %2, i64 0
%28 = shufflevector <4 x i32> %27, <4 x i32> poison, <4 x i32> zeroinitializer
%29 = mul <4 x i32> %28, <i32 0, i32 1, i32 2, i32 3>
%30 = add <4 x i32> %26, %29
%31 = shl i32 %2, 2
%32 = insertelement <4 x i32> poison, i32 %31, i64 0
%33 = shufflevector <4 x i32> %32, <4 x i32> poison, <4 x i32> zeroinitializer
%34 = insertelement <4 x i32> <i32 poison, i32 0, i32 0, i32 0>, i32 %8, i64 0
%35 = insertelement <4 x i32> poison, i32 %8, i64 0
%36 = shufflevector <4 x i32> %35, <4 x i32> poison, <4 x i32> zeroinitializer
%37 = insertelement <4 x i32> poison, i32 %8, i64 0
%38 = shufflevector <4 x i32> %37, <4 x i32> poison, <4 x i32> zeroinitializer
%39 = add i32 %22, -8
%40 = lshr exact i32 %39, 3
%41 = add nuw nsw i32 %40, 1
%42 = and i32 %41, 1
%43 = icmp eq i32 %39, 0
br i1 %43, label %65, label %44
44: ; preds = %21
%45 = and i32 %41, 1073741822
br label %46
46: ; preds = %46, %44
%47 = phi <4 x i32> [ %30, %44 ], [ %62, %46 ]
%48 = phi <4 x i32> [ %34, %44 ], [ %60, %46 ]
%49 = phi <4 x i32> [ zeroinitializer, %44 ], [ %61, %46 ]
%50 = phi i32 [ 0, %44 ], [ %63, %46 ]
%51 = add <4 x i32> %47, %33
%52 = ashr <4 x i32> %36, %47
%53 = ashr <4 x i32> %38, %51
%54 = add <4 x i32> %52, %48
%55 = add <4 x i32> %53, %49
%56 = add <4 x i32> %51, %33
%57 = add <4 x i32> %56, %33
%58 = ashr <4 x i32> %36, %56
%59 = ashr <4 x i32> %38, %57
%60 = add <4 x i32> %58, %54
%61 = add <4 x i32> %59, %55
%62 = add <4 x i32> %57, %33
%63 = add i32 %50, 2
%64 = icmp eq i32 %63, %45
br i1 %64, label %65, label %46
65: ; preds = %46, %21
%66 = phi <4 x i32> [ undef, %21 ], [ %60, %46 ]
%67 = phi <4 x i32> [ undef, %21 ], [ %61, %46 ]
%68 = phi <4 x i32> [ %30, %21 ], [ %62, %46 ]
%69 = phi <4 x i32> [ %34, %21 ], [ %60, %46 ]
%70 = phi <4 x i32> [ zeroinitializer, %21 ], [ %61, %46 ]
%71 = icmp eq i32 %42, 0
br i1 %71, label %78, label %72
72: ; preds = %65
%73 = add <4 x i32> %68, %33
%74 = ashr <4 x i32> %36, %68
%75 = ashr <4 x i32> %38, %73
%76 = add <4 x i32> %74, %69
%77 = add <4 x i32> %75, %70
br label %78
78: ; preds = %65, %72
%79 = phi <4 x i32> [ %66, %65 ], [ %76, %72 ]
%80 = phi <4 x i32> [ %67, %65 ], [ %77, %72 ]
%81 = add <4 x i32> %80, %79
%82 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %81)
%83 = icmp eq i32 %19, %22
br i1 %83, label %94, label %84
84: ; preds = %10, %78
%85 = phi i32 [ %2, %10 ], [ %24, %78 ]
%86 = phi i32 [ %8, %10 ], [ %82, %78 ]
br label %87
87: ; preds = %84, %87
%88 = phi i32 [ %92, %87 ], [ %85, %84 ]
%89 = phi i32 [ %91, %87 ], [ %86, %84 ]
%90 = ashr i32 %8, %88
%91 = add nsw i32 %90, %89
%92 = add nsw i32 %88, %2
%93 = icmp slt i32 %92, 8
br i1 %93, label %87, label %94
94: ; preds = %87, %78, %3
%95 = phi i32 [ %8, %3 ], [ %82, %78 ], [ %91, %87 ]
ret i32 %95
}