void blatch(void *head, int n) {
  unsigned char *c = (unsigned char *)head;
  unsigned char *e = (unsigned char *)head + n;
  for (; c < e; c++) {
    *c &= 0x7f;
  }
}


x86 assembly (clang, -O0):
<blatch>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    114d <blatch+0x4d>
mov    -0x18(%rbp),%rax
movzbl (%rax),%ecx
and    $0x7f,%ecx
mov    %cl,(%rax)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    1122 <blatch+0x22>
pop    %rbp
ret

x86 assembly (clang, -O2):
<blatch>:
test   %esi,%esi
jle    122c <blatch+0x12c>
movslq %esi,%rax
add    %rdi,%rax
lea    0x1(%rdi),%r8
cmp    %r8,%rax
mov    %r8,%r10
cmova  %rax,%r10
sub    %rdi,%r10
cmp    $0x8,%r10
jae    112d <blatch+0x2d>
mov    %rdi,%rcx
jmp    1220 <blatch+0x120>
cmp    $0x20,%r10
jae    113a <blatch+0x3a>
xor    %edx,%edx
jmp    11dc <blatch+0xdc>
mov    %r10,%rdx
and    $0xffffffffffffffe0,%rdx
lea    -0x20(%rdx),%rcx
mov    %rcx,%r9
shr    $0x5,%r9
add    $0x1,%r9
test   %rcx,%rcx
je     122d <blatch+0x12d>
mov    %r9,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %ecx,%ecx
movaps 0xe97(%rip),%xmm0
nopl   0x0(%rax)
movups (%rdi,%rcx,1),%xmm1
movups 0x10(%rdi,%rcx,1),%xmm2
movups 0x20(%rdi,%rcx,1),%xmm3
movups 0x30(%rdi,%rcx,1),%xmm4
andps  %xmm0,%xmm1
andps  %xmm0,%xmm2
movups %xmm1,(%rdi,%rcx,1)
movups %xmm2,0x10(%rdi,%rcx,1)
andps  %xmm0,%xmm3
andps  %xmm0,%xmm4
movups %xmm3,0x20(%rdi,%rcx,1)
movups %xmm4,0x30(%rdi,%rcx,1)
add    $0x40,%rcx
add    $0xfffffffffffffffe,%rsi
jne    1170 <blatch+0x70>
test   $0x1,%r9b
je     11d1 <blatch+0xd1>
movups (%rdi,%rcx,1),%xmm0
movups 0x10(%rdi,%rcx,1),%xmm1
movaps 0xe3e(%rip),%xmm2
andps  %xmm2,%xmm0
andps  %xmm2,%xmm1
movups %xmm0,(%rdi,%rcx,1)
movups %xmm1,0x10(%rdi,%rcx,1)
cmp    %rdx,%r10
je     122c <blatch+0x12c>
test   $0x18,%r10b
je     123b <blatch+0x13b>
cmp    %r8,%rax
cmova  %rax,%r8
sub    %rdi,%r8
mov    %r8,%rsi
and    $0xfffffffffffffff8,%rsi
lea    (%rdi,%rsi,1),%rcx
movabs $0x7f7f7f7f7f7f7f7f,%r9
7f 7f 7f
nopl   0x0(%rax,%rax,1)
and    %r9,(%rdi,%rdx,1)
add    $0x8,%rdx
cmp    %rdx,%rsi
jne    1200 <blatch+0x100>
cmp    %rsi,%r8
je     122c <blatch+0x12c>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
andb   $0x7f,(%rcx)
add    $0x1,%rcx
cmp    %rax,%rcx
jb     1220 <blatch+0x120>
ret
xor    %ecx,%ecx
test   $0x1,%r9b
jne    11b2 <blatch+0xb2>
jmp    11d1 <blatch+0xd1>
add    %rdx,%rdi
jmp    1125 <blatch+0x25>

LLVM IR (-O0):
define void @blatch(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i8*
store i8* %0, i8** %3
store i32 %1, i32* %4
%7 = load i8*, i8** %3
store i8* %7, i8** %5
%8 = load i8*, i8** %3
%9 = load i32, i32* %4
%10 = sext i32 %9 to i64
%11 = getelementptr inbounds i8, i8* %8, i64 %10
store i8* %11, i8** %6
br label %12
12: ; preds = %22, %2
%13 = load i8*, i8** %5
%14 = load i8*, i8** %6
%15 = icmp ult i8* %13, %14
br i1 %15, label %16, label %25
16: ; preds = %12
%17 = load i8*, i8** %5
%18 = load i8, i8* %17
%19 = zext i8 %18 to i32
%20 = and i32 %19, 127
%21 = trunc i32 %20 to i8
store i8 %21, i8* %17
br label %22
22: ; preds = %16
%23 = load i8*, i8** %5
%24 = getelementptr inbounds i8, i8* %23, i32 1
store i8* %24, i8** %5
br label %12
25: ; preds = %12
ret void
}

