From ca37830df005a8f2f71d9c7e5b54ba994502c7cc Mon Sep 17 00:00:00 2001 From: Aditya Nandakumar Date: Wed, 25 Oct 2017 18:49:18 +0000 Subject: [PATCH] Make the combiner check if shifts are legal before creating them Summary: Make sure shifts are legal/specified by the legalizerinfo before creating it Reviewers: qcolombet, dsanders, rovka, t.p.northover Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39264 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316602 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../CodeGen/GlobalISel/LegalizerCombiner.h | 28 +++++++++++++++---- .../llvm/CodeGen/GlobalISel/LegalizerHelper.h | 3 ++ lib/CodeGen/GlobalISel/Legalizer.cpp | 5 ++-- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/include/llvm/CodeGen/GlobalISel/LegalizerCombiner.h b/include/llvm/CodeGen/GlobalISel/LegalizerCombiner.h index 1d501416b18..c22b31302e5 100644 --- a/include/llvm/CodeGen/GlobalISel/LegalizerCombiner.h +++ b/include/llvm/CodeGen/GlobalISel/LegalizerCombiner.h @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/GlobalISel/Legalizer.h" +#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h" #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" #include "llvm/CodeGen/GlobalISel/Utils.h" #include "llvm/CodeGen/MachineRegisterInfo.h" @@ -24,10 +25,12 @@ namespace llvm { class LegalizerCombiner { MachineIRBuilder &Builder; MachineRegisterInfo &MRI; + const LegalizerInfo &LI; public: - LegalizerCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI) - : Builder(B), MRI(MRI) {} + LegalizerCombiner(MachineIRBuilder &B, MachineRegisterInfo &MRI, + const LegalizerInfo &LI) + : Builder(B), MRI(MRI), LI(LI) {} bool tryCombineAnyExt(MachineInstr &MI, SmallVectorImpl &DeadInsts) { @@ -54,12 +57,15 @@ public: return false; MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(1).getReg()); if (DefMI->getOpcode() == TargetOpcode::G_TRUNC) { + unsigned DstReg = MI.getOperand(0).getReg(); + LLT DstTy = MRI.getType(DstReg); + if (isInstUnsupported(TargetOpcode::G_AND, DstTy) || + isInstUnsupported(TargetOpcode::G_CONSTANT, DstTy)) + return false; DEBUG(dbgs() << ".. Combine MI: " << MI;); Builder.setInstr(MI); - unsigned DstReg = MI.getOperand(0).getReg(); unsigned ZExtSrc = MI.getOperand(1).getReg(); LLT ZExtSrcTy = MRI.getType(ZExtSrc); - LLT DstTy = MRI.getType(DstReg); APInt Mask = APInt::getAllOnesValue(ZExtSrcTy.getSizeInBits()); auto MaskCstMIB = Builder.buildConstant(DstTy, Mask.getZExtValue()); unsigned TruncSrc = DefMI->getOperand(1).getReg(); @@ -79,10 +85,13 @@ public: return false; MachineInstr *DefMI = MRI.getVRegDef(MI.getOperand(1).getReg()); if (DefMI->getOpcode() == TargetOpcode::G_TRUNC) { - DEBUG(dbgs() << ".. Combine MI: " << MI;); - Builder.setInstr(MI); unsigned DstReg = MI.getOperand(0).getReg(); LLT DstTy = MRI.getType(DstReg); + if (isInstUnsupported(TargetOpcode::G_SHL, DstTy) || + isInstUnsupported(TargetOpcode::G_ASHR, DstTy)) + return false; + DEBUG(dbgs() << ".. Combine MI: " << MI;); + Builder.setInstr(MI); unsigned SExtSrc = MI.getOperand(1).getReg(); LLT SExtSrcTy = MRI.getType(SExtSrc); unsigned SizeDiff = DstTy.getSizeInBits() - SExtSrcTy.getSizeInBits(); @@ -202,6 +211,13 @@ private: if (MRI.hasOneUse(DefMI.getOperand(0).getReg())) DeadInsts.push_back(&DefMI); } + /// Checks if the target legalizer info has specified anything about the + /// instruction, or if unsupported. + bool isInstUnsupported(unsigned Opcode, const LLT &DstTy) const { + auto Action = LI.getAction({Opcode, 0, DstTy}); + return Action.first == LegalizerInfo::LegalizeAction::Unsupported || + Action.first == LegalizerInfo::LegalizeAction::NotFound; + } }; } // namespace llvm diff --git a/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h index 1fd45b52e3a..8bd8a9dcd0e 100644 --- a/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h +++ b/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h @@ -89,6 +89,9 @@ public: /// functions MachineIRBuilder MIRBuilder; + /// Expose LegalizerInfo so the clients can re-use. + const LegalizerInfo &getLegalizerInfo() const { return LI; } + private: /// Helper function to split a wide generic register into bitwise blocks with diff --git a/lib/CodeGen/GlobalISel/Legalizer.cpp b/lib/CodeGen/GlobalISel/Legalizer.cpp index 83e5dc4025d..fb954f3c3f1 100644 --- a/lib/CodeGen/GlobalISel/Legalizer.cpp +++ b/lib/CodeGen/GlobalISel/Legalizer.cpp @@ -97,7 +97,8 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) { } }); WorkList.insert(&*MI); - LegalizerCombiner C(Helper.MIRBuilder, MF.getRegInfo()); + LegalizerCombiner C(Helper.MIRBuilder, MF.getRegInfo(), + Helper.getLegalizerInfo()); bool Changed = false; LegalizerHelper::LegalizeResult Res; do { @@ -158,7 +159,7 @@ bool Legalizer::runOnMachineFunction(MachineFunction &MF) { MachineRegisterInfo &MRI = MF.getRegInfo(); MachineIRBuilder MIRBuilder(MF); - LegalizerCombiner C(MIRBuilder, MRI); + LegalizerCombiner C(MIRBuilder, MRI, Helper.getLegalizerInfo()); for (auto &MBB : MF) { for (auto MI = MBB.begin(); MI != MBB.end(); MI = NextMI) { // Get the next Instruction before we try to legalize, because there's a -- 2.40.0