[PATCH] D71831: [PowerPC] Exploit the rldicl + rldicl when and with mask
Nemanja Ivanovic via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 30 05:55:22 PDT 2020
nemanjai added a comment.
In D71831#1938331 <https://reviews.llvm.org/D71831#1938331>, @steven.zhang wrote:
> In D71831#1936489 <https://reviews.llvm.org/D71831#1936489>, @nemanjai wrote:
>
> > 2. Rename `RotateRightClearLeft` to something like `RightJustifyRangeAndClear` as it appears that is what the function is doing.
>
>
> In ISA, the RLDICL is named as: "Rotate Left Doubleword Immediate then Clear Left". I am not sure if the right justify range make it more clear. Regarding to left or right, it is just a wrap rotate. The lambda here is trying to hide the detail that implement the right rotate with left rotate. Personally, I prefer the RotateRightClearLeft one, but also ok to the RightJustifyRangeAndClear if you insist.
I think we can retire this discussion quite easily by just removing the lambda. There isn't a whole lot of point to a lambda that is used only once. If it helped with readability I would be in favour of it, but I think it actually makes the code less readable.
In any case, I described the concise algorithm in pseudo-code not so much because I think it is a useful comment, but because I think that is how the function should flow. For example, isn't something like this much more readable:
bool PPCDAGToDAGISel::tryAsPairOfRLDICL(SDNode *N) {
assert(N->getOpcode() == ISD::AND && "ISD::AND SDNode expected");
uint64_t Imm64;
// Do nothing if it is 16-bit imm as the pattern in the .td file handles
// it well with "andi.".
if (!isInt64Immediate(N->getOperand(1).getNode(), Imm64) || isUInt<16>(Imm64))
return false;
SDLoc Loc(N);
SDValue Val = N->getOperand(0);
// Optimized with two rldicl's as follows:
// Add missing bits on left to the mask and check that the mask is a
// wrapped run of ones, i.e.
// Change pattern |0001111100000011111111|
// to |1111111100000011111111|.
unsigned NumOfLeadingZeros = countLeadingZeros(Imm64);
if (NumOfLeadingZeros != 0)
Imm64 |= maskLeadingOnes<uint64_t>(NumOfLeadingZeros);
unsigned MB, ME;
if (!isRunOfOnes64(Imm64, MB, ME))
return false;
// ME MB
// +----------------------+ +----------------------+
// |1111111100000011111111| -> |0000001111111111111111|
// +----------------------+ +----------------------+
// 0 63 0 63
// There are ME + 1 ones on the left and (MB - ME + 63) & 63 zeros in between.
unsigned OnesOnLeft = ME + 1;
unsigned ZerosInBetween = (MB - ME + 63) & 63;
// Rotate left by OnesOnLeft (so leading ones are now trailing ones) and clear
// on the left the bits that are already zeros in the mask.
Val = SDValue(CurDAG->getMachineNode(PPC::RLDICL, Loc, MVT::i64, Val,
getI64Imm(OnesOnLeft, Loc),
getI64Imm(ZerosInBetween, Loc)),
0);
// ME MB
// +----------------------+ +----------------------+
// |0000001111111111111111| -> |0001111100000011111111|
// +----------------------+ +----------------------+
// 0 63 0 63
// Rotate back by 64 - OnesOnLeft to undo previous rotate. Then clear on the
// left the number of ones we previously added.
SDValue Ops[] = {Val, getI64Imm(64 - OnesOnLeft, Loc),
getI64Imm(NumOfLeadingZeros, Loc)};
CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Ops);
return true;
}
Note that the above is just a sample of how I think the code should be structured for readability. While I am fairly sure it is semantically equivalent to what you have, I did not carefully verify this.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D71831/new/
https://reviews.llvm.org/D71831
More information about the llvm-commits
mailing list