void _right_left_solid_dest_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_end - 1; source_row_ptr >= source_row_start;
       source_row_ptr--) {
    *destination_row_ptr = (*destination_row_ptr & ~destMask) | *source_row_ptr;
    destination_row_ptr++;
  }
}


x86 assembly (clang, -O0):
<_right_left_solid_dest_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    -0x10(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x8(%rbp),%rax
jb     1176 <_right_left_solid_dest_mask+0x76>
mov    -0x30(%rbp),%rax
movzbl (%rax),%eax
mov    -0x20(%rbp),%ecx
xor    $0xffffffff,%ecx
and    %ecx,%eax
mov    -0x28(%rbp),%rcx
movzbl (%rcx),%ecx
or     %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    $0xffffffffffffffff,%rax
mov    %rax,-0x28(%rbp)
jmp    112b <_right_left_solid_dest_mask+0x2b>
pop    %rbp
ret

x86 assembly (clang, -O2):
<_right_left_solid_dest_mask>:
push   %r15
push   %r14
push   %rbx
lea    -0x1(%rsi),%rax
cmp    %rdi,%rax
jb     1177 <_right_left_solid_dest_mask+0x77>
mov    %rdi,%r10
neg    %r10
mov    $0x1,%r9d
sub    %rsi,%r9
cmp    %r9,%r10
cmova  %r10,%r9
not    %r8b
add    %rsi,%r9
cmp    $0x8,%r9
jb     1159 <_right_left_solid_dest_mask+0x59>
lea    -0x1(%rdi),%rcx
lea    -0x2(%rsi),%rbx
cmp    %rbx,%rcx
cmovb  %rcx,%rbx
cmp    %rsi,%rdx
jae    117d <_right_left_solid_dest_mask+0x7d>
mov    %rbx,%rcx
not    %rcx
add    %rsi,%rcx
add    %rdx,%rcx
add    $0x1,%rbx
cmp    %rcx,%rbx
jae    117d <_right_left_solid_dest_mask+0x7d>
mov    %rdx,%rcx
nopl   0x0(%rax)
movzbl (%rcx),%edx
and    %r8b,%dl
or     (%rax),%dl
mov    %dl,(%rcx)
add    $0x1,%rcx
add    $0xffffffffffffffff,%rax
cmp    %rdi,%rax
jae    1160 <_right_left_solid_dest_mask+0x60>
pop    %rbx
pop    %r14
pop    %r15
ret
movzbl %r8b,%r11d
cmp    $0x20,%r9
jae    118f <_right_left_solid_dest_mask+0x8f>
xor    %r15d,%r15d
jmp    126e <_right_left_solid_dest_mask+0x16e>
mov    %r9,%r15
and    $0xffffffffffffffe0,%r15
movd   %r11d,%xmm0
punpcklbw %xmm0,%xmm0
pshuflw $0x0,%xmm0,%xmm0
pshufd $0x0,%xmm0,%xmm0
lea    0x10(%rdx),%rcx
mov    %r15,%r14
neg    %r14
xor    %ebx,%ebx
pxor   %xmm1,%xmm1
nopl   0x0(%rax)
movdqu -0x10(%rcx),%xmm2
movdqu (%rcx),%xmm3
movdqu -0x20(%rsi,%rbx,1),%xmm4
movdqu -0x10(%rsi,%rbx,1),%xmm5
movdqa %xmm5,%xmm6
punpcklbw %xmm1,%xmm6
pshufd $0x4e,%xmm6,%xmm6
pshuflw $0x1b,%xmm6,%xmm6
pshufhw $0x1b,%xmm6,%xmm6
punpckhbw %xmm1,%xmm5
pshufd $0x4e,%xmm5,%xmm5
pshuflw $0x1b,%xmm5,%xmm5
pshufhw $0x1b,%xmm5,%xmm5
packuswb %xmm6,%xmm5
movdqa %xmm4,%xmm6
punpcklbw %xmm1,%xmm6
pshufd $0x4e,%xmm6,%xmm6
pshuflw $0x1b,%xmm6,%xmm6
pshufhw $0x1b,%xmm6,%xmm6
punpckhbw %xmm1,%xmm4
pshufd $0x4e,%xmm4,%xmm4
pshuflw $0x1b,%xmm4,%xmm4
pshufhw $0x1b,%xmm4,%xmm4
packuswb %xmm6,%xmm4
pand   %xmm0,%xmm2
por    %xmm5,%xmm2
pand   %xmm0,%xmm3
por    %xmm4,%xmm3
movdqu %xmm2,-0x10(%rcx)
movdqu %xmm3,(%rcx)
add    $0x20,%rcx
add    $0xffffffffffffffe0,%rbx
cmp    %rbx,%r14
jne    11c0 <_right_left_solid_dest_mask+0xc0>
cmp    %r15,%r9
je     1177 <_right_left_solid_dest_mask+0x77>
test   $0x18,%r9b
je     12f9 <_right_left_solid_dest_mask+0x1f9>
mov    $0x1,%r14d
sub    %rsi,%r14
cmp    %r14,%r10
cmova  %r10,%r14
add    %rsi,%r14
mov    %r14,%rbx
and    $0xfffffffffffffff8,%rbx
sub    %rbx,%rax
lea    (%rdx,%rbx,1),%rcx
movd   %r11d,%xmm0
punpcklbw %xmm0,%xmm0
pshuflw $0x0,%xmm0,%xmm0
add    %r15,%rdx
neg    %r15
and    $0xfffffffffffffff8,%r9
neg    %r9
pxor   %xmm1,%xmm1
xchg   %ax,%ax
movq   (%rdx),%xmm2
pand   %xmm0,%xmm2
movq   -0x8(%rsi,%r15,1),%xmm3
punpcklbw %xmm1,%xmm3
pshufd $0x4e,%xmm3,%xmm3
pshuflw $0x1b,%xmm3,%xmm3
pshufhw $0x1b,%xmm3,%xmm3
packuswb %xmm3,%xmm3
por    %xmm2,%xmm3
movq   %xmm3,(%rdx)
add    $0x8,%rdx
add    $0xfffffffffffffff8,%r15
cmp    %r15,%r9
jne    12b0 <_right_left_solid_dest_mask+0x1b0>
cmp    %rbx,%r14
jne    1160 <_right_left_solid_dest_mask+0x60>
jmp    1177 <_right_left_solid_dest_mask+0x77>
add    %r15,%rdx
sub    %r15,%rax
jmp    1159 <_right_left_solid_dest_mask+0x59>

LLVM IR (-O0):
define void @_right_left_solid_dest_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** %7
%15 = getelementptr inbounds i8, i8* %14, i64 -1
store i8* %15, i8** %11
br label %16
16: ; preds = %35, %5
%17 = load i8*, i8** %11
%18 = load i8*, i8** %6
%19 = icmp uge i8* %17, %18
br i1 %19, label %20, label %38
20: ; preds = %16
%21 = load i8*, i8** %12
%22 = load i8, i8* %21
%23 = zext i8 %22 to i32
%24 = load i32, i32* %10
%25 = xor i32 %24, -1
%26 = and i32 %23, %25
%27 = load i8*, i8** %11
%28 = load i8, i8* %27
%29 = zext i8 %28 to i32
%30 = or i32 %26, %29
%31 = trunc i32 %30 to i8
%32 = load i8*, i8** %12
store i8 %31, i8* %32
%33 = load i8*, i8** %12
%34 = getelementptr inbounds i8, i8* %33, i32 1
store i8* %34, i8** %12
br label %35
35: ; preds = %20
%36 = load i8*, i8** %11
%37 = getelementptr inbounds i8, i8* %36, i32 -1
store i8* %37, i8** %11
br label %16
38: ; preds = %16
ret void
}

