Issue 71390
Summary Manual application of De Morgan's laws results in better emit
Labels new issue
Assignees
Reporter Validark
    I had some code and wanted to wrap the return statement in parenthesis and do a bitwise negation to see if the emit is better. Here is the code after the aforementioned modification:
```zig
export fn swarControlCharMask1(v: u64) u64 {
 const ones: u64 = 0x0101010101010101;
    const mask = ones * 0x7F;
 const low_7_bits = v & mask;
    const del = low_7_bits + ones;
 const non_control_or_space = low_7_bits + ones * (0x80 - 0x21);
    return ~(~v & (del | ~non_control_or_space));
}
```

What I got was:

```asm
swarControlCharMask1:
        movabs  rcx, 9187201950435737471
        movabs  rdx, 72340172838076673
 movabs  rax, -6872316419617283936
        and     rcx, rdi
        add rdx, rcx
        sub     rax, rcx
        or      rax, rdx
 not     rax
        or      rax, rdi
        ret
```

I had a hunch this was not the best the compiler could do, so I manually applied De Morgan's laws by inverting the bits of each operand and changing the bitwise OR's to AND's and the AND's to OR's:

```zig
export fn swarControlCharMask2(v: u64) u64 {
    const ones: u64 = 0x0101010101010101;
    const mask = ones * 0x7F;
    const low_7_bits = v & mask;
    const del = low_7_bits + ones;
    const non_control_or_space = low_7_bits + ones * (0x80 - 0x21);
    return (v | (~del & non_control_or_space));
}
```

And, sure enough, we save an instruction:

```asm
swarControlCharMask2:
        movabs rcx, 9187201950435737471
        movabs  rdx, 6872316419617283935
 movabs  rax, -72340172838076674
        and     rcx, rdi
        add rdx, rcx
        sub     rax, rcx
        and     rax, rdx
 or      rax, rdi
        ret
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to