This is an archive of the discontinued LLVM Phabricator instance.

[X86] Teach PostprocessISelDAG to fold ANDrm+TESTrr when chain result is used.
ClosedPublic

Authored by craig.topper on Aug 3 2022, 2:41 PM.

Details

Summary

The isOnlyUserOf prevented the fold if the chain result had any
users. What we really care about is the the data result from the
AND is only used by the TEST, and the flags results from the ANDs
aren't used at all. It's ok if the chain has users, we just need
to replace those users with the chain from the TESTrm.

Diff Detail

Event Timeline

craig.topper created this revision.Aug 3 2022, 2:41 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 3 2022, 2:41 PM
craig.topper requested review of this revision.Aug 3 2022, 2:41 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 3 2022, 2:41 PM
LuoYuanke added inline comments.Aug 3 2022, 7:25 PM
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
1490

AND32rm has 3 output. This check 1st output, should we also check 2nd output (EFLAGS) and only leave the 3rd (chain) output be used freely?

craig.topper added inline comments.Aug 3 2022, 7:26 PM
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
1490

See line 1496 and 1507. We have to check the opcode before we can tell if output 1 exists.

LuoYuanke added inline comments.Aug 3 2022, 7:37 PM
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
1507

Is the EFLAGS of AND32rm the same to the EFLAGS produced by TEST32mr?

craig.topper added inline comments.Aug 3 2022, 7:51 PM
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
1507

That's not quite the right question to ask because the EFLAGS of AND32rm were never used.

The question to ask is does TEST32mr have the same EFLAGs as a TEST32rr of the AND32rm result register. Remember that the TEST32rr is doing an AND of the input with itself.

They both internally do an AND and discard the result, but keep the flags which are calculated form the result. For TEST32mr this result will computed by ANDing the two inputs from the original AND32rm. For the TEST32rr it will AND a value with itself so the resulting values is just whatever original AND32rm computed. So for both TEST instruction this result value is the same.

Let's look at each of the 6 flags
C - both set to 0
O - both set to 0
S - set to the sign bit of the result of the internal AND. Both produce the same result so the flag is the same
P - set based on the parity of the lower 8 bits of the result of the internal AND. Both produce the same result so the flag is the same
A - undefined and the compiler never uses it anyway
Z - set if the result of the internal AND is zero. Both produce the same result so the flag is the same

LuoYuanke added inline comments.Aug 3 2022, 8:17 PM
llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
1507

Thank Craig for explaining. If And->hasAnyUseOfValue(1) is true. Can Value 1 be replaced by SDValue(Test, 0)?

LuoYuanke accepted this revision.Aug 3 2022, 8:48 PM

LGTM except some question that not relevant to this patch.

This revision is now accepted and ready to land.Aug 3 2022, 8:48 PM
This revision was landed with ongoing or failed builds.Aug 3 2022, 9:03 PM
This revision was automatically updated to reflect the committed changes.