LLVM IR (-O2):
define void @_right_left_solid_dest_mask(i8* readnone %0, i8* %1, i8* nocapture %2, i32 %3, i32 %4) {
%6 = ptrtoint i8* %0 to i64
%7 = ptrtoint i8* %1 to i64
%8 = ptrtoint i8* %1 to i64
%9 = ptrtoint i8* %0 to i64
%10 = ptrtoint i8* %1 to i64
%11 = getelementptr inbounds i8, i8* %1, i64 -1
%12 = icmp ult i8* %11, %0
br i1 %12, label %121, label %13
13: ; preds = %5
%14 = ptrtoint i8* %0 to i64
%15 = trunc i32 %4 to i8
%16 = xor i8 %15, -1
%17 = sub i64 0, %14
%18 = sub i64 1, %8
%19 = call i64 @llvm.umax.i64(i64 %17, i64 %18)
%20 = add i64 %19, %8
%21 = icmp ult i64 %20, 8
br i1 %21, label %108, label %22
22: ; preds = %13
%23 = add i64 %9, -1
%24 = add i64 %10, -2
%25 = call i64 @llvm.umin.i64(i64 %23, i64 %24)
%26 = xor i64 %25, -1
%27 = add i64 %26, %10
%28 = getelementptr i8, i8* %2, i64 %27
%29 = add i64 %25, 1
%30 = sub i64 %29, %10
%31 = getelementptr i8, i8* %1, i64 %30
%32 = icmp ult i8* %2, %1
%33 = icmp ult i8* %31, %28
%34 = and i1 %32, %33
br i1 %34, label %108, label %35
35: ; preds = %22
%36 = icmp ult i64 %20, 32
br i1 %36, label %78, label %37
37: ; preds = %35
%38 = and i64 %20, -32
%39 = insertelement <16 x i8> poison, i8 %16, i64 0
%40 = shufflevector <16 x i8> %39, <16 x i8> poison, <16 x i32> zeroinitializer
%41 = insertelement <16 x i8> poison, i8 %16, i64 0
%42 = shufflevector <16 x i8> %41, <16 x i8> poison, <16 x i32> zeroinitializer
br label %43
43: ; preds = %43, %37
%44 = phi i64 [ 0, %37 ], [ %68, %43 ]
%45 = sub i64 0, %44
%46 = getelementptr i8, i8* %11, i64 %45
%47 = getelementptr i8, i8* %2, i64 %44
%48 = bitcast i8* %47 to <16 x i8>*
%49 = load <16 x i8>, <16 x i8>* %48
%50 = getelementptr i8, i8* %47, i64 16
%51 = bitcast i8* %50 to <16 x i8>*
%52 = load <16 x i8>, <16 x i8>* %51
%53 = getelementptr i8, i8* %46, i64 -15
%54 = bitcast i8* %53 to <16 x i8>*
%55 = load <16 x i8>, <16 x i8>* %54
%56 = shufflevector <16 x i8> %55, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%57 = getelementptr i8, i8* %46, i64 -16
%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 = shufflevector <16 x i8> %60, <16 x i8> poison, <16 x i32> <i32 15, i32 14, i32 13, i32 12, i32 11, i32 10, i32 9, i32 8, i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%62 = and <16 x i8> %49, %40
%63 = and <16 x i8> %52, %42
%64 = or <16 x i8> %62, %56
%65 = or <16 x i8> %63, %61
%66 = bitcast i8* %47 to <16 x i8>*
store <16 x i8> %64, <16 x i8>* %66
%67 = bitcast i8* %50 to <16 x i8>*
store <16 x i8> %65, <16 x i8>* %67
%68 = add nuw i64 %44, 32
%69 = icmp eq i64 %68, %38
br i1 %69, label %70, label %43
70: ; preds = %43
%71 = icmp eq i64 %20, %38
br i1 %71, label %121, label %72
72: ; preds = %70
%73 = getelementptr i8, i8* %2, i64 %38
%74 = sub i64 0, %38
%75 = getelementptr i8, i8* %11, i64 %74
%76 = and i64 %20, 24
%77 = icmp eq i64 %76, 0
br i1 %77, label %108, label %78
78: ; preds = %35, %72
%79 = phi i64 [ %38, %72 ], [ 0, %35 ]
%80 = sub i64 0, %6
%81 = sub i64 1, %7
%82 = call i64 @llvm.umax.i64(i64 %80, i64 %81)
%83 = add i64 %82, %7
%84 = and i64 %83, -8
%85 = sub i64 0, %84
%86 = getelementptr i8, i8* %11, i64 %85
%87 = getelementptr i8, i8* %2, i64 %84
%88 = insertelement <8 x i8> poison, i8 %16, i64 0
%89 = shufflevector <8 x i8> %88, <8 x i8> poison, <8 x i32> zeroinitializer
%90 = getelementptr i8, i8* %1, i64 -8
br label %91
91: ; preds = %91, %78
%92 = phi i64 [ %79, %78 ], [ %104, %91 ]
%93 = sub i64 0, %92
%94 = getelementptr i8, i8* %2, i64 %92
%95 = bitcast i8* %94 to <8 x i8>*
%96 = load <8 x i8>, <8 x i8>* %95
%97 = getelementptr i8, i8* %90, i64 %93
%98 = bitcast i8* %97 to <8 x i8>*
%99 = load <8 x i8>, <8 x i8>* %98
%100 = shufflevector <8 x i8> %99, <8 x i8> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
%101 = and <8 x i8> %96, %89
%102 = or <8 x i8> %101, %100
%103 = bitcast i8* %94 to <8 x i8>*
store <8 x i8> %102, <8 x i8>* %103
%104 = add nuw i64 %92, 8
%105 = icmp eq i64 %104, %84
br i1 %105, label %106, label %91
106: ; preds = %91
%107 = icmp eq i64 %83, %84
br i1 %107, label %121, label %108
108: ; preds = %22, %13, %72, %106
%109 = phi i8* [ %11, %13 ], [ %11, %22 ], [ %75, %72 ], [ %86, %106 ]
%110 = phi i8* [ %2, %13 ], [ %2, %22 ], [ %73, %72 ], [ %87, %106 ]
br label %111
111: ; preds = %108, %111
%112 = phi i8* [ %119, %111 ], [ %109, %108 ]
%113 = phi i8* [ %118, %111 ], [ %110, %108 ]
%114 = load i8, i8* %113
%115 = load i8, i8* %112
%116 = and i8 %114, %16
%117 = or i8 %116, %115
store i8 %117, i8* %113
%118 = getelementptr inbounds i8, i8* %113, i64 1
%119 = getelementptr inbounds i8, i8* %112, i64 -1
%120 = icmp ult i8* %119, %0
br i1 %120, label %121, label %111
121: ; preds = %111, %70, %106, %5
ret void
}