diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-06-14 15:22:25 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-06-14 15:22:25 +0000 |
commit | c2864c0de07efb5451d32d27a7d4ff2984830929 (patch) | |
tree | 90c7519d9b67b5cb7d7acd94ed21b4cffaccf105 /llvm/lib/CodeGen | |
parent | 7ea378b940b4c4d0690a67679c7d291743e3c8ed (diff) | |
download | bcm5719-llvm-c2864c0de07efb5451d32d27a7d4ff2984830929.tar.gz bcm5719-llvm-c2864c0de07efb5451d32d27a7d4ff2984830929.zip |
GlobalISel: Avoid producing Illegal copies in RegBankSelect
Avoid producing illegal register bank copies for reg_sequence and
phi. The default implementation assumes it is possible to pick any
operand's bank and use that for the result, introducing a copy for
operands with a different bank. This does not check for illegal
copies. It is not legal to introduce a VGPR->SGPR copy, so any VGPR
operand requires the result to be a VGPR.
The changes in getInstrMappingImpl aren't strictly necessary, since
AMDGPU now just bypasses this for reg_sequence/phi. This could be
replaced with an assert in case other targets run into this. It is
currently responsible for producing the error for unsatisfiable
copies, but this will be better served with a verifier check.
For phis, for now assume any undetermined operands must be
VGPRs. Eventually, this needs to be able to defer mapping these
operations. This also does not yet have a way to check for whether the
block is in a divergent region.
llvm-svn: 363410
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp index 9542c1fe1fc..afab9380af1 100644 --- a/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp @@ -220,18 +220,35 @@ RegisterBankInfo::getInstrMappingImpl(const MachineInstr &MI) const { } else { OperandsMapping[0] = ValMapping; } + } - CompleteMapping = true; + // The default handling assumes any register bank can be copied to any + // other. If this isn't the case, the target should specially deal with + // reg_sequence/phi. There may also be unsatisfiable copies. + for (; OpIdx != EndIdx; ++OpIdx) { + const MachineOperand &MO = MI.getOperand(OpIdx); + if (!MO.isReg()) + continue; + unsigned Reg = MO.getReg(); + if (!Reg) + continue; + + const RegisterBank *AltRegBank = getRegBank(Reg, MRI, TRI); + if (cannotCopy(*CurRegBank, *AltRegBank, getSizeInBits(Reg, MRI, TRI))) + return getInvalidInstructionMapping(); } + CompleteMapping = true; break; } + OperandsMapping[OpIdx] = ValMapping; } - if (IsCopyLike && !CompleteMapping) + if (IsCopyLike && !CompleteMapping) { // No way to deduce the type from what we have. return getInvalidInstructionMapping(); + } assert(CompleteMapping && "Setting an uncomplete mapping"); return getInstructionMapping( @@ -390,8 +407,12 @@ RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { RegisterBankInfo::InstructionMappings RegisterBankInfo::getInstrPossibleMappings(const MachineInstr &MI) const { InstructionMappings PossibleMappings; - // Put the default mapping first. - PossibleMappings.push_back(&getInstrMapping(MI)); + const auto &Mapping = getInstrMapping(MI); + if (Mapping.isValid()) { + // Put the default mapping first. + PossibleMappings.push_back(&Mapping); + } + // Then the alternative mapping, if any. InstructionMappings AltMappings = getInstrAlternativeMappings(MI); for (const InstructionMapping *AltMapping : AltMappings) |