Index: llvm/include/llvm/CodeGen/GlobalISel/Utils.h =================================================================== --- llvm/include/llvm/CodeGen/GlobalISel/Utils.h +++ llvm/include/llvm/CodeGen/GlobalISel/Utils.h @@ -184,5 +184,17 @@ unsigned inferAlignmentFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO); +/// Return the least common multiple type of \p Ty0 and \p Ty1, by changing +/// the number of vector elements or scalar bitwidth. The intent is a +/// G_MERGE_VALUES can be constructed from \p Ty0 elements, and unmerged into +/// \p Ty1. +LLT getLCMType(LLT Ty0, LLT Ty1); + +/// Return a type that is greatest common divisor of \p OrigTy and \p +/// TargetTy. This will either change the number of vector elements, or +/// bitwidth of scalars. The intent is the result type can be used as the +/// result of a G_UNMERGE_VALUES from \p OrigTy. +LLT getGCDType(LLT OrigTy, LLT TargetTy); + } // End namespace llvm. #endif Index: llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -63,58 +63,6 @@ return std::make_pair(NumParts, NumLeftover); } -static LLT getGCDType(LLT OrigTy, LLT TargetTy) { - if (OrigTy.isVector() && TargetTy.isVector()) { - assert(OrigTy.getElementType() == TargetTy.getElementType()); - int GCD = greatestCommonDivisor(OrigTy.getNumElements(), - TargetTy.getNumElements()); - return LLT::scalarOrVector(GCD, OrigTy.getElementType()); - } - - if (OrigTy.isVector() && !TargetTy.isVector()) { - assert(OrigTy.getElementType() == TargetTy); - return TargetTy; - } - - assert(!OrigTy.isVector() && !TargetTy.isVector() && - "GCD type of vector and scalar not implemented"); - - int GCD = greatestCommonDivisor(OrigTy.getSizeInBits(), - TargetTy.getSizeInBits()); - return LLT::scalar(GCD); -} - -static LLT getLCMType(LLT Ty0, LLT Ty1) { - if (!Ty0.isVector() && !Ty1.isVector()) { - unsigned Mul = Ty0.getSizeInBits() * Ty1.getSizeInBits(); - int GCDSize = greatestCommonDivisor(Ty0.getSizeInBits(), - Ty1.getSizeInBits()); - return LLT::scalar(Mul / GCDSize); - } - - if (Ty0.isVector() && !Ty1.isVector()) { - assert(Ty0.getElementType() == Ty1 && "not yet handled"); - return Ty0; - } - - if (Ty1.isVector() && !Ty0.isVector()) { - assert(Ty1.getElementType() == Ty0 && "not yet handled"); - return Ty1; - } - - if (Ty0.isVector() && Ty1.isVector()) { - assert(Ty0.getElementType() == Ty1.getElementType() && "not yet handled"); - - int GCDElts = greatestCommonDivisor(Ty0.getNumElements(), - Ty1.getNumElements()); - - int Mul = Ty0.getNumElements() * Ty1.getNumElements(); - return LLT::vector(Mul / GCDElts, Ty0.getElementType()); - } - - llvm_unreachable("not yet handled"); -} - static Type *getFloatTypeForLLT(LLVMContext &Ctx, LLT Ty) { if (!Ty.isScalar()) Index: llvm/lib/CodeGen/GlobalISel/Utils.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -488,3 +488,55 @@ void llvm::getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU) { AU.addPreserved(); } + +LLT llvm::getLCMType(LLT Ty0, LLT Ty1) { + if (!Ty0.isVector() && !Ty1.isVector()) { + unsigned Mul = Ty0.getSizeInBits() * Ty1.getSizeInBits(); + int GCDSize = greatestCommonDivisor(Ty0.getSizeInBits(), + Ty1.getSizeInBits()); + return LLT::scalar(Mul / GCDSize); + } + + if (Ty0.isVector() && !Ty1.isVector()) { + assert(Ty0.getElementType() == Ty1 && "not yet handled"); + return Ty0; + } + + if (Ty1.isVector() && !Ty0.isVector()) { + assert(Ty1.getElementType() == Ty0 && "not yet handled"); + return Ty1; + } + + if (Ty0.isVector() && Ty1.isVector()) { + assert(Ty0.getElementType() == Ty1.getElementType() && "not yet handled"); + + int GCDElts = greatestCommonDivisor(Ty0.getNumElements(), + Ty1.getNumElements()); + + int Mul = Ty0.getNumElements() * Ty1.getNumElements(); + return LLT::vector(Mul / GCDElts, Ty0.getElementType()); + } + + llvm_unreachable("not yet handled"); +} + +LLT llvm::getGCDType(LLT OrigTy, LLT TargetTy) { + if (OrigTy.isVector() && TargetTy.isVector()) { + assert(OrigTy.getElementType() == TargetTy.getElementType()); + int GCD = greatestCommonDivisor(OrigTy.getNumElements(), + TargetTy.getNumElements()); + return LLT::scalarOrVector(GCD, OrigTy.getElementType()); + } + + if (OrigTy.isVector() && !TargetTy.isVector()) { + assert(OrigTy.getElementType() == TargetTy); + return TargetTy; + } + + assert(!OrigTy.isVector() && !TargetTy.isVector() && + "GCD type of vector and scalar not implemented"); + + int GCD = greatestCommonDivisor(OrigTy.getSizeInBits(), + TargetTy.getSizeInBits()); + return LLT::scalar(GCD); +}