summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2013-06-03 17:39:46 +0000
committerTom Stellard <thomas.stellard@amd.com>2013-06-03 17:39:46 +0000
commit2183b70523b86c0e568ef6efb3c7a2cecdf104bf (patch)
tree72d6636693d3b51f87fe8c75d56305cf42e926b8
parent07a10a3d3f51c3a2a2cf83144d678d22cf2595e4 (diff)
downloadbcm5719-llvm-2183b70523b86c0e568ef6efb3c7a2cecdf104bf.tar.gz
bcm5719-llvm-2183b70523b86c0e568ef6efb3c7a2cecdf104bf.zip
R600/SI: Fixup CopyToReg register class in PostprocessISelDAG()
The CopyToReg nodes will sometimes try to copy a value from a VGPR to an SGPR. This kind of copy is not possible, so we need to detect VGPR->SGPR copies and do something else. The current strategy is to replace these copies with VGPR->VGPR copies and hope that all the users of CopyToReg can accept VGPRs as arguments. llvm-svn: 183132
-rw-r--r--llvm/lib/Target/R600/AMDILISelDAGToDAG.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/llvm/lib/Target/R600/AMDILISelDAGToDAG.cpp b/llvm/lib/Target/R600/AMDILISelDAGToDAG.cpp
index 00d7c8fa570..959d6621fba 100644
--- a/llvm/lib/Target/R600/AMDILISelDAGToDAG.cpp
+++ b/llvm/lib/Target/R600/AMDILISelDAGToDAG.cpp
@@ -18,6 +18,7 @@
#include "R600InstrInfo.h"
#include "SIISelLowering.h"
#include "llvm/ADT/ValueMap.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
@@ -649,18 +650,45 @@ bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base,
void AMDGPUDAGToDAGISel::PostprocessISelDAG() {
+ if (Subtarget.device()->getGeneration() < AMDGPUDeviceInfo::HD7XXX) {
+ return;
+ }
+
// Go over all selected nodes and try to fold them a bit more
const AMDGPUTargetLowering& Lowering = ((const AMDGPUTargetLowering&)TLI);
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
E = CurDAG->allnodes_end(); I != E; ++I) {
- MachineSDNode *Node = dyn_cast<MachineSDNode>(I);
- if (!Node)
+ SDNode *Node = I;
+ switch (Node->getOpcode()) {
+ // Fix the register class in copy to CopyToReg nodes - ISel will always
+ // use SReg classes for 64-bit copies, but this is not always what we want.
+ case ISD::CopyToReg: {
+ unsigned Reg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
+ SDValue Val = Node->getOperand(2);
+ const TargetRegisterClass *RC = RegInfo->getRegClass(Reg);
+ if (RC != &AMDGPU::SReg_64RegClass) {
+ continue;
+ }
+
+ if (!Val.getNode()->isMachineOpcode()) {
+ continue;
+ }
+
+ const MCInstrDesc Desc = TM.getInstrInfo()->get(Val.getNode()->getMachineOpcode());
+ const TargetRegisterInfo *TRI = TM.getRegisterInfo();
+ RegInfo->setRegClass(Reg, TRI->getRegClass(Desc.OpInfo[0].RegClass));
+ continue;
+ }
+ }
+
+ MachineSDNode *MachineNode = dyn_cast<MachineSDNode>(I);
+ if (!MachineNode)
continue;
- SDNode *ResNode = Lowering.PostISelFolding(Node, *CurDAG);
- if (ResNode != Node)
+ SDNode *ResNode = Lowering.PostISelFolding(MachineNode, *CurDAG);
+ if (ResNode != Node) {
ReplaceUses(Node, ResNode);
+ }
}
}
-
OpenPOWER on IntegriCloud