void invert(int firstBit, int bits, char binary[bits]) {
  for (int i = firstBit; i < bits; i++) {
    if (binary[i] == '1')
      binary[i] = '0';
    else
      binary[i] = '1';
  }
}


x86 assembly (clang, -O0):
<invert>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %rdx,-0x10(%rbp)
mov    -0x4(%rbp),%eax
mov    %eax,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    1165 <invert+0x65>
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x31,%eax
jne    1146 <invert+0x46>
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movb   $0x30,(%rax,%rcx,1)
jmp    1152 <invert+0x52>
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movb   $0x31,(%rax,%rcx,1)
jmp    1157 <invert+0x57>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1114 <invert+0x14>
pop    %rbp
ret

x86 assembly (clang, -O2):
<invert>:
cmp    %esi,%edi
jge    1275 <invert+0x175>
movslq %edi,%r11
movslq %esi,%r10
mov    %r10,%r8
sub    %r11,%r8
cmp    $0x8,%r8
jae    1122 <invert+0x22>
mov    %r11,%rsi
jmp    1260 <invert+0x160>
cmp    $0x20,%r8
jae    112f <invert+0x2f>
xor    %edi,%edi
jmp    120a <invert+0x10a>
mov    %r8,%rdi
and    $0xffffffffffffffe0,%rdi
lea    -0x20(%rdi),%rax
mov    %rax,%r9
shr    $0x5,%r9
add    $0x1,%r9
test   %rax,%rax
je     1244 <invert+0x144>
mov    %r9,%rax
and    $0xfffffffffffffffe,%rax
lea    (%r11,%rdx,1),%rcx
add    $0x30,%rcx
xor    %esi,%esi
movdqa 0xe99(%rip),%xmm0
nopw   0x0(%rax,%rax,1)
movdqu -0x30(%rcx,%rsi,1),%xmm1
movdqu -0x20(%rcx,%rsi,1),%xmm2
movdqu -0x10(%rcx,%rsi,1),%xmm3
movdqu (%rcx,%rsi,1),%xmm4
pcmpeqb %xmm0,%xmm1
paddb  %xmm0,%xmm1
pcmpeqb %xmm0,%xmm2
paddb  %xmm0,%xmm2
movdqu %xmm1,-0x30(%rcx,%rsi,1)
movdqu %xmm2,-0x20(%rcx,%rsi,1)
pcmpeqb %xmm0,%xmm3
paddb  %xmm0,%xmm3
pcmpeqb %xmm0,%xmm4
paddb  %xmm0,%xmm4
movdqu %xmm3,-0x10(%rcx,%rsi,1)
movdqu %xmm4,(%rcx,%rsi,1)
add    $0x40,%rsi
add    $0xfffffffffffffffe,%rax
jne    1170 <invert+0x70>
test   $0x1,%r9b
je     11ff <invert+0xff>
add    %r11,%rsi
movdqu (%rdx,%rsi,1),%xmm0
movdqu 0x10(%rdx,%rsi,1),%xmm1
movdqa 0xe1c(%rip),%xmm2
pcmpeqb %xmm2,%xmm0
paddb  %xmm2,%xmm0
pcmpeqb %xmm2,%xmm1
paddb  %xmm2,%xmm1
movdqu %xmm0,(%rdx,%rsi,1)
movdqu %xmm1,0x10(%rdx,%rsi,1)
cmp    %rdi,%r8
je     1275 <invert+0x175>
test   $0x18,%r8b
je     124e <invert+0x14e>
mov    %r8,%rax
and    $0xfffffffffffffff8,%rax
lea    (%rax,%r11,1),%rsi
add    %rdx,%r11
movdqa 0xdf0(%rip),%xmm0
movq   (%r11,%rdi,1),%xmm1
pcmpeqb %xmm0,%xmm1
paddb  %xmm0,%xmm1
movq   %xmm1,(%r11,%rdi,1)
add    $0x8,%rdi
cmp    %rdi,%rax
jne    1220 <invert+0x120>
cmp    %rax,%r8
jne    1260 <invert+0x160>
jmp    1275 <invert+0x175>
xor    %esi,%esi
test   $0x1,%r9b
jne    11ce <invert+0xce>
jmp    11ff <invert+0xff>
add    %r11,%rdi
mov    %rdi,%rsi
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
cmpb   $0x31,(%rdx,%rsi,1)
sete   %al
xor    $0x31,%al
mov    %al,(%rdx,%rsi,1)
add    $0x1,%rsi
cmp    %rsi,%r10
jne    1260 <invert+0x160>
ret

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

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