diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h --- a/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -687,9 +687,6 @@ /// would typically be allowed using throughput or size cost models. bool hasDivRemOp(Type *DataType, bool IsSigned) const; - /// Returns the maximum bitwidth of legal div and rem instructions. - unsigned maxLegalDivRemBitWidth() const; - /// Return true if the given instruction (assumed to be a memory access /// instruction) has a volatile variant. If that's the case then we can avoid /// addrspacecast to generic AS for volatile loads/stores. Default @@ -1644,7 +1641,6 @@ const SmallBitVector &OpcodeMask) const = 0; virtual bool enableOrderedReductions() = 0; virtual bool hasDivRemOp(Type *DataType, bool IsSigned) = 0; - virtual unsigned maxLegalDivRemBitWidth() = 0; virtual bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) = 0; virtual bool prefersVectorizedAddressing() = 0; virtual InstructionCost getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, @@ -2092,9 +2088,6 @@ bool hasDivRemOp(Type *DataType, bool IsSigned) override { return Impl.hasDivRemOp(DataType, IsSigned); } - unsigned maxLegalDivRemBitWidth() override { - return Impl.maxLegalDivRemBitWidth(); - } bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) override { return Impl.hasVolatileVariant(I, AddrSpace); } diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -291,10 +291,6 @@ bool hasDivRemOp(Type *DataType, bool IsSigned) const { return false; } - unsigned maxLegalDivRemBitWidth() const { - return llvm::IntegerType::MAX_INT_BITS; - } - bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) const { return false; } diff --git a/llvm/include/llvm/CodeGen/ExpandLargeDivRem.h b/llvm/include/llvm/CodeGen/ExpandLargeDivRem.h deleted file mode 100644 --- a/llvm/include/llvm/CodeGen/ExpandLargeDivRem.h +++ /dev/null @@ -1,29 +0,0 @@ -//===----- ExpandLargeDivRem.h - Expand large div/rem ---------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CODEGEN_EXPANDLARGEDIVREM_H -#define LLVM_CODEGEN_EXPANDLARGEDIVREM_H - -#include "llvm/IR/PassManager.h" - -namespace llvm { - -/// Expands div/rem instructions with a bitwidth above a threshold -/// into a loop. -/// This is useful for backends like x86 that cannot lower divisions -/// with more than 128 bits. -class ExpandLargeDivRemPass : public PassInfoMixin { -public: - PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); - - // The backend asserts when seeing large div/rem instructions. - static bool isRequired() { return true; } -}; -} // end namespace llvm - -#endif // LLVM_CODEGEN_EXPANDLARGEDIVREM_H diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -4573,6 +4573,13 @@ //===--------------------------------------------------------------------===// // Div utility functions // + + /// Returns the maximum bitwidth of div and rem instructions supported by + /// codegen. + virtual unsigned maxSupportedDivRemBitWidth() const { + return llvm::IntegerType::MAX_INT_BITS; + } + SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, SmallVectorImpl &Created) const; SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization, diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -451,10 +451,6 @@ return TTIImpl->hasDivRemOp(DataType, IsSigned); } -unsigned TargetTransformInfo::maxLegalDivRemBitWidth() const { - return TTIImpl->maxLegalDivRemBitWidth(); -} - bool TargetTransformInfo::hasVolatileVariant(Instruction *I, unsigned AddrSpace) const { return TTIImpl->hasVolatileVariant(I, AddrSpace); diff --git a/llvm/lib/CodeGen/ExpandLargeDivRem.cpp b/llvm/lib/CodeGen/ExpandLargeDivRem.cpp --- a/llvm/lib/CodeGen/ExpandLargeDivRem.cpp +++ b/llvm/lib/CodeGen/ExpandLargeDivRem.cpp @@ -14,18 +14,20 @@ // //===----------------------------------------------------------------------===// -#include "llvm/CodeGen/ExpandLargeDivRem.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/GlobalsModRef.h" -#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InstIterator.h" #include "llvm/IR/PassManager.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/Utils/IntegerDivision.h" using namespace llvm; @@ -51,11 +53,11 @@ return Opcode == Instruction::SDiv || Opcode == Instruction::SRem; } -static bool runImpl(Function &F, const TargetTransformInfo &TTI) { +static bool runImpl(Function &F, const TargetLowering &TLI) { SmallVector Replace; bool Modified = false; - unsigned MaxLegalDivRemBitWidth = TTI.maxLegalDivRemBitWidth(); + unsigned MaxLegalDivRemBitWidth = TLI.maxSupportedDivRemBitWidth(); if (ExpandDivRemBits != llvm::IntegerType::MAX_INT_BITS) MaxLegalDivRemBitWidth = ExpandDivRemBits; @@ -103,17 +105,6 @@ return Modified; } -PreservedAnalyses ExpandLargeDivRemPass::run(Function &F, - FunctionAnalysisManager &AM) { - TargetTransformInfo &TTI = AM.getResult(F); - bool Changed = runImpl(F, TTI); - - if (Changed) - return PreservedAnalyses::none(); - - return PreservedAnalyses::all(); -} - class ExpandLargeDivRemLegacyPass : public FunctionPass { public: static char ID; @@ -123,12 +114,13 @@ } bool runOnFunction(Function &F) override { - auto &TTI = getAnalysis().getTTI(F); - return runImpl(F, TTI); + auto *TM = &getAnalysis().getTM(); + auto *TLI = TM->getSubtargetImpl(F)->getTargetLowering(); + return runImpl(F, *TLI); } void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); + AU.addRequired(); AU.addPreserved(); AU.addPreserved(); } diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.h b/llvm/lib/Target/AArch64/AArch64ISelLowering.h --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.h +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.h @@ -1093,6 +1093,10 @@ std::vector &Ops, SelectionDAG &DAG) const override; + /// Returns the maximum bitwidth of div and rem instructions supported by + /// codegen. + unsigned maxSupportedDivRemBitWidth() const override; + unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override { if (ConstraintCode == "Q") return InlineAsm::Constraint_Q; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -9528,6 +9528,12 @@ return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG); } +/// Returns the maximum bitwidth of div and rem instructions supported by +/// codegen. +unsigned AArch64TargetLowering::maxSupportedDivRemBitWidth() const { + return 128; +} + //===----------------------------------------------------------------------===// // AArch64 Advanced SIMD Support //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h @@ -319,8 +319,6 @@ bool enableOrderedReductions() const { return true; } - unsigned maxLegalDivRemBitWidth() const { return 128; } - InstructionCost getInterleavedMemoryOpCost( unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef Indices, Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind, diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -534,6 +534,10 @@ std::vector &Ops, SelectionDAG &DAG) const override; + /// Returns the maximum bitwidth of div and rem instructions supported by + /// codegen. + unsigned maxSupportedDivRemBitWidth() const override; + unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override { if (ConstraintCode == "Q") diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -20121,6 +20121,10 @@ return weight; } +/// Returns the maximum bitwidth of div and rem instructions supported by +/// codegen. +unsigned ARMTargetLowering::maxSupportedDivRemBitWidth() const { return 64; } + using RCPair = std::pair; RCPair ARMTargetLowering::getRegForInlineAsmConstraint( diff --git a/llvm/lib/Target/ARM/ARMTargetTransformInfo.h b/llvm/lib/Target/ARM/ARMTargetTransformInfo.h --- a/llvm/lib/Target/ARM/ARMTargetTransformInfo.h +++ b/llvm/lib/Target/ARM/ARMTargetTransformInfo.h @@ -207,8 +207,6 @@ return isLegalMaskedGather(Ty, Alignment); } - unsigned maxLegalDivRemBitWidth() const { return 64; } - InstructionCost getMemcpyCost(const Instruction *I); int getNumMemOps(const IntrinsicInst *I) const; diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -1214,6 +1214,10 @@ const AsmOperandInfo &Constraint, SelectionDAG &DAG) const override; + /// Returns the maximum bitwidth of div and rem instructions supported by + /// codegen. + unsigned maxSupportedDivRemBitWidth() const override; + /// Given a physical register constraint /// (e.g. {edx}), return the register number and the register class for the /// register. This should only be used for C_Register constraints. On diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -55924,6 +55924,12 @@ return Result; } +/// Returns the maximum bitwidth of div and rem instructions supported by +/// codegen. +unsigned X86TargetLowering::maxSupportedDivRemBitWidth() const { + return Subtarget.is64Bit() ? 128 : 64; +} + /// Lower the specified operand into the Ops vector. /// If it is invalid, don't add anything to Ops. void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op, diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.h b/llvm/lib/Target/X86/X86TargetTransformInfo.h --- a/llvm/lib/Target/X86/X86TargetTransformInfo.h +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.h @@ -255,7 +255,6 @@ const SmallBitVector &OpcodeMask) const; bool hasDivRemOp(Type *DataType, bool IsSigned); bool isExpensiveToSpeculativelyExecute(const Instruction *I); - unsigned maxLegalDivRemBitWidth() const; bool isFCmpOrdCheaperThanFCmpZero(Type *Ty); bool areInlineCompatible(const Function *Caller, const Function *Callee) const; diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp --- a/llvm/lib/Target/X86/X86TargetTransformInfo.cpp +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.cpp @@ -5751,10 +5751,6 @@ return BaseT::isExpensiveToSpeculativelyExecute(I); } -unsigned X86TTIImpl::maxLegalDivRemBitWidth() const { - return ST->is64Bit() ? 128 : 64; -} - bool X86TTIImpl::isFCmpOrdCheaperThanFCmpZero(Type *Ty) { return false; } diff --git a/llvm/test/Transforms/ExpandLargeDivRem/sdiv129.ll b/llvm/test/Transforms/ExpandLargeDivRem/sdiv129.ll --- a/llvm/test/Transforms/ExpandLargeDivRem/sdiv129.ll +++ b/llvm/test/Transforms/ExpandLargeDivRem/sdiv129.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s define void @sdiv129(i129* %ptr, i129* %out) nounwind { ; CHECK-LABEL: @sdiv129( diff --git a/llvm/test/Transforms/ExpandLargeDivRem/srem129.ll b/llvm/test/Transforms/ExpandLargeDivRem/srem129.ll --- a/llvm/test/Transforms/ExpandLargeDivRem/srem129.ll +++ b/llvm/test/Transforms/ExpandLargeDivRem/srem129.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s define void @test(i129* %ptr, i129* %out) nounwind { ; CHECK-LABEL: @test( diff --git a/llvm/test/Transforms/ExpandLargeDivRem/udiv129.ll b/llvm/test/Transforms/ExpandLargeDivRem/udiv129.ll --- a/llvm/test/Transforms/ExpandLargeDivRem/udiv129.ll +++ b/llvm/test/Transforms/ExpandLargeDivRem/udiv129.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s define void @test(i129* %ptr, i129* %out) nounwind { ; CHECK-LABEL: @test( diff --git a/llvm/test/Transforms/ExpandLargeDivRem/urem129.ll b/llvm/test/Transforms/ExpandLargeDivRem/urem129.ll --- a/llvm/test/Transforms/ExpandLargeDivRem/urem129.ll +++ b/llvm/test/Transforms/ExpandLargeDivRem/urem129.ll @@ -1,5 +1,5 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s +; RUN: opt -S -mtriple=x86_64-- -expand-large-div-rem -expand-div-rem-bits 128 < %s | FileCheck %s define void @test(i129* %ptr, i129* %out) nounwind { ; CHECK-LABEL: @test(