LLVM IR (-O2):
define void @blatch(i8* %0, i32 %1) {
%3 = ptrtoint i8* %0 to i64
%4 = sext i32 %1 to i64
%5 = getelementptr inbounds i8, i8* %0, i64 %4
%6 = icmp sgt i32 %1, 0
br i1 %6, label %7, label %98
7: ; preds = %2
%8 = add i64 %3, %4
%9 = add i64 %3, 1
%10 = call i64 @llvm.umax.i64(i64 %8, i64 %9)
%11 = sub i64 %10, %3
%12 = icmp ult i64 %11, 8
br i1 %12, label %90, label %13
13: ; preds = %7
%14 = icmp ult i64 %11, 32
br i1 %14, label %71, label %15
15: ; preds = %13
%16 = and i64 %11, -32
%17 = add i64 %16, -32
%18 = lshr exact i64 %17, 5
%19 = add nuw nsw i64 %18, 1
%20 = and i64 %19, 1
%21 = icmp eq i64 %17, 0
br i1 %21, label %51, label %22
22: ; preds = %15
%23 = and i64 %19, 1152921504606846974
br label %24
24: ; preds = %24, %22
%25 = phi i64 [ 0, %22 ], [ %48, %24 ]
%26 = phi i64 [ 0, %22 ], [ %49, %24 ]
%27 = getelementptr i8, i8* %0, i64 %25
%28 = bitcast i8* %27 to <16 x i8>*
%29 = load <16 x i8>, <16 x i8>* %28
%30 = getelementptr i8, i8* %27, i64 16
%31 = bitcast i8* %30 to <16 x i8>*
%32 = load <16 x i8>, <16 x i8>* %31
%33 = and <16 x i8> %29, <i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127>
%34 = and <16 x i8> %32, <i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127>
%35 = bitcast i8* %27 to <16 x i8>*
store <16 x i8> %33, <16 x i8>* %35
%36 = bitcast i8* %30 to <16 x i8>*
store <16 x i8> %34, <16 x i8>* %36
%37 = or i64 %25, 32
%38 = getelementptr i8, i8* %0, i64 %37
%39 = bitcast i8* %38 to <16 x i8>*
%40 = load <16 x i8>, <16 x i8>* %39
%41 = getelementptr i8, i8* %38, i64 16
%42 = bitcast i8* %41 to <16 x i8>*
%43 = load <16 x i8>, <16 x i8>* %42
%44 = and <16 x i8> %40, <i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127>
%45 = and <16 x i8> %43, <i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127>
%46 = bitcast i8* %38 to <16 x i8>*
store <16 x i8> %44, <16 x i8>* %46
%47 = bitcast i8* %41 to <16 x i8>*
store <16 x i8> %45, <16 x i8>* %47
%48 = add nuw i64 %25, 64
%49 = add i64 %26, 2
%50 = icmp eq i64 %49, %23
br i1 %50, label %51, label %24
51: ; preds = %24, %15
%52 = phi i64 [ 0, %15 ], [ %48, %24 ]
%53 = icmp eq i64 %20, 0
br i1 %53, label %65, label %54
54: ; preds = %51
%55 = getelementptr i8, i8* %0, i64 %52
%56 = bitcast i8* %55 to <16 x i8>*
%57 = load <16 x i8>, <16 x i8>* %56
%58 = getelementptr i8, i8* %55, i64 16
%59 = bitcast i8* %58 to <16 x i8>*
%60 = load <16 x i8>, <16 x i8>* %59
%61 = and <16 x i8> %57, <i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127>
%62 = and <16 x i8> %60, <i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127>
%63 = bitcast i8* %55 to <16 x i8>*
store <16 x i8> %61, <16 x i8>* %63
%64 = bitcast i8* %58 to <16 x i8>*
store <16 x i8> %62, <16 x i8>* %64
br label %65
65: ; preds = %51, %54
%66 = icmp eq i64 %11, %16
br i1 %66, label %98, label %67
67: ; preds = %65
%68 = getelementptr i8, i8* %0, i64 %16
%69 = and i64 %11, 24
%70 = icmp eq i64 %69, 0
br i1 %70, label %90, label %71
71: ; preds = %13, %67
%72 = phi i64 [ %16, %67 ], [ 0, %13 ]
%73 = add i64 %3, %4
%74 = add i64 %3, 1
%75 = call i64 @llvm.umax.i64(i64 %73, i64 %74)
%76 = sub i64 %75, %3
%77 = and i64 %76, -8
%78 = getelementptr i8, i8* %0, i64 %77
br label %79
79: ; preds = %79, %71
%80 = phi i64 [ %72, %71 ], [ %86, %79 ]
%81 = getelementptr i8, i8* %0, i64 %80
%82 = bitcast i8* %81 to <8 x i8>*
%83 = load <8 x i8>, <8 x i8>* %82
%84 = and <8 x i8> %83, <i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127, i8 127>
%85 = bitcast i8* %81 to <8 x i8>*
store <8 x i8> %84, <8 x i8>* %85
%86 = add nuw i64 %80, 8
%87 = icmp eq i64 %86, %77
br i1 %87, label %88, label %79
88: ; preds = %79
%89 = icmp eq i64 %76, %77
br i1 %89, label %98, label %90
90: ; preds = %7, %67, %88
%91 = phi i8* [ %0, %7 ], [ %68, %67 ], [ %78, %88 ]
br label %92
92: ; preds = %90, %92
%93 = phi i8* [ %96, %92 ], [ %91, %90 ]
%94 = load i8, i8* %93
%95 = and i8 %94, 127
store i8 %95, i8* %93
%96 = getelementptr inbounds i8, i8* %93, i64 1
%97 = icmp ult i8* %96, %5
br i1 %97, label %92, label %98
98: ; preds = %92, %65, %88, %2
ret void
}