diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp index 396d64625fb5c..43cfcee42705f 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalize.cpp @@ -418,7 +418,7 @@ bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) { const RegBankLegalizeRules &RBLRules = getRules(ST, MRI); // Logic that does legalization based on IDs assigned to Opcode. - RegBankLegalizeHelper RBLHelper(B, MUI, RBI, RBLRules); + RegBankLegalizeHelper RBLHelper(B, MUI, RBI, TPC, RBLRules); SmallVector AllInst; @@ -435,7 +435,8 @@ bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) { unsigned Opc = MI->getOpcode(); // Insert point for use operands needs some calculation. if (Opc == AMDGPU::G_PHI) { - RBLHelper.applyMappingPHI(*MI); + if (!RBLHelper.applyMappingPHI(*MI)) + return false; continue; } @@ -466,7 +467,8 @@ bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) { // S1 rules are in RegBankLegalizeRules. } - RBLHelper.findRuleAndApplyMapping(*MI); + if (!RBLHelper.findRuleAndApplyMapping(*MI)) + return false; } // Sgpr S1 clean up combines: diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp index 123fc5bf37a19..5666d87f7c9b8 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.cpp @@ -31,29 +31,47 @@ using namespace AMDGPU; RegBankLegalizeHelper::RegBankLegalizeHelper( MachineIRBuilder &B, const MachineUniformityInfo &MUI, - const RegisterBankInfo &RBI, const RegBankLegalizeRules &RBLRules) - : ST(B.getMF().getSubtarget()), B(B), MRI(*B.getMRI()), - MUI(MUI), RBI(RBI), RBLRules(RBLRules), IsWave32(ST.isWave32()), + const RegisterBankInfo &RBI, const TargetPassConfig &TPC, + const RegBankLegalizeRules &RBLRules) + : MF(B.getMF()), ST(MF.getSubtarget()), B(B), + MRI(*B.getMRI()), MUI(MUI), RBI(RBI), TPC(TPC), MORE(MF, nullptr), + RBLRules(RBLRules), IsWave32(ST.isWave32()), SgprRB(&RBI.getRegBank(AMDGPU::SGPRRegBankID)), VgprRB(&RBI.getRegBank(AMDGPU::VGPRRegBankID)), VccRB(&RBI.getRegBank(AMDGPU::VCCRegBankID)) {} -void RegBankLegalizeHelper::findRuleAndApplyMapping(MachineInstr &MI) { - const SetOfRulesForOpcode &RuleSet = RBLRules.getRulesForOpc(MI); - const RegBankLLTMapping &Mapping = RuleSet.findMappingForMI(MI, MRI, MUI); +bool RegBankLegalizeHelper::findRuleAndApplyMapping(MachineInstr &MI) { + const SetOfRulesForOpcode *RuleSet = RBLRules.getRulesForOpc(MI); + if (!RuleSet) { + reportGISelFailure(MF, TPC, MORE, "amdgpu-regbanklegalize", + "No AMDGPU RegBankLegalize rules defined for opcode", + MI); + return false; + } + + const RegBankLLTMapping *Mapping = RuleSet->findMappingForMI(MI, MRI, MUI); + if (!Mapping) { + reportGISelFailure(MF, TPC, MORE, "amdgpu-regbanklegalize", + "AMDGPU RegBankLegalize: none of the rules defined with " + "'Any' for MI's opcode matched MI", + MI); + return false; + } SmallSet WaterfallSgprs; unsigned OpIdx = 0; - if (Mapping.DstOpMapping.size() > 0) { + if (Mapping->DstOpMapping.size() > 0) { B.setInsertPt(*MI.getParent(), std::next(MI.getIterator())); - applyMappingDst(MI, OpIdx, Mapping.DstOpMapping); + if (!applyMappingDst(MI, OpIdx, Mapping->DstOpMapping)) + return false; } - if (Mapping.SrcOpMapping.size() > 0) { + if (Mapping->SrcOpMapping.size() > 0) { B.setInstr(MI); - applyMappingSrc(MI, OpIdx, Mapping.SrcOpMapping, WaterfallSgprs); + applyMappingSrc(MI, OpIdx, Mapping->SrcOpMapping, WaterfallSgprs); } - lower(MI, Mapping, WaterfallSgprs); + lower(MI, *Mapping, WaterfallSgprs); + return true; } bool RegBankLegalizeHelper::executeInWaterfallLoop( @@ -1055,7 +1073,7 @@ RegBankLegalizeHelper::getRegBankFromID(RegBankLLTMappingApplyID ID) { } } -void RegBankLegalizeHelper::applyMappingDst( +bool RegBankLegalizeHelper::applyMappingDst( MachineInstr &MI, unsigned &OpIdx, const SmallVectorImpl &MethodIDs) { // Defs start from operand 0 @@ -1180,13 +1198,17 @@ void RegBankLegalizeHelper::applyMappingDst( break; } case InvalidMapping: { - LLVM_DEBUG(dbgs() << "Instruction with Invalid mapping: "; MI.dump();); - llvm_unreachable("missing fast rule for MI"); + reportGISelFailure( + MF, TPC, MORE, "amdgpu-regbanklegalize", + "AMDGPU RegBankLegalize: missing fast rule ('Div' or 'Uni') for", MI); + return false; } default: llvm_unreachable("ID not supported"); } } + + return true; } void RegBankLegalizeHelper::applyMappingSrc( @@ -1348,7 +1370,7 @@ void RegBankLegalizeHelper::applyMappingSrc( } } -void RegBankLegalizeHelper::applyMappingPHI(MachineInstr &MI) { +bool RegBankLegalizeHelper::applyMappingPHI(MachineInstr &MI) { Register Dst = MI.getOperand(0).getReg(); LLT Ty = MRI.getType(Dst); @@ -1371,16 +1393,17 @@ void RegBankLegalizeHelper::applyMappingPHI(MachineInstr &MI) { MI.getOperand(i).setReg(NewUse.getReg(0)); } - return; + return true; } - // ALL divergent i1 phis should be already lowered and inst-selected into PHI - // with sgpr reg class and S1 LLT. + // ALL divergent i1 phis should have been lowered and inst-selected into PHI + // with sgpr reg class and S1 LLT in AMDGPUGlobalISelDivergenceLowering pass. // Note: this includes divergent phis that don't require lowering. if (Ty == LLT::scalar(1) && MUI.isDivergent(Dst)) { - LLVM_DEBUG(dbgs() << "Divergent S1 G_PHI: "; MI.dump();); - llvm_unreachable("Make sure to run AMDGPUGlobalISelDivergenceLowering " - "before RegBankLegalize to lower lane mask(vcc) phis"); + reportGISelFailure(MF, TPC, MORE, "amdgpu-regbanklegalize", + "AMDGPU RegBankLegalize: Can't lower divergent S1 G_PHI", + MI); + return false; } // We accept all types that can fit in some register class. @@ -1388,11 +1411,13 @@ void RegBankLegalizeHelper::applyMappingPHI(MachineInstr &MI) { // Divergent G_PHIs have vgpr dst but inputs can be sgpr or vgpr. if (Ty == LLT::scalar(32) || Ty == LLT::pointer(1, 64) || Ty == LLT::pointer(4, 64)) { - return; + return true; } - LLVM_DEBUG(dbgs() << "G_PHI not handled: "; MI.dump();); - llvm_unreachable("type not supported"); + reportGISelFailure(MF, TPC, MORE, "amdgpu-regbanklegalize", + "AMDGPU RegBankLegalize: type not supported for G_PHI", + MI); + return false; } [[maybe_unused]] static bool verifyRegBankOnOperands(MachineInstr &MI, diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.h b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.h index 4f1c3c02fa5d6..c9d0bbc1e7742 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.h +++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeHelper.h @@ -12,7 +12,9 @@ #include "AMDGPURegBankLegalizeRules.h" #include "llvm/ADT/SmallSet.h" #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h" +#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetPassConfig.h" namespace llvm { @@ -27,11 +29,14 @@ namespace AMDGPU { // to replace instruction. In other case InstApplyMethod will create new // instruction(s). class RegBankLegalizeHelper { + MachineFunction &MF; const GCNSubtarget &ST; MachineIRBuilder &B; MachineRegisterInfo &MRI; const MachineUniformityInfo &MUI; const RegisterBankInfo &RBI; + const TargetPassConfig &TPC; + MachineOptimizationRemarkEmitter MORE; const RegBankLegalizeRules &RBLRules; const bool IsWave32; const RegisterBank *SgprRB; @@ -79,12 +84,13 @@ class RegBankLegalizeHelper { public: RegBankLegalizeHelper(MachineIRBuilder &B, const MachineUniformityInfo &MUI, const RegisterBankInfo &RBI, + const TargetPassConfig &TPC, const RegBankLegalizeRules &RBLRules); - void findRuleAndApplyMapping(MachineInstr &MI); + bool findRuleAndApplyMapping(MachineInstr &MI); // Manual apply helpers. - void applyMappingPHI(MachineInstr &MI); + bool applyMappingPHI(MachineInstr &MI); void applyMappingTrivial(MachineInstr &MI); private: @@ -97,7 +103,7 @@ class RegBankLegalizeHelper { const RegisterBank *getRegBankFromID(RegBankLLTMappingApplyID ID); - void + bool applyMappingDst(MachineInstr &MI, unsigned &OpIdx, const SmallVectorImpl &MethodIDs); diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp index 6ec51e1be8aca..d07e356100508 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.cpp @@ -243,7 +243,7 @@ UniformityLLTOpPredicateID LLTToBId(LLT Ty) { return _; } -const RegBankLLTMapping & +const RegBankLLTMapping * SetOfRulesForOpcode::findMappingForMI(const MachineInstr &MI, const MachineRegisterInfo &MRI, const MachineUniformityInfo &MUI) const { @@ -260,17 +260,16 @@ SetOfRulesForOpcode::findMappingForMI(const MachineInstr &MI, Slot = getFastPredicateSlot(LLTToId(MRI.getType(Reg))); if (Slot != -1) - return MUI.isUniform(Reg) ? Uni[Slot] : Div[Slot]; + return MUI.isUniform(Reg) ? &Uni[Slot] : &Div[Slot]; } // Slow search for more complex rules. for (const RegBankLegalizeRule &Rule : Rules) { if (Rule.Predicate.match(MI, MUI, MRI)) - return Rule.OperandMapping; + return &Rule.OperandMapping; } - LLVM_DEBUG(dbgs() << "MI: "; MI.dump();); - llvm_unreachable("None of the rules defined for MI's opcode matched MI"); + return nullptr; } void SetOfRulesForOpcode::addRule(RegBankLegalizeRule Rule) { @@ -353,7 +352,7 @@ RegBankLegalizeRules::addRulesForIOpcs(std::initializer_list OpcList, return RuleSetInitializer(OpcList, IRulesAlias, IRules, FastTypes); } -const SetOfRulesForOpcode & +const SetOfRulesForOpcode * RegBankLegalizeRules::getRulesForOpc(MachineInstr &MI) const { unsigned Opc = MI.getOpcode(); if (Opc == AMDGPU::G_INTRINSIC || Opc == AMDGPU::G_INTRINSIC_CONVERGENT || @@ -361,19 +360,15 @@ RegBankLegalizeRules::getRulesForOpc(MachineInstr &MI) const { Opc == AMDGPU::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS) { unsigned IntrID = cast(MI).getIntrinsicID(); auto IRAIt = IRulesAlias.find(IntrID); - if (IRAIt == IRulesAlias.end()) { - LLVM_DEBUG(dbgs() << "MI: "; MI.dump();); - llvm_unreachable("No rules defined for intrinsic opcode"); - } - return IRules.at(IRAIt->second); + if (IRAIt == IRulesAlias.end()) + return nullptr; + return &IRules.at(IRAIt->second); } auto GRAIt = GRulesAlias.find(Opc); - if (GRAIt == GRulesAlias.end()) { - LLVM_DEBUG(dbgs() << "MI: "; MI.dump();); - llvm_unreachable("No rules defined for generic opcode"); - } - return GRules.at(GRAIt->second); + if (GRAIt == GRulesAlias.end()) + return nullptr; + return &GRules.at(GRAIt->second); } // Syntactic sugar wrapper for predicate lambda that enables '&&', '||' and '!'. diff --git a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h index 7e4ce7b43dc3b..1ac117304b76f 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h +++ b/llvm/lib/Target/AMDGPU/AMDGPURegBankLegalizeRules.h @@ -287,7 +287,7 @@ class SetOfRulesForOpcode { SetOfRulesForOpcode(); SetOfRulesForOpcode(FastRulesTypes FastTypes); - const RegBankLLTMapping & + const RegBankLLTMapping * findMappingForMI(const MachineInstr &MI, const MachineRegisterInfo &MRI, const MachineUniformityInfo &MUI) const; @@ -385,7 +385,7 @@ class RegBankLegalizeRules { MRI = &_MRI; }; - const SetOfRulesForOpcode &getRulesForOpc(MachineInstr &MI) const; + const SetOfRulesForOpcode *getRulesForOpc(MachineInstr &MI) const; }; } // end namespace AMDGPU