int blockiszero(const char *blk, const int ln) {
  unsigned long *ptr = (unsigned long *)blk;
  while ((ptr - (unsigned long *)blk) < ln / sizeof(unsigned long))
    if (*(ptr++))
      return (sizeof(unsigned long) * (ptr - (unsigned long *)blk));
  return ln;
}


x86 assembly (clang, -O0):
<blockiszero>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
sar    $0x3,%rax
movslq -0x14(%rbp),%rcx
shr    $0x3,%rcx
cmp    %rcx,%rax
jae    116c <blockiszero+0x6c>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x20(%rbp)
cmpq   $0x0,(%rax)
je     1167 <blockiszero+0x67>
mov    -0x20(%rbp),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
sar    $0x3,%rax
shl    $0x3,%rax
mov    %eax,-0x4(%rbp)
jmp    1172 <blockiszero+0x72>
jmp    1113 <blockiszero+0x13>
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<blockiszero>:
mov    %esi,%eax
movslq %esi,%rcx
shr    $0x3,%rcx
xor    %edx,%edx
nopl   0x0(%rax,%rax,1)
mov    %rdx,%rsi
sar    $0x3,%rsi
cmp    %rcx,%rsi
jae    112c <blockiszero+0x2c>
lea    0x8(%rdx),%rsi
cmpq   $0x0,(%rdi,%rdx,1)
mov    %rsi,%rdx
je     1110 <blockiszero+0x10>
mov    %esi,%eax
ret

LLVM IR (-O0):
define i32 @blockiszero(i8* %0, i32 %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i64*
store i8* %0, i8** %4
store i32 %1, i32* %5
%7 = load i8*, i8** %4
%8 = bitcast i8* %7 to i64*
store i64* %8, i64** %6
br label %9
9: ; preds = %36, %2
%10 = load i64*, i64** %6
%11 = load i8*, i8** %4
%12 = bitcast i8* %11 to i64*
%13 = ptrtoint i64* %10 to i64
%14 = ptrtoint i64* %12 to i64
%15 = sub i64 %13, %14
%16 = sdiv exact i64 %15, 8
%17 = load i32, i32* %5
%18 = sext i32 %17 to i64
%19 = udiv i64 %18, 8
%20 = icmp ult i64 %16, %19
br i1 %20, label %21, label %37
21: ; preds = %9
%22 = load i64*, i64** %6
%23 = getelementptr inbounds i64, i64* %22, i32 1
store i64* %23, i64** %6
%24 = load i64, i64* %22
%25 = icmp ne i64 %24, 0
br i1 %25, label %26, label %36
26: ; preds = %21
%27 = load i64*, i64** %6
%28 = load i8*, i8** %4
%29 = bitcast i8* %28 to i64*
%30 = ptrtoint i64* %27 to i64
%31 = ptrtoint i64* %29 to i64
%32 = sub i64 %30, %31
%33 = sdiv exact i64 %32, 8
%34 = mul i64 8, %33
%35 = trunc i64 %34 to i32
store i32 %35, i32* %3
br label %39
36: ; preds = %21
br label %9
37: ; preds = %9
%38 = load i32, i32* %5
store i32 %38, i32* %3
br label %39
39: ; preds = %37, %26
%40 = load i32, i32* %3
ret i32 %40
}

LLVM IR (-O2):
define i32 @blockiszero(i8* %0, i32 %1) {
%3 = bitcast i8* %0 to i64*
%4 = ptrtoint i8* %0 to i64
%5 = sext i32 %1 to i64
%6 = lshr i64 %5, 3
br label %7
7: ; preds = %13, %2
%8 = phi i64* [ %3, %2 ], [ %14, %13 ]
%9 = ptrtoint i64* %8 to i64
%10 = sub i64 %9, %4
%11 = ashr exact i64 %10, 3
%12 = icmp ult i64 %11, %6
br i1 %12, label %13, label %21
13: ; preds = %7
%14 = getelementptr inbounds i64, i64* %8, i64 1
%15 = load i64, i64* %8
%16 = icmp eq i64 %15, 0
br i1 %16, label %7, label %17
17: ; preds = %13
%18 = ptrtoint i64* %14 to i64
%19 = sub i64 %18, %4
%20 = trunc i64 %19 to i32
br label %21
21: ; preds = %7, %17
%22 = phi i32 [ %20, %17 ], [ %1, %7 ]
ret i32 %22
}