diff options
| author | Tom Stellard <thomas.stellard@amd.com> | 2014-09-23 21:26:25 +0000 |
|---|---|---|
| committer | Tom Stellard <thomas.stellard@amd.com> | 2014-09-23 21:26:25 +0000 |
| commit | 73ae1cb59a4a3fe25c8678846816b37bfb87edfe (patch) | |
| tree | 21be006366c091b8a8e1d2ac25e6372477f0c65c /llvm/lib/Target/R600/SIISelLowering.cpp | |
| parent | bdf54a21b5e3392b431b6569007cb61689c76a3c (diff) | |
| download | bcm5719-llvm-73ae1cb59a4a3fe25c8678846816b37bfb87edfe.tar.gz bcm5719-llvm-73ae1cb59a4a3fe25c8678846816b37bfb87edfe.zip | |
R600/SI: Clean up checks for legality of immediate operands
There are new register classes VCSrc_* which represent operands that
can take an SGPR, VGPR or inline constant. The VSrc_* class is now used
to represent operands that can take an SGPR, VGPR, or a 32-bit
immediate.
This allows us to have more accurate checks for legality of
immediates, since before we had no way to distinguish between operands
that supported any 32-bit immediate and operands which could only
support inline constants.
llvm-svn: 218334
Diffstat (limited to 'llvm/lib/Target/R600/SIISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/R600/SIISelLowering.cpp | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/llvm/lib/Target/R600/SIISelLowering.cpp b/llvm/lib/Target/R600/SIISelLowering.cpp index cb7385d66fa..10b42750c13 100644 --- a/llvm/lib/Target/R600/SIISelLowering.cpp +++ b/llvm/lib/Target/R600/SIISelLowering.cpp @@ -1498,8 +1498,14 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N, /// \brief Test if RegClass is one of the VSrc classes static bool isVSrc(unsigned RegClass) { - return AMDGPU::VSrc_32RegClassID == RegClass || - AMDGPU::VSrc_64RegClassID == RegClass; + switch(RegClass) { + default: return false; + case AMDGPU::VSrc_32RegClassID: + case AMDGPU::VCSrc_32RegClassID: + case AMDGPU::VSrc_64RegClassID: + case AMDGPU::VCSrc_64RegClassID: + return true; + } } /// \brief Test if RegClass is one of the SSrc classes @@ -1611,10 +1617,9 @@ const TargetRegisterClass *SITargetLowering::getRegClassForNode( // If the COPY_TO_REGCLASS instruction is copying to a VSrc register // class, then the register class for the value could be either a // VReg or and SReg. In order to get a more accurate - if (OpClassID == AMDGPU::VSrc_32RegClassID || - OpClassID == AMDGPU::VSrc_64RegClassID) { + if (isVSrc(OpClassID)) return getRegClassForNode(DAG, Op.getOperand(0)); - } + return TRI.getRegClass(OpClassID); case AMDGPU::EXTRACT_SUBREG: { int SubIdx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); @@ -1648,14 +1653,23 @@ void SITargetLowering::ensureSRegLimit(SelectionDAG &DAG, SDValue &Operand, unsigned RegClass, bool &ScalarSlotUsed) const { - // First map the operands register class to a destination class - if (RegClass == AMDGPU::VSrc_32RegClassID) - RegClass = AMDGPU::VReg_32RegClassID; - else if (RegClass == AMDGPU::VSrc_64RegClassID) - RegClass = AMDGPU::VReg_64RegClassID; - else + if (!isVSrc(RegClass)) return; + // First map the operands register class to a destination class + switch (RegClass) { + case AMDGPU::VSrc_32RegClassID: + case AMDGPU::VCSrc_32RegClassID: + RegClass = AMDGPU::VReg_32RegClassID; + break; + case AMDGPU::VSrc_64RegClassID: + case AMDGPU::VCSrc_64RegClassID: + RegClass = AMDGPU::VReg_64RegClassID; + break; + default: + llvm_unreachable("Unknown vsrc reg class"); + } + // Nothing to do if they fit naturally if (fitsRegClass(DAG, Operand, RegClass)) return; @@ -1745,6 +1759,15 @@ SDNode *SITargetLowering::legalizeOperands(MachineSDNode *Node, // No scalar allowed when we have both VSrc and SSrc bool ScalarSlotUsed = HaveVSrc && HaveSSrc; + // If this instruction has an implicit use of VCC, then it can't use the + // constant bus. + for (unsigned i = 0, e = Desc->getNumImplicitUses(); i != e; ++i) { + if (Desc->ImplicitUses[i] == AMDGPU::VCC) { + ScalarSlotUsed = true; + break; + } + } + // Second go over the operands and try to fold them std::vector<SDValue> Ops; for (unsigned i = 0, e = Node->getNumOperands(), Op = NumDefs; |

