From 8a72c73032707c7b3c042b716286a1ac33720991 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 3 Jun 2013 17:39:46 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183132 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/AMDILISelDAGToDAG.cpp | 38 +++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/Target/R600/AMDILISelDAGToDAG.cpp b/lib/Target/R600/AMDILISelDAGToDAG.cpp index 00d7c8fa570..959d6621fba 100644 --- a/lib/Target/R600/AMDILISelDAGToDAG.cpp +++ b/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(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(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(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); + } } } -