[RISCV] Handle redundant SplitF64+BuildPairF64 pairs in a DAGCombine

r343712 performed this optimisation during instruction selection. As Eli 
Friedman pointed out in post-commit review, implementing this as a DAGCombine 
might allow opportunities for further optimisations.

llvm-svn: 343741
This commit is contained in:
Alex Bradbury 2018-10-03 23:30:16 +00:00
parent 150ca5309e
commit 5ac0a2fc48
3 changed files with 20 additions and 12 deletions

View File

@ -96,18 +96,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
ReplaceNode(Node, CurDAG->getMachineNode(RISCV::ADDI, DL, VT, TFI, Imm));
return;
}
case RISCVISD::SplitF64: {
// If the input to SplitF64 is just BuildPairF64 then the operation is
// redundant. Instead, use BuildPairF64's operands directly. This pattern
// can't be written in tablegen due to the multiple outputs.
SDValue Op0 = Node->getOperand(0);
if (Op0->getOpcode() != RISCVISD::BuildPairF64)
break;
ReplaceUses(SDValue(Node, 0), Op0.getOperand(0));
ReplaceUses(SDValue(Node, 1), Op0.getOperand(1));
CurDAG->RemoveDeadNode(Node);
return;
}
}
// Select the default instruction.

View File

@ -494,6 +494,24 @@ SDValue RISCVTargetLowering::LowerRETURNADDR(SDValue Op,
return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, XLenVT);
}
SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
DAGCombinerInfo &DCI) const {
switch (N->getOpcode()) {
default:
break;
case RISCVISD::SplitF64: {
// If the input to SplitF64 is just BuildPairF64 then the operation is
// redundant. Instead, use BuildPairF64's operands directly.
SDValue Op0 = N->getOperand(0);
if (Op0->getOpcode() != RISCVISD::BuildPairF64)
break;
return DCI.CombineTo(N, Op0.getOperand(0), Op0.getOperand(1));
}
}
return SDValue();
}
static MachineBasicBlock *emitSplitF64Pseudo(MachineInstr &MI,
MachineBasicBlock *BB) {
assert(MI.getOpcode() == RISCV::SplitF64Pseudo && "Unexpected instruction");

View File

@ -58,6 +58,8 @@ public:
// Provide custom lowering hooks for some operations.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
// This method returns the name of a target specific DAG node.
const char *getTargetNodeName(unsigned Opcode) const override;