void strshft(char *b, char *e, unsigned int s) {
  *(e + s) = *e;
  while (e != b) {
    *(e + s) = *e;
    --e;
  }
  *(b + s) = *b;
}


x86 assembly (clang, -O0):
<strshft>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%dl
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
cmp    -0x8(%rbp),%rax
je     114e <strshft+0x4e>
mov    -0x10(%rbp),%rax
mov    (%rax),%dl
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x10(%rbp)
jmp    111f <strshft+0x1f>
mov    -0x8(%rbp),%rax
mov    (%rax),%dl
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    %dl,(%rax,%rcx,1)
pop    %rbp
ret

x86 assembly (clang, -O2):
<strshft>:
push   %r14
push   %rbx
mov    (%rsi),%cl
mov    %edx,%ebx
mov    %cl,(%rsi,%rbx,1)
mov    %rsi,%r9
sub    %rdi,%r9
je     11a7 <strshft+0xa7>
mov    %rdi,%r8
not    %r8
cmp    $0x4,%r9
jae    11b0 <strshft+0xb0>
mov    %rsi,%rcx
mov    %ecx,%edx
sub    %edi,%edx
add    %rcx,%r8
and    $0x7,%rdx
je     1150 <strshft+0x50>
cs nopw 0x0(%rax,%rax,1)
movzbl (%rcx),%eax
mov    %al,(%rcx,%rbx,1)
add    $0xffffffffffffffff,%rcx
add    $0xffffffffffffffff,%rdx
jne    1140 <strshft+0x40>
cmp    $0x7,%r8
jb     11a7 <strshft+0xa7>
cs nopw 0x0(%rax,%rax,1)
movzbl (%rcx),%eax
mov    %al,(%rcx,%rbx,1)
movzbl -0x1(%rcx),%eax
mov    %al,-0x1(%rcx,%rbx,1)
movzbl -0x2(%rcx),%eax
mov    %al,-0x2(%rcx,%rbx,1)
movzbl -0x3(%rcx),%eax
mov    %al,-0x3(%rcx,%rbx,1)
movzbl -0x4(%rcx),%eax
mov    %al,-0x4(%rcx,%rbx,1)
movzbl -0x5(%rcx),%eax
mov    %al,-0x5(%rcx,%rbx,1)
movzbl -0x6(%rcx),%eax
mov    %al,-0x6(%rcx,%rbx,1)
movzbl -0x7(%rcx),%eax
mov    %al,-0x7(%rcx,%rbx,1)
add    $0xfffffffffffffff8,%rcx
cmp    %rdi,%rcx
jne    1160 <strshft+0x60>
mov    (%rdi),%al
mov    %al,(%rdi,%rbx,1)
pop    %rbx
pop    %r14
ret
lea    (%r8,%rsi,1),%rcx
lea    (%rsi,%rbx,1),%rax
mov    %rax,%rdx
sub    %rcx,%rdx
cmp    %rax,%rdx
ja     1126 <strshft+0x26>
mov    %rsi,%rdx
sub    %rcx,%rdx
cmp    %rsi,%rdx
ja     1126 <strshft+0x26>
lea    (%rdi,%rbx,1),%rcx
add    $0x1,%rcx
lea    0x1(%rsi),%rdx
cmp    %rdx,%rcx
jae    11fc <strshft+0xfc>
lea    (%rbx,%rsi,1),%rcx
add    $0x1,%rcx
lea    0x1(%rdi),%rdx
cmp    %rcx,%rdx
jb     1126 <strshft+0x26>
cmp    $0x10,%r9
jae    1209 <strshft+0x109>
xor    %edx,%edx
jmp    12c5 <strshft+0x1c5>
mov    %r9,%rdx
and    $0xfffffffffffffff0,%rdx
lea    -0x10(%rdx),%rcx
mov    %rcx,%r11
shr    $0x4,%r11
add    $0x1,%r11
mov    %r11d,%r10d
and    $0x3,%r10d
cmp    $0x30,%rcx
jae    1230 <strshft+0x130>
xor    %ecx,%ecx
jmp    1274 <strshft+0x174>
and    $0xfffffffffffffffc,%r11
lea    (%rbx,%rsi,1),%rax
add    $0xfffffffffffffff1,%rax
xor    %ecx,%ecx
xchg   %ax,%ax
movups -0xf(%rsi,%rcx,1),%xmm0
movups %xmm0,(%rax,%rcx,1)
movups -0x1f(%rsi,%rcx,1),%xmm0
movups %xmm0,-0x10(%rax,%rcx,1)
movups -0x2f(%rsi,%rcx,1),%xmm0
movups %xmm0,-0x20(%rax,%rcx,1)
movups -0x3f(%rsi,%rcx,1),%xmm0
movups %xmm0,-0x30(%rax,%rcx,1)
add    $0xffffffffffffffc0,%rcx
add    $0xfffffffffffffffc,%r11
jne    1240 <strshft+0x140>
neg    %rcx
test   %r10,%r10
je     12b6 <strshft+0x1b6>
mov    %rbx,%rax
sub    %rcx,%rax
lea    (%rax,%rsi,1),%r11
add    $0xfffffffffffffff1,%r11
mov    %rsi,%r14
sub    %rcx,%r14
add    $0xfffffffffffffff1,%r14
shl    $0x4,%r10
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
movups (%r14,%rcx,1),%xmm0
movups %xmm0,(%r11,%rcx,1)
add    $0xfffffffffffffff0,%rcx
mov    %r10,%rax
add    %rcx,%rax
jne    12a0 <strshft+0x1a0>
cmp    %rdx,%r9
je     11a7 <strshft+0xa7>
test   $0xc,%r9b
je     12fd <strshft+0x1fd>
mov    %r9,%r10
and    $0xfffffffffffffffc,%r10
mov    %rsi,%rcx
sub    %r10,%rcx
sub    %rdx,%rsi
add    $0xfffffffffffffffd,%rsi
sub    %r10,%rdx
nopl   0x0(%rax)
mov    (%rsi),%eax
mov    %eax,(%rsi,%rbx,1)
add    $0xfffffffffffffffc,%rsi
add    $0x4,%rdx
jne    12e0 <strshft+0x1e0>
cmp    %r10,%r9
jne    1129 <strshft+0x29>
jmp    11a7 <strshft+0xa7>
sub    %rdx,%rsi
jmp    1126 <strshft+0x26>

