Skip to content

Weaken xor to or under nand #58624

Open
Open
@scottmcm

Description

@scottmcm

Alive2 proof: https://alive2.llvm.org/ce/z/tMGuKE

define i1 @src(i1 %x, i1 %y) denormal-fp-math=ieee,ieee {
%start:
  %_4 = and i1 %x, %y
  %_3 = xor i1 %_4, 1
  assume i1 %_3 ; <-- because we know !(X & Y)
  %0 = xor i1 %x, %y ; <-- this X^Y
  ret i1 %0
}
=>
define i1 @tgt(i1 %x, i1 %y) denormal-fp-math=ieee,ieee {
%start:
  %_4 = and i1 %x, %y
  %_3 = xor i1 %_4, 1
  assume i1 %_3
  %0 = or i1 %x, %y ; <-- can be just X|Y
  ret i1 %0
}
Transformation seems to be correct!

It's also possible that, for normalization, this shouldn't always happen, so here's my non-minimized example: https://alive2.llvm.org/ce/z/_c36CA

In that one, replacing the xor with an or opened up a bunch of additional possibilities that ended up making a huge improvement in the generated assembly:

        test    edi, edi
        je      .LBB0_3
        test    esi, esi
        je      .LBB0_3
        cmp     edi, esi
        sete    al
        ret
 .LBB0_3:                                # %other
-       test    esi, esi
-       setne   cl
-       test    edi, edi
-       setne   al
-       xor     al, cl
-       xor     al, 1
+       or      edi, esi
+       sete    al
        ret

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions