Produce better code from maskW
authorMateusz Kowalczyk <fuuzetsu@fuuzetsu.co.uk>
Tue, 22 Jan 2019 04:38:16 +0000 (13:38 +0900)
committerDavid Feuer <David.Feuer@gmail.com>
Fri, 12 Apr 2019 20:20:51 +0000 (16:20 -0400)
commitca3406cc59c711c9230efe411bad02bee880f8f1
tree7942880a48a4c9e9071d3e7b5ef8be327034353c
parent2420e116dd78a82b288fb3b186ab87f018bf67c6
Produce better code from maskW

```
complement (m-1) `xor` m == -m `xor` m
```

Latter produces slightly better assembly.

```asm
movq %rdi, %rax
negq %rax
xorq %rdi, %rax
```

Indeed if we give

```cpp
uint64_t f(uint64_t m_aQU2) {
  return ((m_aQU2 - 1) ^ 18446744073709551615UL) ^ m_aQU2;
}
```

to clang and compile with optimisation, that's the ASM it spits out.
Translating it back to Haskell gives the solution from this branch.
Without same optimisation, even in Haskell it saves an instruction.

```hs
maskW :: Word -> Word
maskW m = complement (m-1) `xor` m

{-
movq %rax,%rbx
xorq $-1,%rbx
decq %rax
xorq %rbx,%rax
-}
```

```hs
maskMine :: Word -> Word
maskMine m = (-m) `xor` m

{-
movq %rax,%rbx
negq %rbx
xorq %rax,%rbx
-}
```
Data/IntMap/Internal.hs