summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/R600/SIISelLowering.cpp
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2014-09-23 21:26:25 +0000
committerTom Stellard <thomas.stellard@amd.com>2014-09-23 21:26:25 +0000
commit73ae1cb59a4a3fe25c8678846816b37bfb87edfe (patch)
tree21be006366c091b8a8e1d2ac25e6372477f0c65c /llvm/lib/Target/R600/SIISelLowering.cpp
parentbdf54a21b5e3392b431b6569007cb61689c76a3c (diff)
downloadbcm5719-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.cpp45
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;
OpenPOWER on IntegriCloud