This is an archive of the discontinued LLVM Phabricator instance.

[GlobalISel] Combine (xor (and x, y), y) -> (and (not x), y)
ClosedPublic

Authored by paquette on Sep 22 2020, 9:30 AM.

Details

Summary

When we see this:

%and = G_AND %x, %y
%xor = G_XOR %and, %y

Produce this:

%not = G_XOR %x, -1
%new_and = G_AND %not, %y

as long as we are guaranteed to eliminate the original G_AND.

Also matches all commuted forms. E.g.

%and = G_AND %y, %x
%xor = G_XOR %y, %and

will be matched as well.

Diff Detail

Event Timeline

paquette created this revision.Sep 22 2020, 9:30 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 22 2020, 9:30 AM
paquette requested review of this revision.Sep 22 2020, 9:30 AM
aemerson added inline comments.Sep 22 2020, 10:19 AM
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
2741

This code is a bit big-brain for me this morning. Simplify this to return X == SharedReg || Y == SharedReg?

paquette added inline comments.Sep 24 2020, 9:22 AM
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
2741

I don't think that would be correct. At this point, Y is set to the RHS of the G_AND. This is passed along as the second element of the pair when we get to applyXorOfAndWithSameReg.

So we'd end up folding

xor (and x, y), x) -> (and (not x), y)

if you let x =1 and y = 0 then

xor (and 1, 0), 1 = 1
and (not 1), 0 = 0
aemerson accepted this revision.Sep 24 2020, 11:35 AM

Maybe try to modify the existing G_XOR to be a G_AND instead of creating a new instruction?

This revision is now accepted and ready to land.Sep 24 2020, 11:35 AM