void _left_right_alpha_src_mask(unsigned char *source_row_start,
                                unsigned char *source_row_end,
                                unsigned char *destination_row_start,
                                int srcMask, int destMask) {
  unsigned char *source_row_ptr;
  unsigned char *destination_row_ptr = destination_row_start;
  for (source_row_ptr = source_row_start; source_row_ptr < source_row_end;
       source_row_ptr++) {
    if (*source_row_ptr)
      *destination_row_ptr = srcMask & *source_row_ptr;
    destination_row_ptr++;
  }
}


x86 assembly (clang, -O0):
<_left_right_alpha_src_mask>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8d,-0x20(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    1173 <_left_right_alpha_src_mask+0x73>
mov    -0x28(%rbp),%rax
cmpb   $0x0,(%rax)
je     1156 <_left_right_alpha_src_mask+0x56>
mov    -0x1c(%rbp),%eax
mov    -0x28(%rbp),%rcx
movzbl (%rcx),%ecx
and    %ecx,%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %cl,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1127 <_left_right_alpha_src_mask+0x27>
pop    %rbp
ret

x86 assembly (clang, -O2):
<_left_right_alpha_src_mask>:
push   %rbx
cmp    %rsi,%rdi
jae    130f <_left_right_alpha_src_mask+0x20f>
mov    %rsi,%r9
sub    %rdi,%r9
cmp    $0x8,%r9
jb     112c <_left_right_alpha_src_mask+0x2c>
cmp    %rdx,%rsi
jbe    11d3 <_left_right_alpha_src_mask+0xd3>
lea    (%rdx,%r9,1),%rax
cmp    %rdi,%rax
jbe    11d3 <_left_right_alpha_src_mask+0xd3>
mov    %rdx,%r8
mov    %rdi,%r11
mov    %esi,%edx
sub    %r11d,%edx
mov    %r11,%rdi
not    %rdi
add    %rsi,%rdi
and    $0x3,%rdx
jne    116e <_left_right_alpha_src_mask+0x6e>
cmp    $0x3,%rdi
jb     130f <_left_right_alpha_src_mask+0x20f>
xor    %eax,%eax
jmp    1191 <_left_right_alpha_src_mask+0x91>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
add    $0x1,%r8
add    $0x1,%r11
add    $0xffffffffffffffff,%rdx
je     1146 <_left_right_alpha_src_mask+0x46>
movzbl (%r11),%eax
test   %al,%al
je     1160 <_left_right_alpha_src_mask+0x60>
and    %cl,%al
mov    %al,(%r8)
jmp    1160 <_left_right_alpha_src_mask+0x60>
nopl   (%rax)
add    $0x4,%rax
add    $0x4,%rdi
cmp    %rsi,%rdi
je     130f <_left_right_alpha_src_mask+0x20f>
lea    (%r11,%rax,1),%rdi
movzbl (%r11,%rax,1),%edx
test   %dl,%dl
je     11a4 <_left_right_alpha_src_mask+0xa4>
and    %cl,%dl
mov    %dl,(%r8,%rax,1)
movzbl 0x1(%rdi),%edx
test   %dl,%dl
je     11b3 <_left_right_alpha_src_mask+0xb3>
and    %cl,%dl
mov    %dl,0x1(%r8,%rax,1)
movzbl 0x2(%rdi),%edx
test   %dl,%dl
je     11c2 <_left_right_alpha_src_mask+0xc2>
and    %cl,%dl
mov    %dl,0x2(%r8,%rax,1)
movzbl 0x3(%rdi),%edx
test   %dl,%dl
je     1180 <_left_right_alpha_src_mask+0x80>
and    %cl,%dl
mov    %dl,0x3(%r8,%rax,1)
jmp    1180 <_left_right_alpha_src_mask+0x80>
mov    %r9,%r10
and    $0xfffffffffffffff8,%r10
lea    (%rdx,%r10,1),%r8
lea    (%rdi,%r10,1),%r11
xor    %eax,%eax
pxor   %xmm0,%xmm0
pcmpeqd %xmm1,%xmm1
jmp    11fd <_left_right_alpha_src_mask+0xfd>
xchg   %ax,%ax
add    $0x8,%rax
cmp    %rax,%r10
je     1306 <_left_right_alpha_src_mask+0x206>
movq   (%rdi,%rax,1),%xmm2
movdqa %xmm2,%xmm3
pcmpeqb %xmm0,%xmm3
movd   %xmm3,%ebx
not    %bl
test   $0x1,%bl
je     121e <_left_right_alpha_src_mask+0x11e>
movd   %xmm2,%ebx
and    %cl,%bl
mov    %bl,(%rdx,%rax,1)
pxor   %xmm1,%xmm3
movdqa %xmm3,%xmm4
pslld  $0x8,%xmm4
movd   %xmm4,%ebx
shr    $0x10,%ebx
test   $0x1,%bl
je     1244 <_left_right_alpha_src_mask+0x144>
movd   %xmm2,%ebx
shr    $0x8,%ebx
and    %cl,%bl
mov    %bl,0x1(%rdx,%rax,1)
pshuflw $0x55,%xmm2,%xmm4
pcmpeqb %xmm0,%xmm4
pxor   %xmm1,%xmm4
pextrw $0x2,%xmm4,%ebx
test   $0x1,%bl
je     1268 <_left_right_alpha_src_mask+0x168>
movd   %xmm2,%ebx
shr    $0x10,%ebx
and    %cl,%bl
mov    %bl,0x2(%rdx,%rax,1)
movdqa %xmm3,%xmm4
psllq  $0x18,%xmm4
pextrw $0x3,%xmm4,%ebx
test   $0x1,%bl
je     1288 <_left_right_alpha_src_mask+0x188>
movd   %xmm2,%ebx
shr    $0x18,%ebx
and    %cl,%bl
mov    %bl,0x3(%rdx,%rax,1)
pshufd $0x55,%xmm2,%xmm4
pcmpeqb %xmm0,%xmm4
pxor   %xmm1,%xmm4
pextrw $0x4,%xmm4,%ebx
test   $0x1,%bl
je     12aa <_left_right_alpha_src_mask+0x1aa>
pextrw $0x2,%xmm2,%ebx
and    %cl,%bl
mov    %bl,0x4(%rdx,%rax,1)
movdqa %xmm3,%xmm4
pslldq $0x5,%xmm4
pextrw $0x5,%xmm4,%ebx
test   $0x1,%bl
je     12cb <_left_right_alpha_src_mask+0x1cb>
pextrw $0x2,%xmm2,%ebx
shr    $0x8,%ebx
and    %cl,%bl
mov    %bl,0x5(%rdx,%rax,1)
pextrw $0x3,%xmm3,%ebx
test   $0x1,%bl
je     12e0 <_left_right_alpha_src_mask+0x1e0>
pextrw $0x3,%xmm2,%ebx
and    %cl,%bl
mov    %bl,0x6(%rdx,%rax,1)
pslldq $0x7,%xmm3
pextrw $0x7,%xmm3,%ebx
test   $0x1,%bl
je     11f0 <_left_right_alpha_src_mask+0xf0>
pextrw $0x3,%xmm2,%ebx
shr    $0x8,%ebx
and    %cl,%bl
mov    %bl,0x7(%rdx,%rax,1)
jmp    11f0 <_left_right_alpha_src_mask+0xf0>
cmp    %r10,%r9
jne    1132 <_left_right_alpha_src_mask+0x32>
pop    %rbx
ret

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

LLVM IR (-O2):
define void @_left_right_alpha_src_mask(i8* %0, i8* readnone %1, i8* nocapture writeonly %2, i32 %3, i32 %4) {
%6 = icmp ult i8* %0, %1
br i1 %6, label %7, label %146
7: ; preds = %5
%8 = ptrtoint i8* %1 to i64
%9 = ptrtoint i8* %0 to i64
%10 = trunc i32 %3 to i8
%11 = sub i64 %8, %9
%12 = getelementptr i8, i8* %0, i64 %11
%13 = icmp ult i64 %11, 8
br i1 %13, label %88, label %14
14: ; preds = %7
%15 = getelementptr i8, i8* %2, i64 %11
%16 = icmp ugt i8* %12, %2
%17 = icmp ugt i8* %15, %0
%18 = and i1 %16, %17
br i1 %18, label %88, label %19
19: ; preds = %14
%20 = and i64 %11, -8
%21 = getelementptr i8, i8* %2, i64 %20
%22 = getelementptr i8, i8* %0, i64 %20
br label %23
23: ; preds = %83, %19
%24 = phi i64 [ 0, %19 ], [ %84, %83 ]
%25 = getelementptr i8, i8* %0, i64 %24
%26 = bitcast i8* %25 to <8 x i8>*
%27 = load <8 x i8>, <8 x i8>* %26
%28 = icmp ne <8 x i8> %27, zeroinitializer
%29 = extractelement <8 x i1> %28, i64 0
br i1 %29, label %30, label %34
30: ; preds = %23
%31 = getelementptr i8, i8* %2, i64 %24
%32 = extractelement <8 x i8> %27, i64 0
%33 = and i8 %32, %10
store i8 %33, i8* %31
br label %34
34: ; preds = %30, %23
%35 = extractelement <8 x i1> %28, i64 1
br i1 %35, label %36, label %41
36: ; preds = %34
%37 = or i64 %24, 1
%38 = getelementptr i8, i8* %2, i64 %37
%39 = extractelement <8 x i8> %27, i64 1
%40 = and i8 %39, %10
store i8 %40, i8* %38
br label %41
41: ; preds = %36, %34
%42 = extractelement <8 x i1> %28, i64 2
br i1 %42, label %43, label %48
43: ; preds = %41
%44 = or i64 %24, 2
%45 = getelementptr i8, i8* %2, i64 %44
%46 = extractelement <8 x i8> %27, i64 2
%47 = and i8 %46, %10
store i8 %47, i8* %45
br label %48
48: ; preds = %43, %41
%49 = extractelement <8 x i1> %28, i64 3
br i1 %49, label %50, label %55
50: ; preds = %48
%51 = or i64 %24, 3
%52 = getelementptr i8, i8* %2, i64 %51
%53 = extractelement <8 x i8> %27, i64 3
%54 = and i8 %53, %10
store i8 %54, i8* %52
br label %55
55: ; preds = %50, %48
%56 = extractelement <8 x i1> %28, i64 4
br i1 %56, label %57, label %62
57: ; preds = %55
%58 = or i64 %24, 4
%59 = getelementptr i8, i8* %2, i64 %58
%60 = extractelement <8 x i8> %27, i64 4
%61 = and i8 %60, %10
store i8 %61, i8* %59
br label %62
62: ; preds = %57, %55
%63 = extractelement <8 x i1> %28, i64 5
br i1 %63, label %64, label %69
64: ; preds = %62
%65 = or i64 %24, 5
%66 = getelementptr i8, i8* %2, i64 %65
%67 = extractelement <8 x i8> %27, i64 5
%68 = and i8 %67, %10
store i8 %68, i8* %66
br label %69
69: ; preds = %64, %62
%70 = extractelement <8 x i1> %28, i64 6
br i1 %70, label %71, label %76
71: ; preds = %69
%72 = or i64 %24, 6
%73 = getelementptr i8, i8* %2, i64 %72
%74 = extractelement <8 x i8> %27, i64 6
%75 = and i8 %74, %10
store i8 %75, i8* %73
br label %76
76: ; preds = %71, %69
%77 = extractelement <8 x i1> %28, i64 7
br i1 %77, label %78, label %83
78: ; preds = %76
%79 = or i64 %24, 7
%80 = getelementptr i8, i8* %2, i64 %79
%81 = extractelement <8 x i8> %27, i64 7
%82 = and i8 %81, %10
store i8 %82, i8* %80
br label %83
83: ; preds = %78, %76
%84 = add nuw i64 %24, 8
%85 = icmp eq i64 %84, %20
br i1 %85, label %86, label %23
86: ; preds = %83
%87 = icmp eq i64 %11, %20
br i1 %87, label %146, label %88
88: ; preds = %14, %7, %86
%89 = phi i8* [ %2, %14 ], [ %2, %7 ], [ %21, %86 ]
%90 = phi i8* [ %0, %14 ], [ %0, %7 ], [ %22, %86 ]
%91 = ptrtoint i8* %90 to i64
%92 = sub i64 %8, %91
%93 = xor i64 %91, -1
%94 = add i64 %93, %8
%95 = and i64 %92, 3
%96 = icmp eq i64 %95, 0
br i1 %96, label %110, label %97
97: ; preds = %88, %105
%98 = phi i8* [ %106, %105 ], [ %89, %88 ]
%99 = phi i8* [ %107, %105 ], [ %90, %88 ]
%100 = phi i64 [ %108, %105 ], [ 0, %88 ]
%101 = load i8, i8* %99
%102 = icmp eq i8 %101, 0
br i1 %102, label %105, label %103
103: ; preds = %97
%104 = and i8 %101, %10
store i8 %104, i8* %98
br label %105
105: ; preds = %103, %97
%106 = getelementptr inbounds i8, i8* %98, i64 1
%107 = getelementptr inbounds i8, i8* %99, i64 1
%108 = add i64 %100, 1
%109 = icmp eq i64 %108, %95
br i1 %109, label %110, label %97
110: ; preds = %105, %88
%111 = phi i8* [ %89, %88 ], [ %106, %105 ]
%112 = phi i8* [ %90, %88 ], [ %107, %105 ]
%113 = icmp ult i64 %94, 3
br i1 %113, label %146, label %114
114: ; preds = %110, %142
%115 = phi i8* [ %143, %142 ], [ %111, %110 ]
%116 = phi i8* [ %144, %142 ], [ %112, %110 ]
%117 = load i8, i8* %116
%118 = icmp eq i8 %117, 0
br i1 %118, label %121, label %119
119: ; preds = %114
%120 = and i8 %117, %10
store i8 %120, i8* %115
br label %121
121: ; preds = %119, %114
%122 = getelementptr inbounds i8, i8* %116, i64 1
%123 = load i8, i8* %122
%124 = icmp eq i8 %123, 0
br i1 %124, label %128, label %125
125: ; preds = %121
%126 = getelementptr inbounds i8, i8* %115, i64 1
%127 = and i8 %123, %10
store i8 %127, i8* %126
br label %128
128: ; preds = %125, %121
%129 = getelementptr inbounds i8, i8* %116, i64 2
%130 = load i8, i8* %129
%131 = icmp eq i8 %130, 0
br i1 %131, label %135, label %132
132: ; preds = %128
%133 = getelementptr inbounds i8, i8* %115, i64 2
%134 = and i8 %130, %10
store i8 %134, i8* %133
br label %135
135: ; preds = %132, %128
%136 = getelementptr inbounds i8, i8* %116, i64 3
%137 = load i8, i8* %136
%138 = icmp eq i8 %137, 0
br i1 %138, label %142, label %139
139: ; preds = %135
%140 = getelementptr inbounds i8, i8* %115, i64 3
%141 = and i8 %137, %10
store i8 %141, i8* %140
br label %142
142: ; preds = %139, %135
%143 = getelementptr inbounds i8, i8* %115, i64 4
%144 = getelementptr inbounds i8, i8* %116, i64 4
%145 = icmp eq i8* %144, %12
br i1 %145, label %146, label %114
146: ; preds = %110, %142, %86, %5
ret void
}