LLVM IR (-O0):
define void @strshft(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%7 = load i8*, i8** %5
%8 = load i8, i8* %7
%9 = load i8*, i8** %5
%10 = load i32, i32* %6
%11 = zext i32 %10 to i64
%12 = getelementptr inbounds i8, i8* %9, i64 %11
store i8 %8, i8* %12
br label %13
13: ; preds = %17, %3
%14 = load i8*, i8** %5
%15 = load i8*, i8** %4
%16 = icmp ne i8* %14, %15
br i1 %16, label %17, label %26
17: ; preds = %13
%18 = load i8*, i8** %5
%19 = load i8, i8* %18
%20 = load i8*, i8** %5
%21 = load i32, i32* %6
%22 = zext i32 %21 to i64
%23 = getelementptr inbounds i8, i8* %20, i64 %22
store i8 %19, i8* %23
%24 = load i8*, i8** %5
%25 = getelementptr inbounds i8, i8* %24, i32 -1
store i8* %25, i8** %5
br label %13
26: ; preds = %13
%27 = load i8*, i8** %4
%28 = load i8, i8* %27
%29 = load i8*, i8** %4
%30 = load i32, i32* %6
%31 = zext i32 %30 to i64
%32 = getelementptr inbounds i8, i8* %29, i64 %31
store i8 %28, i8* %32
ret void
}

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