void hc_pairs_downstream(unsigned int i, char c_option, char *hc,
                         unsigned int length, int *index) {
  unsigned int l;
  for (l = length; l > i; l--)
    hc[index[l] + i] &= c_option;
  for (l = i - 1; l >= 1; l--)
    hc[index[i] + l] = (char)0;
}


x86 assembly (clang, -O0):
<hc_pairs_downstream>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %edi,-0x4(%rbp)
mov    %al,-0x5(%rbp)
mov    %rdx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8,-0x20(%rbp)
mov    -0x14(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x4(%rbp),%eax
jbe    1158 <hc_pairs_downstream+0x58>
movsbl -0x5(%rbp),%esi
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    -0x24(%rbp),%edx
mov    (%rcx,%rdx,4),%ecx
add    -0x4(%rbp),%ecx
mov    %ecx,%ecx
movsbl (%rax,%rcx,1),%edx
and    %esi,%edx
mov    %dl,(%rax,%rcx,1)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    111e <hc_pairs_downstream+0x1e>
mov    -0x4(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x24(%rbp)
cmpl   $0x1,-0x24(%rbp)
jb     1190 <hc_pairs_downstream+0x90>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    -0x4(%rbp),%edx
mov    (%rcx,%rdx,4),%ecx
add    -0x24(%rbp),%ecx
mov    %ecx,%ecx
movb   $0x0,(%rax,%rcx,1)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    1161 <hc_pairs_downstream+0x61>
pop    %rbp
ret

x86 assembly (clang, -O2):
<hc_pairs_downstream>:
mov    %ecx,%r10d
sub    %edi,%r10d
jbe    114e <hc_pairs_downstream+0x4e>
mov    %ecx,%r11d
mov    %edi,%r9d
not    %r9d
test   $0x1,%r10b
je     1125 <hc_pairs_downstream+0x25>
mov    (%r8,%r11,4),%eax
add    %edi,%eax
and    %sil,(%rdx,%rax,1)
add    $0xffffffffffffffff,%r11
add    %ecx,%r9d
je     114e <hc_pairs_downstream+0x4e>
nopw   0x0(%rax,%rax,1)
mov    (%r8,%r11,4),%eax
add    %edi,%eax
and    %sil,(%rdx,%rax,1)
mov    -0x4(%r8,%r11,4),%eax
add    %edi,%eax
and    %sil,(%rdx,%rax,1)
add    $0xfffffffffffffffe,%r11
cmp    %edi,%r11d
ja     1130 <hc_pairs_downstream+0x30>
mov    %edi,%eax
add    $0xffffffff,%eax
je     11c5 <hc_pairs_downstream+0xc5>
mov    %edi,%r9d
add    $0xfffffffe,%edi
mov    %eax,%esi
and    $0x3,%esi
je     1182 <hc_pairs_downstream+0x82>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
mov    (%r8,%r9,4),%ecx
add    %eax,%ecx
movb   $0x0,(%rdx,%rcx,1)
add    $0xffffffff,%eax
add    $0xffffffff,%esi
jne    1170 <hc_pairs_downstream+0x70>
cmp    $0x3,%edi
jb     11c5 <hc_pairs_downstream+0xc5>
nopw   0x0(%rax,%rax,1)
mov    (%r8,%r9,4),%ecx
add    %eax,%ecx
movb   $0x0,(%rdx,%rcx,1)
mov    (%r8,%r9,4),%ecx
add    %eax,%ecx
add    $0xffffffff,%ecx
movb   $0x0,(%rdx,%rcx,1)
mov    (%r8,%r9,4),%ecx
lea    -0x2(%rax,%rcx,1),%ecx
movb   $0x0,(%rdx,%rcx,1)
mov    (%r8,%r9,4),%ecx
add    %eax,%ecx
add    $0xfffffffd,%ecx
movb   $0x0,(%rdx,%rcx,1)
add    $0xfffffffc,%eax
jne    1190 <hc_pairs_downstream+0x90>
ret

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

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