[X86] Correct the implementation of BEXTR load folding to use the shift as the parent node and pass a separate root.

We were calling tryFoldLoad with the 'and' node was the root and parent node of the load. But the parent of the load should be the shift that proceeds the and. While the and node is correctly the root node.

To fix this I had to make tryFoldLoad take a separate use and root input. I've added a convenience version with the old signature to avoid updating the other call sites.

llvm-svn: 317720
This commit is contained in:
Craig Topper 2017-11-08 20:17:33 +00:00
parent fb0ebecf0e
commit 78a770402a
1 changed files with 14 additions and 6 deletions

View File

@ -226,11 +226,19 @@ namespace {
SDValue &NodeWithChain);
bool selectRelocImm(SDValue N, SDValue &Op);
bool tryFoldLoad(SDNode *P, SDValue N,
bool tryFoldLoad(SDNode *Root, SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment);
// Convience method where P is also root.
bool tryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment) {
return tryFoldLoad(P, P, N, Base, Scale, Index, Disp, Segment);
}
/// Implement addressing mode selection for inline asm expressions.
bool SelectInlineAsmMemoryOperand(const SDValue &Op,
unsigned ConstraintID,
@ -1886,13 +1894,13 @@ bool X86DAGToDAGISel::selectRelocImm(SDValue N, SDValue &Op) {
return true;
}
bool X86DAGToDAGISel::tryFoldLoad(SDNode *P, SDValue N,
bool X86DAGToDAGISel::tryFoldLoad(SDNode *Root, SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
SDValue &Index, SDValue &Disp,
SDValue &Segment) {
if (!ISD::isNON_EXTLoad(N.getNode()) ||
!IsProfitableToFold(N, P, P) ||
!IsLegalToFold(N, P, P, OptLevel))
!IsProfitableToFold(N, P, Root) ||
!IsLegalToFold(N, P, Root, OptLevel))
return false;
return selectAddr(N.getNode(),
@ -2402,12 +2410,12 @@ bool X86DAGToDAGISel::matchBEXTRFromAnd(SDNode *Node) {
MachineSDNode *NewNode;
SDValue Input = N0->getOperand(0);
SDValue Tmp0, Tmp1, Tmp2, Tmp3, Tmp4;
if (tryFoldLoad(Node, Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
if (tryFoldLoad(Node, N0.getNode(), Input, Tmp0, Tmp1, Tmp2, Tmp3, Tmp4)) {
SDValue Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Tmp4, New, Input.getOperand(0) };
SDVTList VTs = CurDAG->getVTList(NVT, MVT::Other);
NewNode = CurDAG->getMachineNode(MOpc, dl, VTs, Ops);
// Update the chain.
ReplaceUses(N1.getValue(1), SDValue(NewNode, 1));
ReplaceUses(Input.getValue(1), SDValue(NewNode, 1));
// Record the mem-refs
LoadSDNode *LoadNode = cast<LoadSDNode>(Input);
if (LoadNode) {