Index: docs/LangRef.rst =================================================================== --- docs/LangRef.rst +++ docs/LangRef.rst @@ -6602,6 +6602,8 @@ = udiv , ; yields ty:result = udiv exact , ; yields ty:result + = udiv nof , ; yields ty:result + = udiv mof , ; yields ty:result Overview: """"""""" @@ -6623,14 +6625,17 @@ Note that unsigned integer division and signed integer division are distinct operations; for signed integer division, use '``sdiv``'. -Division by zero is undefined behavior. For vectors, if any element -of the divisor is zero, the operation has undefined behavior. +See the description of the ``nof`` and ``mof`` keywords below for division by zero. If the ``exact`` keyword is present, the result value of the ``udiv`` is a :ref:`poison value ` if %op1 is not a multiple of %op2 (as such, "((a udiv exact b) mul b) == a"). +``nof`` stands for “No Overflow”. If the ``nof`` keyword is present, the result is undefined behavior for division by zero. Currently for backward compatibility if ``udiv`` come without any attribute it will be treated the same as ``nof`` attribute exist. +If the ``mof`` keyword is present, it means that the result "May Overflow" so division by zero results in poison value. +For vectors, if any element of the divisor is zero, the behavior is same as for scalar division by zero. + Example: """""""" @@ -6648,6 +6653,8 @@ = sdiv , ; yields ty:result = sdiv exact , ; yields ty:result + = sdiv nof , ; yields ty:result + = sdiv mof , ; yields ty:result Overview: """"""""" @@ -6670,14 +6677,15 @@ Note that signed integer division and unsigned integer division are distinct operations; for unsigned integer division, use '``udiv``'. -Division by zero is undefined behavior. For vectors, if any element -of the divisor is zero, the operation has undefined behavior. -Overflow also leads to undefined behavior; this is a rare case, but can -occur, for example, by doing a 32-bit division of -2147483648 by -1. +See the description of the ``nof`` and ``mof`` keywords below for division by zero and overflow. If the ``exact`` keyword is present, the result value of the ``sdiv`` is a :ref:`poison value ` if the result would be rounded. +``nof`` stands for “No Overflow”. If the ``nof`` keyword is present, the result is undefined behavior if overflow occurs. This may be result of division by zero or dividing the smallest representable integer of the type by -1. Currently for backward compatibility if ``sdiv`` come without any attribute it will be treated the same as ``nof`` attribute exist. +If the ``mof`` keyword is present, it means that the result "May Overflow" so the overflow cases described above result in poison value. +For vectors, if any element of the division causes overflow, the behavior is same as for scalar division with overflow. + Example: """""""" Index: include/llvm/Analysis/TargetFolder.h =================================================================== --- include/llvm/Analysis/TargetFolder.h +++ include/llvm/Analysis/TargetFolder.h @@ -67,11 +67,13 @@ Constant *CreateFMul(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFMul(LHS, RHS)); } - Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{ - return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact)); - } - Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{ - return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact)); + Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false, + bool isNoOverflow = true) const { + return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact, isNoOverflow)); + } + Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false, + bool isNoOverflow = true) const { + return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact, isNoOverflow)); } Constant *CreateFDiv(Constant *LHS, Constant *RHS) const { return Fold(ConstantExpr::getFDiv(LHS, RHS)); Index: include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- include/llvm/Analysis/TargetTransformInfo.h +++ include/llvm/Analysis/TargetTransformInfo.h @@ -487,6 +487,11 @@ bool isLegalMaskedScatter(Type *DataType) const; bool isLegalMaskedGather(Type *DataType) const; + /// \brief Return true if the target support div that may overflow + /// divide by zero without causing a side effect + bool isLegalMayOverflowUDiv(Type *DataType) const; + bool isLegalMayOverflowSDiv(Type *DataType) const; + /// Return true if the target has a unified operation to calculate division /// and remainder. If so, the additional implicit multiplication and /// subtraction required to calculate a remainder from division are free. This @@ -988,6 +993,8 @@ virtual bool isLegalMaskedLoad(Type *DataType) = 0; virtual bool isLegalMaskedScatter(Type *DataType) = 0; virtual bool isLegalMaskedGather(Type *DataType) = 0; + virtual bool isLegalMayOverflowUDiv(Type *DataType) = 0; + virtual bool isLegalMayOverflowSDiv(Type *DataType) = 0; virtual bool hasDivRemOp(Type *DataType, bool IsSigned) = 0; virtual bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) = 0; virtual bool prefersVectorizedAddressing() = 0; @@ -1218,6 +1225,12 @@ bool isLegalMaskedGather(Type *DataType) override { return Impl.isLegalMaskedGather(DataType); } + bool isLegalMayOverflowUDiv(Type *DataType) override { + return Impl.isLegalMayOverflowUDiv(DataType); + } + bool isLegalMayOverflowSDiv(Type *DataType) override { + return Impl.isLegalMayOverflowSDiv(DataType); + } bool hasDivRemOp(Type *DataType, bool IsSigned) override { return Impl.hasDivRemOp(DataType, IsSigned); } Index: include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- include/llvm/Analysis/TargetTransformInfoImpl.h +++ include/llvm/Analysis/TargetTransformInfoImpl.h @@ -256,6 +256,10 @@ bool isLegalMaskedGather(Type *DataType) { return false; } + bool isLegalMayOverflowUDiv(Type *DataType) { return false; } + + bool isLegalMayOverflowSDiv(Type *DataType) { return false; } + bool hasDivRemOp(Type *DataType, bool IsSigned) { return false; } bool hasVolatileVariant(Instruction *I, unsigned AddrSpace) { return false; } Index: include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- include/llvm/Bitcode/LLVMBitCodes.h +++ include/llvm/Bitcode/LLVMBitCodes.h @@ -406,6 +406,10 @@ /// PossiblyExactOperator's SubclassOptionalData contents. enum PossiblyExactOperatorOptionalFlags { PEO_EXACT = 0 }; +/// PossiblyOverflowOperatorOptionalFlags - Flags for serializing +/// PossiblyOverflowOperator's SubclassOptionalData contents +enum PossiblyOverflowOperatorOptionalFlags { POO_MAY_OVERFLOW = 1 }; + /// Encoded AtomicOrdering values. enum AtomicOrderingCodes { ORDERING_NOTATOMIC = 0, Index: include/llvm/CodeGen/Passes.h =================================================================== --- include/llvm/CodeGen/Passes.h +++ include/llvm/CodeGen/Passes.h @@ -69,6 +69,10 @@ /// and scatter intrinsics with scalar code when target doesn't support them. FunctionPass *createScalarizeMaskedMemIntrinPass(); + /// createScalarizeMayOverflowDivPass - Replace may overflow divisions + /// with a guarded scalar sequence when target doesn't support them + FunctionPass *createScalarizeMayOverflowDivPass(); + /// AtomicExpandID -- Lowers atomic operations in terms of either cmpxchg /// load-linked/store-conditional loops. extern char &AtomicExpandID; Index: include/llvm/IR/ConstantFolder.h =================================================================== --- include/llvm/IR/ConstantFolder.h +++ include/llvm/IR/ConstantFolder.h @@ -60,14 +60,14 @@ return ConstantExpr::getFMul(LHS, RHS); } - Constant *CreateUDiv(Constant *LHS, Constant *RHS, - bool isExact = false) const { - return ConstantExpr::getUDiv(LHS, RHS, isExact); + Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false, + bool isNoOverflow = true) const { + return ConstantExpr::getUDiv(LHS, RHS, isExact, isNoOverflow); } - Constant *CreateSDiv(Constant *LHS, Constant *RHS, - bool isExact = false) const { - return ConstantExpr::getSDiv(LHS, RHS, isExact); + Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false, + bool isNoOverflow = true) const { + return ConstantExpr::getSDiv(LHS, RHS, isExact, isNoOverflow); } Constant *CreateFDiv(Constant *LHS, Constant *RHS) const { Index: include/llvm/IR/Constants.h =================================================================== --- include/llvm/IR/Constants.h +++ include/llvm/IR/Constants.h @@ -911,8 +911,10 @@ static Constant *getMul(Constant *C1, Constant *C2, bool HasNUW = false, bool HasNSW = false); static Constant *getFMul(Constant *C1, Constant *C2); - static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false); - static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false); + static Constant *getUDiv(Constant *C1, Constant *C2, bool isExact = false, + bool isNoOverflow = true); + static Constant *getSDiv(Constant *C1, Constant *C2, bool isExact = false, + bool isNoOverflow = true); static Constant *getFDiv(Constant *C1, Constant *C2); static Constant *getURem(Constant *C1, Constant *C2); static Constant *getSRem(Constant *C1, Constant *C2); Index: include/llvm/IR/IRBuilder.h =================================================================== --- include/llvm/IR/IRBuilder.h +++ include/llvm/IR/IRBuilder.h @@ -917,6 +917,16 @@ return BO; } + BinaryOperator *CreateInsertExactNofDivOp(BinaryOperator::BinaryOps Opc, + Value *LHS, Value *RHS, + const Twine &Name, + bool isExact, bool isNof) { + BinaryOperator *BO = Insert(BinaryOperator::Create(Opc, LHS, RHS), Name); + if (isExact) BO->setIsExact(isExact); + if (isNof) BO->setIsNoOverflow(isNof); + return BO; + } + Instruction *AddFPMathAttributes(Instruction *I, MDNode *FPMathTag, FastMathFlags FMF) const { @@ -996,29 +1006,43 @@ FPMathTag, FMF), Name); } Value *CreateUDiv(Value *LHS, Value *RHS, const Twine &Name = "", - bool isExact = false) { + bool isExact = false, bool isNoOverflow = true) { + if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateUDiv(LC, RC, isExact), Name); - if (!isExact) - return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name); - return Insert(BinaryOperator::CreateExactUDiv(LHS, RHS), Name); + return Insert(Folder.CreateUDiv(LC, RC, isExact, isNoOverflow), Name); + return CreateInsertExactNofDivOp(Instruction::UDiv, LHS, RHS, Name, + isExact, isNoOverflow); } Value *CreateExactUDiv(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateUDiv(LHS, RHS, Name, true); } + Value *CreateMayOverflowUDiv(Value *LHS, Value *RHS, const Twine &Name = "") { + return CreateUDiv(LHS, RHS, Name, false, false); + } + Value *CreateExactMayOverflowUDiv(Value *LHS, Value *RHS, + const Twine &Name = "") { + return CreateUDiv(LHS, RHS, Name, true, false); + } Value *CreateSDiv(Value *LHS, Value *RHS, const Twine &Name = "", - bool isExact = false) { + bool isExact = false, bool isNoOverflow = true) { + if (Constant *LC = dyn_cast(LHS)) if (Constant *RC = dyn_cast(RHS)) - return Insert(Folder.CreateSDiv(LC, RC, isExact), Name); - if (!isExact) - return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name); - return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name); + return Insert(Folder.CreateSDiv(LC, RC, isExact, isNoOverflow), Name); + return CreateInsertExactNofDivOp(Instruction::SDiv, LHS, RHS, Name, + isExact, isNoOverflow); } Value *CreateExactSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { return CreateSDiv(LHS, RHS, Name, true); } + Value *CreateMayOverflowSDiv(Value *LHS, Value *RHS, const Twine &Name = "") { + return CreateSDiv(LHS, RHS, Name, false, false); + } + Value *CreateExactMayOverflowSDiv(Value *LHS, Value *RHS, + const Twine &Name = "") { + return CreateSDiv(LHS, RHS, Name, true, false); + } Value *CreateFDiv(Value *LHS, Value *RHS, const Twine &Name = "", MDNode *FPMathTag = nullptr) { if (Constant *LC = dyn_cast(LHS)) Index: include/llvm/IR/InstrTypes.h =================================================================== --- include/llvm/IR/InstrTypes.h +++ include/llvm/IR/InstrTypes.h @@ -447,6 +447,48 @@ BO->setIsExact(true); return BO; } + static BinaryOperator *CreateNoOverflow(BinaryOps Opc, Value *V1, Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = Create(Opc, V1, V2, Name); + BO->setIsNoOverflow(true); + return BO; + } + static BinaryOperator *CreateNoOverflow(BinaryOps Opc, Value *V1, Value *V2, + const Twine &Name, BasicBlock *BB) { + BinaryOperator *BO = Create(Opc, V1, V2, Name, BB); + BO->setIsNoOverflow(true); + return BO; + } + static BinaryOperator *CreateNoOverflow(BinaryOps Opc, Value *V1, Value *V2, + const Twine &Name, Instruction *I) { + BinaryOperator *BO = Create(Opc, V1, V2, Name, I); + BO->setIsNoOverflow(true); + return BO; + } + static BinaryOperator *CreateExactNoOverflow(BinaryOps Opc, Value *V1, + Value *V2, + const Twine &Name = "") { + BinaryOperator *BO = Create(Opc, V1, V2, Name); + BO->setIsExact(true); + BO->setIsNoOverflow(true); + return BO; + } + static BinaryOperator *CreateExactNoOverflow(BinaryOps Opc, Value *V1, + Value *V2, const Twine &Name, + BasicBlock *BB) { + BinaryOperator *BO = Create(Opc, V1, V2, Name, BB); + BO->setIsExact(true); + BO->setIsNoOverflow(true); + return BO; + } + static BinaryOperator *CreateExactNoOverflow(BinaryOps Opc, Value *V1, + Value *V2, const Twine &Name, + Instruction *I) { + BinaryOperator *BO = Create(Opc, V1, V2, Name, I); + BO->setIsExact(true); + BO->setIsNoOverflow(true); + return BO; + } #define DEFINE_HELPERS(OPC, NUWNSWEXACT) \ static BinaryOperator *Create##NUWNSWEXACT##OPC(Value *V1, Value *V2, \ @@ -476,6 +518,12 @@ DEFINE_HELPERS(AShr, Exact) // CreateExactAShr DEFINE_HELPERS(LShr, Exact) // CreateExactLShr + DEFINE_HELPERS(SDiv, NoOverflow) // CreateNoOverflowSDiv + DEFINE_HELPERS(UDiv, NoOverflow) // CreateNoOverflowUDiv + + DEFINE_HELPERS(SDiv, ExactNoOverflow) // CreateExactNoOverflowSDiv + DEFINE_HELPERS(UDiv, ExactNoOverflow) // CreateExactNoOverflowUDiv + #undef DEFINE_HELPERS /// Helper functions to construct and inspect unary operations (NEG and NOT) Index: include/llvm/IR/Instruction.h =================================================================== --- include/llvm/IR/Instruction.h +++ include/llvm/IR/Instruction.h @@ -296,6 +296,11 @@ /// which supports this flag. See LangRef.html for the meaning of this flag. void setIsExact(bool b = true); + /// Set or clear the divide-by-zero\overflow flag on this instruction, which + /// must be an operator which supports this flag. See LangRef.html for the + /// meaning of this flag. + void setIsNoOverflow(bool b = true); + /// Determine whether the no unsigned wrap flag is set. bool hasNoUnsignedWrap() const; @@ -309,6 +314,9 @@ /// Determine whether the exact flag is set. bool isExact() const; + /// Determine whether the no-overflow flag is set. + bool isNoOverflow() const; + /// Set or clear all fast-math-flags on this instruction, which must be an /// operator which supports this flag. See LangRef.html for the meaning of /// this flag. Index: include/llvm/IR/NoFolder.h =================================================================== --- include/llvm/IR/NoFolder.h +++ include/llvm/IR/NoFolder.h @@ -99,28 +99,52 @@ return BinaryOperator::CreateFMul(LHS, RHS); } - Instruction *CreateUDiv(Constant *LHS, Constant *RHS, - bool isExact = false) const { - if (!isExact) + Instruction *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false, + bool isNoOverflow = true) const { + if (!isExact && !isNoOverflow) return BinaryOperator::CreateUDiv(LHS, RHS); - return BinaryOperator::CreateExactUDiv(LHS, RHS); + if (!isExact) + return BinaryOperator::CreateNoOverflowUDiv(LHS, RHS); + if (!isNoOverflow) + return BinaryOperator::CreateExactUDiv(LHS, RHS); + return BinaryOperator::CreateExactNoOverflowUDiv(LHS, RHS); + } + + Instruction *CreateNoOverflowUDiv(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNoOverflowUDiv(LHS, RHS); } Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateExactUDiv(LHS, RHS); } - Instruction *CreateSDiv(Constant *LHS, Constant *RHS, - bool isExact = false) const { - if (!isExact) + Instruction *CreateExactNoOverflowUDiv(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateExactNoOverflowUDiv(LHS, RHS); + } + + Instruction *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false, + bool isNoOverflow = true) const { + if (!isExact && !isNoOverflow) return BinaryOperator::CreateSDiv(LHS, RHS); - return BinaryOperator::CreateExactSDiv(LHS, RHS); + if (!isExact) + return BinaryOperator::CreateNoOverflowSDiv(LHS, RHS); + if (!isNoOverflow) + return BinaryOperator::CreateExactSDiv(LHS, RHS); + return BinaryOperator::CreateExactNoOverflowSDiv(LHS, RHS); + } + + Instruction *CreateNoOverflowSDiv(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateNoOverflowSDiv(LHS, RHS); } Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateExactSDiv(LHS, RHS); } + Instruction *CreateExactNoOverflowSDiv(Constant *LHS, Constant *RHS) const { + return BinaryOperator::CreateExactNoOverflowSDiv(LHS, RHS); + } + Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const { return BinaryOperator::CreateFDiv(LHS, RHS); } Index: include/llvm/IR/Operator.h =================================================================== --- include/llvm/IR/Operator.h +++ include/llvm/IR/Operator.h @@ -156,6 +156,44 @@ } }; +/// A udiv or sdiv instruction, which can be marked as "nof", +/// indicating that the operand values are safe and overflow +/// or div by zero not expected to occur +class PossiblyOverflowOperator : public PossiblyExactOperator { +public: + enum { MayOverflow = (1 << 1) }; + +private: + friend class Instruction; + friend class ConstantExpr; + + void setIsNoOverflow(bool B) { + unsigned bit = B ? 0 : MayOverflow; + SubclassOptionalData = + (SubclassOptionalData & ~MayOverflow) | bit; + } + +public: + /// Test whether this division is known to be with no-overflow or + /// div by zero or not + bool isNoOverflow() const { return !(SubclassOptionalData & MayOverflow); } + + static bool isPossiblyOverflowOpcode(unsigned OpC) { + return OpC == Instruction::SDiv || OpC == Instruction::UDiv; + } + + static bool classof(const ConstantExpr *CE) { + return isPossiblyOverflowOpcode(CE->getOpcode()); + } + static bool classof(const Instruction *I) { + return isPossiblyOverflowOpcode(I->getOpcode()); + } + static bool classof(const Value *V) { + return (isa(V) && classof(cast(V))) || + (isa(V) && classof(cast(V))); + } +}; + /// Convenience struct for specifying and reasoning about fast-math flags. class FastMathFlags { private: @@ -399,10 +437,10 @@ }; class SDivOperator - : public ConcreteOperator { + : public ConcreteOperator { }; class UDivOperator - : public ConcreteOperator { + : public ConcreteOperator { }; class AShrOperator : public ConcreteOperator { Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -339,6 +339,7 @@ void initializeSanitizerCoverageModulePass(PassRegistry&); void initializeScalarEvolutionWrapperPassPass(PassRegistry&); void initializeScalarizeMaskedMemIntrinPass(PassRegistry&); +void initializeScalarizeMayOverflowDivPass(PassRegistry&); void initializeScalarizerPass(PassRegistry&); void initializeScavengerTestPass(PassRegistry&); void initializeScopedNoAliasAAWrapperPassPass(PassRegistry&); Index: include/llvm/LinkAllPasses.h =================================================================== --- include/llvm/LinkAllPasses.h +++ include/llvm/LinkAllPasses.h @@ -210,6 +210,7 @@ (void) llvm::createFloat2IntPass(); (void) llvm::createEliminateAvailableExternallyPass(); (void) llvm::createScalarizeMaskedMemIntrinPass(); + (void) llvm::createScalarizeMayOverflowDivPass(); (void)new llvm::IntervalPartition(); (void)new llvm::ScalarEvolutionWrapperPass(); Index: lib/Analysis/TargetTransformInfo.cpp =================================================================== --- lib/Analysis/TargetTransformInfo.cpp +++ lib/Analysis/TargetTransformInfo.cpp @@ -175,6 +175,14 @@ return TTIImpl->isLegalMaskedScatter(DataType); } +bool TargetTransformInfo::isLegalMayOverflowUDiv(Type *DataType) const { + return TTIImpl->isLegalMayOverflowUDiv(DataType); +} + +bool TargetTransformInfo::isLegalMayOverflowSDiv(Type *DataType) const { + return TTIImpl->isLegalMayOverflowSDiv(DataType); +} + bool TargetTransformInfo::hasDivRemOp(Type *DataType, bool IsSigned) const { return TTIImpl->hasDivRemOp(DataType, IsSigned); } Index: lib/AsmParser/LLLexer.cpp =================================================================== --- lib/AsmParser/LLLexer.cpp +++ lib/AsmParser/LLLexer.cpp @@ -558,6 +558,8 @@ KEYWORD(nuw); KEYWORD(nsw); KEYWORD(exact); + KEYWORD(nof); + KEYWORD(mof); KEYWORD(inbounds); KEYWORD(inrange); KEYWORD(align); Index: lib/AsmParser/LLParser.cpp =================================================================== --- lib/AsmParser/LLParser.cpp +++ lib/AsmParser/LLParser.cpp @@ -3174,6 +3174,7 @@ bool NUW = false; bool NSW = false; bool Exact = false; + bool NOF = true; unsigned Opc = Lex.getUIntVal(); Constant *Val0, *Val1; Lex.Lex(); @@ -3191,6 +3192,18 @@ Opc == Instruction::LShr || Opc == Instruction::AShr) { if (EatIfPresent(lltok::kw_exact)) Exact = true; + if (Opc == Instruction::SDiv || Opc == Instruction::UDiv) { + if (EatIfPresent(lltok::kw_nof)) { + NOF = true; + if (EatIfPresent(lltok::kw_exact)) + Exact = true; + } + else if (EatIfPresent(lltok::kw_mof)) { + NOF = false; + if (EatIfPresent(lltok::kw_exact)) + Exact = true; + } + } } if (ParseToken(lltok::lparen, "expected '(' in binary constantexpr") || ParseGlobalTypeAndValue(Val0) || @@ -3235,6 +3248,7 @@ if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap; if (NSW) Flags |= OverflowingBinaryOperator::NoSignedWrap; if (Exact) Flags |= PossiblyExactOperator::IsExact; + if (!NOF) Flags |= PossiblyOverflowOperator::MayOverflow; Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags); ID.ConstantVal = C; ID.Kind = ValID::t_Constant; @@ -5266,9 +5280,23 @@ case lltok::kw_lshr: case lltok::kw_ashr: { bool Exact = EatIfPresent(lltok::kw_exact); + bool NOF = true; + + if (Token == lltok::kw_sdiv || Token == lltok::kw_udiv) { + if (EatIfPresent(lltok::kw_nof)) { + if (EatIfPresent(lltok::kw_exact)) + Exact = true; + } + else if (EatIfPresent(lltok::kw_mof)) { + NOF = false; + if (EatIfPresent(lltok::kw_exact)) + Exact = true; + } + } if (ParseArithmetic(Inst, PFS, KeywordVal, 1)) return true; if (Exact) cast(Inst)->setIsExact(true); + if (!NOF) cast(Inst)->setIsNoOverflow(false); return false; } Index: lib/AsmParser/LLToken.h =================================================================== --- lib/AsmParser/LLToken.h +++ lib/AsmParser/LLToken.h @@ -108,6 +108,8 @@ kw_nuw, kw_nsw, kw_exact, + kw_nof, + kw_mof, kw_inbounds, kw_inrange, kw_align, Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -2324,6 +2324,11 @@ Opc == Instruction::AShr) { if (Record[3] & (1 << bitc::PEO_EXACT)) Flags |= SDivOperator::IsExact; + if (Opc == Instruction::SDiv || + Opc == Instruction::UDiv) { + if (Record[3] & (1 << bitc::POO_MAY_OVERFLOW)) + Flags |= SDivOperator::MayOverflow; + } } } V = ConstantExpr::get(Opc, LHS, RHS, Flags); @@ -3528,6 +3533,13 @@ Opc == Instruction::AShr) { if (Record[OpNum] & (1 << bitc::PEO_EXACT)) cast(I)->setIsExact(true); + if (Opc == Instruction::SDiv || + Opc == Instruction::UDiv) { + if (Record[OpNum] & (1 << bitc::POO_MAY_OVERFLOW)) + cast(I)->setIsNoOverflow(false); + else + cast(I)->setIsNoOverflow(true); + } } else if (isa(I)) { FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]); if (FMF.any()) Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1332,6 +1332,11 @@ } else if (const auto *PEO = dyn_cast(V)) { if (PEO->isExact()) Flags |= 1 << bitc::PEO_EXACT; + if (const auto *POO = dyn_cast(V)) { + // flag is set when "MayOverflow" and unset when "NoOverflow" + if (!POO->isNoOverflow()) + Flags |= 1 << bitc::POO_MAY_OVERFLOW; // TODO: rename the constant + } } else if (const auto *FPMO = dyn_cast(V)) { if (FPMO->hasAllowReassoc()) Flags |= FastMathFlags::AllowReassoc; Index: lib/CodeGen/CMakeLists.txt =================================================================== --- lib/CodeGen/CMakeLists.txt +++ lib/CodeGen/CMakeLists.txt @@ -127,6 +127,7 @@ SafeStackColoring.cpp SafeStackLayout.cpp ScalarizeMaskedMemIntrin.cpp + ScalarizeMayOverflowDiv.cpp ScheduleDAG.cpp ScheduleDAGInstrs.cpp ScheduleDAGPrinter.cpp Index: lib/CodeGen/CodeGen.cpp =================================================================== --- lib/CodeGen/CodeGen.cpp +++ lib/CodeGen/CodeGen.cpp @@ -86,6 +86,7 @@ initializeRenameIndependentSubregsPass(Registry); initializeSafeStackLegacyPassPass(Registry); initializeScalarizeMaskedMemIntrinPass(Registry); + initializeScalarizeMayOverflowDivPass(Registry); initializeShrinkWrapPass(Registry); initializeSlotIndexesPass(Registry); initializeStackColoringPass(Registry); Index: lib/CodeGen/ScalarizeMayOverflowDiv.cpp =================================================================== --- lib/CodeGen/ScalarizeMayOverflowDiv.cpp +++ lib/CodeGen/ScalarizeMayOverflowDiv.cpp @@ -0,0 +1,268 @@ +//===- ScalarizeMayOverflowDiv.cpp - Scalarize unsupported may overflow ---===// +// integer division +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass replaces may overflow divisions - when unsupported by the target +// - with a sequence of gaurded no overflowing divisions +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/Twine.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Constant.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Type.h" +#include "llvm/IR/Value.h" +#include "llvm/Pass.h" +#include "llvm/Support/Casting.h" +#include +#include + +using namespace llvm; + +#define DEBUG_TYPE "scalarize-may-overflow-div" + +namespace { + +class ScalarizeMayOverflowDiv : public FunctionPass { + const TargetTransformInfo *TTI = nullptr; + +public: + static char ID; // Pass identification, replacement for typeid + + explicit ScalarizeMayOverflowDiv() : FunctionPass(ID) { + initializeScalarizeMayOverflowDivPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override; + + StringRef getPassName() const override { + return "Scalarize May Overflow Div"; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + } + +private: + bool fixMayOverflowIntegerDiv(Instruction &I, bool isSigned); +}; + +} // end anonymous namespace + +char ScalarizeMayOverflowDiv::ID = 0; + +INITIALIZE_PASS(ScalarizeMayOverflowDiv, DEBUG_TYPE, + "Scalarize unsupported may overflow divisions", false, false) + +FunctionPass *llvm::createScalarizeMayOverflowDivPass() { + return new ScalarizeMayOverflowDiv(); +} + +bool ScalarizeMayOverflowDiv::runOnFunction(Function &F) { + if (skipFunction(F)) + return false; + + bool EverMadeChange = false; + TTI = &getAnalysis().getTTI(F); + /// Search for unsupported may overflow division and replace it with 'nof' + /// integer division sequence + SmallVector SDivInsts; + SmallVector UDivInsts; + for (BasicBlock &BB : F) { + for (Instruction &I : BB) { + if (I.getOpcode() == Instruction::SDiv && !I.isNoOverflow() && + !TTI->isLegalMayOverflowSDiv(I.getType())) + SDivInsts.push_back(&I); + if (I.getOpcode() == Instruction::UDiv && !I.isNoOverflow() && + !TTI->isLegalMayOverflowUDiv(I.getType())) + UDivInsts.push_back(&I); + } + } + for (auto &I : SDivInsts) + EverMadeChange |= fixMayOverflowIntegerDiv(*I, true); + for (auto &I : UDivInsts) + EverMadeChange |= fixMayOverflowIntegerDiv(*I, false); + return EverMadeChange; +} + +/// replace the unsupported division with a scalar safe code +bool ScalarizeMayOverflowDiv::fixMayOverflowIntegerDiv(Instruction &I, + bool isSigned) { + assert((I.getOpcode() == Instruction::SDiv || + I.getOpcode() == Instruction::UDiv) && + "unexpected instruction"); + + IRBuilder<> Builder(I.getContext()); + Instruction *InsertPt = &I; + BasicBlock *IfBlock = I.getParent(); + BasicBlock *CondBlock = nullptr; + BasicBlock *PrevIfBlock = I.getParent(); + + Builder.SetInsertPoint(InsertPt); + Builder.SetCurrentDebugLocation(I.getDebugLoc()); + + Value *B = I.getOperand(0); + Value *C = I.getOperand(1); + Value *UndefVal = UndefValue::get(I.getType()); + PHINode *Phi = nullptr; + + // scalar version case + if (!I.getType()->isVectorTy()) { + // %a = sdiv mof Ty %b, %c ; may overflow or div by zero + // + // can be transformmed to: + // + // BB.cond (unsigned version): + // %cmp = icmp ne Ty %c, 0 + // br %cmp, %BB.true, %BB.merge + // + // BB.cond (signed version): + // %cmp1= icmp ne Ty %c, 0 + // %cmp2= icmp ne Ty %c, -1 + // %cmp3= icmp ne Ty %b, MIN_SIGNED_Ty ;(-2147483648 in case of i32) + // ; NOTE: -2147483648/-1 Overflow + // %overflowcheck = or i1 %cmp2, %cmp3 ; false means we have overflow + // %cmp = and i1 %cmp1, %overflowcheck + // br %cmp, %BB.true, %BB.merge + // BB.true: + // %a.1 = sdiv nof Ty %b, %c + // br %BB.merge + // BB.merge: + // %a = phi [Ty %a.1, %BB.true] [Ty undef, %BB.cond] + Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_NE, C, + ConstantInt::get(C->getType(), 0)); + if (isSigned) { + APInt MinVal = + APInt::getSignedMinValue(B->getType()->getIntegerBitWidth()); + Value *CmpPart2 = Builder.CreateICmp( + ICmpInst::ICMP_NE, C, ConstantInt::getSigned(C->getType(), -1)); + Value *CmpPart3 = Builder.CreateICmp( + ICmpInst::ICMP_NE, B, ConstantInt::get(B->getType(), MinVal)); + Value *OverflowCheck = Builder.CreateOr(CmpPart2, CmpPart3); + Cmp = Builder.CreateAnd(OverflowCheck, Cmp); + } + CondBlock = IfBlock->splitBasicBlock(InsertPt->getIterator(), "cond.div"); + Builder.SetInsertPoint(InsertPt); + + Value *Result = isSigned ? Builder.CreateSDiv(B, C, "", I.isExact()) + : Builder.CreateUDiv(B, C, "", I.isExact()); + + // Create "else" block, fill it in the next iteration + BasicBlock *NewIfBlock = + CondBlock->splitBasicBlock(InsertPt->getIterator(), "else"); + Builder.SetInsertPoint(InsertPt); + + Instruction *OldBr = IfBlock->getTerminator(); + BranchInst::Create(CondBlock, NewIfBlock, Cmp, OldBr); + OldBr->eraseFromParent(); + + Phi = Builder.CreatePHI(I.getType(), 2, "res.phi.select"); + Phi->addIncoming(Result, CondBlock); + Phi->addIncoming(UndefVal, IfBlock); + I.replaceAllUsesWith(Phi); + I.eraseFromParent(); + + return true; + } + + // Vector Case: + // Similar to scalar we start by computing overflowing lanes, after that + // on each lane that has an overflow case we put undef in the relevant + // result lane otherwise we perform scalar nof div operation + // + // output example: (signed version) + // base: + // ... + // %cmp1= icmp ne %c, zeroinitializer + // %cmp2= icmp ne %c, + // %cmp3= icmp ne %b, + // %overflow = or %cmp2, %cmp3 + // %cmp = and %overflow, %cmp1 ; contains overflow status + // ; for each lane + // %cmp.idx.0 = extractelement %cmp, i32 0 ; 1st lane status + // br i1 %cmp.idx, label %cond.div.0, label %else.0 + // + // cond.div.0: + // %b.0 = extractelement %b, i32 0 + // %c.0 = extractelement %c, i32 0 + // %a.0 = sdiv nof %b.0, %c.0 + // %tmp = insertelement undef, %a.0, 0 + // br label %else.0 + // + // else.0: + // %res.phi.else = phi <4 x i32> [ %tmp, %cond.div ], [ undef, %base ] + // %cmp.idx.1 = extractelement %cmp, i32 1 ; 2nd lane status + // br i1 %cmp.idx.1, label %cond.div.1, label %else.1 + // + // ... + // + Value *VResult = UndefVal; + Value *PrevPhi = UndefVal; + unsigned VectorWidth = I.getType()->getVectorNumElements(); + Type *ElementTy = I.getType()->getVectorElementType(); + Value *ZeroVector = ConstantInt::get(I.getType(), 0); + Value *MinusOneVector = ConstantInt::getSigned(I.getType(), -1); + Value *SignedMinVector = ConstantInt::get( + I.getType(), APInt::getSignedMinValue(ElementTy->getIntegerBitWidth())); + Value *Cmp = Builder.CreateICmp(ICmpInst::ICMP_NE, C, ZeroVector); + if (isSigned) { + Value *CmpPart2 = Builder.CreateICmp(ICmpInst::ICMP_NE, C, MinusOneVector); + Value *CmpPart3 = Builder.CreateICmp(ICmpInst::ICMP_NE, B, SignedMinVector); + Value *OverflowCheck = Builder.CreateOr(CmpPart2, CmpPart3); + Cmp = Builder.CreateAnd(OverflowCheck, Cmp); + } + + for (unsigned Idx = 0; Idx < VectorWidth; ++Idx) { + if (Idx > 0) { + Phi = Builder.CreatePHI(I.getType(), 2, "res.phi.else"); + Phi->addIncoming(VResult, CondBlock); + Phi->addIncoming(PrevPhi, PrevIfBlock); + PrevPhi = Phi; + VResult = Phi; + } + + Value *CmpIdx = Builder.CreateExtractElement(Cmp, Idx); + CondBlock = IfBlock->splitBasicBlock(InsertPt->getIterator(), "cond.div"); + Builder.SetInsertPoint(InsertPt); + Value *BIdx = Builder.CreateExtractElement(B, Idx); + Value *CIdx = Builder.CreateExtractElement(C, Idx); + Value *EltDiv = isSigned ? Builder.CreateSDiv(BIdx, CIdx, "", I.isExact()) + : Builder.CreateUDiv(BIdx, CIdx, "", I.isExact()); + VResult = Builder.CreateInsertElement(VResult, EltDiv, Idx); + + // Create "else" block, fill it in the next iteration + BasicBlock *NewIfBlock = + CondBlock->splitBasicBlock(InsertPt->getIterator(), "else"); + Builder.SetInsertPoint(InsertPt); + Instruction *OldBr = IfBlock->getTerminator(); + BranchInst::Create(CondBlock, NewIfBlock, CmpIdx, OldBr); + OldBr->eraseFromParent(); + + PrevIfBlock = IfBlock; + IfBlock = NewIfBlock; + } + Phi = Builder.CreatePHI(I.getType(), 2, "res.phi.select"); + Phi->addIncoming(VResult, CondBlock); + Phi->addIncoming(PrevPhi, PrevIfBlock); + I.replaceAllUsesWith(Phi); + I.eraseFromParent(); + + return true; +} Index: lib/CodeGen/TargetPassConfig.cpp =================================================================== --- lib/CodeGen/TargetPassConfig.cpp +++ lib/CodeGen/TargetPassConfig.cpp @@ -160,7 +160,7 @@ "Enable unification-based CFL-AA"), clEnumValN(CFLAAType::Andersen, "anders", "Enable inclusion-based CFL-AA"), - clEnumValN(CFLAAType::Both, "both", + clEnumValN(CFLAAType::Both, "both", "Enable both variants of CFL-AA"))); /// Option names for limiting the codegen pipeline. @@ -623,6 +623,11 @@ // that stores/loads element one-by-one if the appropriate mask bit is set. addPass(createScalarizeMaskedMemIntrinPass()); + // Add scalarization of target's unsupported may overflow integer divisions. + // the unsupported instruction will be replace with a chain of basic blocks, + // that divide element one-by-one if the appropriate lane is has safe values. + addPass(createScalarizeMayOverflowDivPass()); + // Expand reduction intrinsics into shuffle sequences if the target wants to. addPass(createExpandReductionsPass()); } Index: lib/IR/AsmWriter.cpp =================================================================== --- lib/IR/AsmWriter.cpp +++ lib/IR/AsmWriter.cpp @@ -1129,9 +1129,20 @@ dyn_cast(U)) { if (Div->isExact()) Out << " exact"; + if (const auto *PO = dyn_cast(U)) { + if (PO->isNoOverflow()) + Out << " nof"; + else + Out << " mof"; + } } else if (const GEPOperator *GEP = dyn_cast(U)) { if (GEP->isInBounds()) Out << " inbounds"; + } else if (const auto *PO = dyn_cast(U)) { + if (PO->isNoOverflow()) + Out << " nof"; + else + Out << " mof"; } } Index: lib/IR/Constants.cpp =================================================================== --- lib/IR/Constants.cpp +++ lib/IR/Constants.cpp @@ -2144,14 +2144,18 @@ return get(Instruction::FMul, C1, C2); } -Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact) { - return get(Instruction::UDiv, C1, C2, - isExact ? PossiblyExactOperator::IsExact : 0); +Constant *ConstantExpr::getUDiv(Constant *C1, Constant *C2, bool isExact, + bool isNoOverflow) { + unsigned Flags = (isExact ? PossiblyExactOperator::IsExact : 0) | + (isNoOverflow ? 0 : PossiblyOverflowOperator::MayOverflow); + return get(Instruction::UDiv, C1, C2, Flags); } -Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact) { - return get(Instruction::SDiv, C1, C2, - isExact ? PossiblyExactOperator::IsExact : 0); +Constant *ConstantExpr::getSDiv(Constant *C1, Constant *C2, bool isExact, + bool isNoOverflow) { + unsigned Flags = (isExact ? PossiblyExactOperator::IsExact : 0) | + (isNoOverflow ? 0 : PossiblyOverflowOperator::MayOverflow); + return get(Instruction::SDiv, C1, C2, Flags); } Constant *ConstantExpr::getFDiv(Constant *C1, Constant *C2) { @@ -2912,6 +2916,9 @@ } if (isa(BO)) BO->setIsExact(SubclassOptionalData & PossiblyExactOperator::IsExact); + if (isa(BO)) + BO->setIsNoOverflow(!(SubclassOptionalData & + PossiblyOverflowOperator::MayOverflow)); return BO; } } Index: lib/IR/Instruction.cpp =================================================================== --- lib/IR/Instruction.cpp +++ lib/IR/Instruction.cpp @@ -109,6 +109,10 @@ cast(this)->setIsExact(b); } +void Instruction::setIsNoOverflow(bool b) { + cast(this)->setIsNoOverflow(b); +} + bool Instruction::hasNoUnsignedWrap() const { return cast(this)->hasNoUnsignedWrap(); } @@ -129,6 +133,7 @@ case Instruction::UDiv: case Instruction::SDiv: + cast(this)->setIsNoOverflow(true); case Instruction::AShr: case Instruction::LShr: cast(this)->setIsExact(false); @@ -144,6 +149,10 @@ return cast(this)->isExact(); } +bool Instruction::isNoOverflow() const { + return cast(this)->isNoOverflow(); +} + void Instruction::setFast(bool B) { assert(isa(this) && "setting fast-math flag on invalid op"); cast(this)->setFast(B); @@ -252,6 +261,11 @@ if (isa(this)) setIsExact(PE->isExact()); + // Copy the no-overflow flag + if (auto *PO = dyn_cast(V)) + if (isa(this)) + setIsNoOverflow(PO->isNoOverflow()); + // Copy the fast-math flags. if (auto *FP = dyn_cast(V)) if (isa(this)) @@ -274,6 +288,10 @@ if (isa(this)) setIsExact(isExact() & PE->isExact()); + if (auto *PO = dyn_cast(V)) + if (isa(this)) + setIsNoOverflow(isNoOverflow() & PO->isNoOverflow()); + if (auto *FP = dyn_cast(V)) { if (isa(this)) { FastMathFlags FM = getFastMathFlags(); Index: lib/Target/X86/X86TargetTransformInfo.h =================================================================== --- lib/Target/X86/X86TargetTransformInfo.h +++ lib/Target/X86/X86TargetTransformInfo.h @@ -125,6 +125,8 @@ bool isLegalMaskedStore(Type *DataType); bool isLegalMaskedGather(Type *DataType); bool isLegalMaskedScatter(Type *DataType); + bool isLegalMayOverflowUDiv(Type *DataType); + bool isLegalMayOverflowSDiv(Type *DataType); bool hasDivRemOp(Type *DataType, bool IsSigned); bool isFCmpOrdCheaperThanFCmpZero(Type *Ty); bool areInlineCompatible(const Function *Caller, Index: lib/Target/X86/X86TargetTransformInfo.cpp =================================================================== --- lib/Target/X86/X86TargetTransformInfo.cpp +++ lib/Target/X86/X86TargetTransformInfo.cpp @@ -2540,6 +2540,14 @@ return isLegalMaskedGather(DataType); } +bool X86TTIImpl::isLegalMayOverflowUDiv(Type *DataType) { + return false; +} + +bool X86TTIImpl::isLegalMayOverflowSDiv(Type *DataType) { + return isLegalMayOverflowUDiv(DataType); +} + bool X86TTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) { EVT VT = TLI->getValueType(DL, DataType); return TLI->isOperationLegal(IsSigned ? ISD::SDIVREM : ISD::UDIVREM, VT); Index: lib/Transforms/InstCombine/InstCombineAddSub.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -1629,8 +1629,11 @@ // 0 - (X sdiv C) -> (X sdiv -C) provided the negation doesn't overflow. if (match(Op1, m_SDiv(m_Value(X), m_Constant(C))) && match(Op0, m_Zero()) && - C->isNotMinSignedValue() && !C->isOneValue()) - return BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(C)); + C->isNotMinSignedValue() && !C->isOneValue()) { + Instruction *BinOp = BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(C)); + BinOp->setIsNoOverflow(cast(Op1)->isNoOverflow()); + return BinOp; + } // 0 - (X << Y) -> (-X << Y) when X is freely negatable. if (match(Op1, m_Shl(m_Value(X), m_Value(Y))) && match(Op0, m_Zero())) Index: lib/Transforms/InstCombine/InstCombineMulDivRem.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineMulDivRem.cpp +++ lib/Transforms/InstCombine/InstCombineMulDivRem.cpp @@ -918,9 +918,12 @@ if ((IsSigned && match(LHS, m_SDiv(m_Value(X), m_APInt(C1)))) || (!IsSigned && match(LHS, m_UDiv(m_Value(X), m_APInt(C1))))) { APInt Product(C1->getBitWidth(), /*Val=*/0ULL, IsSigned); - if (!MultiplyOverflows(*C1, *C2, Product, IsSigned)) - return BinaryOperator::Create(I.getOpcode(), X, - ConstantInt::get(I.getType(), Product)); + if (!MultiplyOverflows(*C1, *C2, Product, IsSigned)) { + Instruction *BinOp = BinaryOperator::Create( + I.getOpcode(), X, ConstantInt::get(I.getType(), Product)); + BinOp->setIsNoOverflow(I.isNoOverflow() && LHS->isNoOverflow()); + return BinOp; + } } if ((IsSigned && match(LHS, m_NSWMul(m_Value(X), m_APInt(C1)))) || @@ -932,6 +935,7 @@ BinaryOperator *BO = BinaryOperator::Create( I.getOpcode(), X, ConstantInt::get(X->getType(), Quotient)); BO->setIsExact(I.isExact()); + BO->setIsNoOverflow(I.isNoOverflow()); return BO; } @@ -960,6 +964,7 @@ BinaryOperator *BO = BinaryOperator::Create( I.getOpcode(), X, ConstantInt::get(X->getType(), Quotient)); BO->setIsExact(I.isExact()); + BO->setIsNoOverflow(I.isNoOverflow()); return BO; } @@ -1006,8 +1011,11 @@ Value *X, *Z; if (match(Op0, m_Sub(m_Value(X), m_Value(Z)))) // (X - Z) / Y; Y = Op1 if ((IsSigned && match(Z, m_SRem(m_Specific(X), m_Specific(Op1)))) || - (!IsSigned && match(Z, m_URem(m_Specific(X), m_Specific(Op1))))) - return BinaryOperator::Create(I.getOpcode(), X, Op1); + (!IsSigned && match(Z, m_URem(m_Specific(X), m_Specific(Op1))))) { + Instruction *BinOp = BinaryOperator::Create(I.getOpcode(), X, Op1); + BinOp->setIsNoOverflow(I.isNoOverflow()); + return BinOp; + } // (X << Y) / X -> 1 << Y Value *Y; @@ -1163,6 +1171,9 @@ // udiv (zext X), (zext Y) --> zext (udiv X, Y) // urem (zext X), (zext Y) --> zext (urem X, Y) Value *NarrowOp = Builder.CreateBinOp(Opcode, X, Y); + Instruction *BinOp = dyn_cast(NarrowOp); + if (BinOp && isa(NarrowOp)) + BinOp->setIsNoOverflow(I.isNoOverflow()); return new ZExtInst(NarrowOp, Ty); } @@ -1180,6 +1191,9 @@ // urem C, (zext X) --> zext (urem C', X) Value *NarrowOp = isa(D) ? Builder.CreateBinOp(Opcode, X, TruncC) : Builder.CreateBinOp(Opcode, TruncC, X); + Instruction *BinOp = dyn_cast(NarrowOp); + if (BinOp && isa(NarrowOp)) + BinOp->setIsNoOverflow(I.isNoOverflow()); return new ZExtInst(NarrowOp, Ty); } @@ -1213,6 +1227,7 @@ X, ConstantInt::get(X->getType(), C2ShlC1)); if (IsExact) BO->setIsExact(); + BO->setIsNoOverflow(I.isNoOverflow()); return BO; } } @@ -1308,6 +1323,7 @@ if (match(Op0, m_NSWSub(m_Zero(), m_Value(X)))) { auto *BO = BinaryOperator::CreateSDiv(X, ConstantExpr::getNeg(RHS)); BO->setIsExact(I.isExact()); + BO->setIsNoOverflow(I.isNoOverflow()); return BO; } } @@ -1320,6 +1336,7 @@ // X sdiv Y -> X udiv Y, iff X and Y don't have sign bit set auto *BO = BinaryOperator::CreateUDiv(Op0, Op1, I.getName()); BO->setIsExact(I.isExact()); + BO->setIsNoOverflow(I.isNoOverflow()); return BO; } @@ -1330,6 +1347,7 @@ // the sign bit set. auto *BO = BinaryOperator::CreateUDiv(Op0, Op1, I.getName()); BO->setIsExact(I.isExact()); + BO->setIsNoOverflow(I.isNoOverflow()); return BO; } } Index: lib/Transforms/InstCombine/InstCombineVectorOps.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -967,6 +967,9 @@ if (isa(BO)) { New->setIsExact(BO->isExact()); } + if (isa(BO)) { + New->setIsNoOverflow(BO->isNoOverflow()); + } if (isa(BO)) New->copyFastMathFlags(I); return New; Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -938,9 +938,11 @@ std::swap(Op0, Op1); Value *RI = Builder.CreateBinOp(I->getOpcode(), Op0, Op1, "phitmp"); - auto *FPInst = dyn_cast(RI); - if (FPInst && isa(FPInst)) - FPInst->copyFastMathFlags(I); + auto *Inst = dyn_cast(RI); + if (Inst && isa(RI)) + Inst->setIsNoOverflow(I->isNoOverflow()); + if (Inst && isa(Inst)) + Inst->copyFastMathFlags(I); return RI; } Index: lib/Transforms/Scalar/CorrelatedValuePropagation.cpp =================================================================== --- lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -459,6 +459,7 @@ auto *BO = BinaryOperator::CreateUDiv(SDI->getOperand(0), SDI->getOperand(1), SDI->getName(), SDI); BO->setIsExact(SDI->isExact()); + BO->setIsNoOverflow(SDI->isNoOverflow()); SDI->replaceAllUsesWith(BO); SDI->eraseFromParent(); Index: lib/Transforms/Utils/SimplifyIndVar.cpp =================================================================== --- lib/Transforms/Utils/SimplifyIndVar.cpp +++ lib/Transforms/Utils/SimplifyIndVar.cpp @@ -292,6 +292,7 @@ BinaryOperator::UDiv, SDiv->getOperand(0), SDiv->getOperand(1), SDiv->getName() + ".udiv", SDiv); UDiv->setIsExact(SDiv->isExact()); + UDiv->setIsNoOverflow(SDiv->isNoOverflow()); SDiv->replaceAllUsesWith(UDiv); DEBUG(dbgs() << "INDVARS: Simplified sdiv: " << *SDiv << '\n'); ++NumSimplifiedSDiv; Index: test/Analysis/CostModel/SystemZ/div-pow2.ll =================================================================== --- test/Analysis/CostModel/SystemZ/div-pow2.ll +++ test/Analysis/CostModel/SystemZ/div-pow2.ll @@ -3,152 +3,152 @@ ; Scalar sdiv define i64 @fun0(i64 %a) { - %r = sdiv i64 %a, 2 + %r = sdiv nof i64 %a, 2 ret i64 %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv i64 %a, 2 +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof i64 %a, 2 } define i64 @fun1(i64 %a) { - %r = sdiv i64 %a, -4 + %r = sdiv nof i64 %a, -4 ret i64 %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv i64 %a, -4 +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof i64 %a, -4 } define i32 @fun2(i32 %a) { - %r = sdiv i32 %a, 8 + %r = sdiv nof i32 %a, 8 ret i32 %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv i32 %a, 8 +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof i32 %a, 8 } define i32 @fun3(i32 %a) { - %r = sdiv i32 %a, -16 + %r = sdiv nof i32 %a, -16 ret i32 %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv i32 %a, -16 +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof i32 %a, -16 } define i16 @fun4(i16 %a) { - %r = sdiv i16 %a, 32 + %r = sdiv nof i16 %a, 32 ret i16 %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv i16 %a, 32 +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof i16 %a, 32 } define i16 @fun5(i16 %a) { - %r = sdiv i16 %a, -64 + %r = sdiv nof i16 %a, -64 ret i16 %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv i16 %a, -64 +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof i16 %a, -64 } define i8 @fun6(i8 %a) { - %r = sdiv i8 %a, 64 + %r = sdiv nof i8 %a, 64 ret i8 %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv i8 %a, 64 +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof i8 %a, 64 } define i8 @fun7(i8 %a) { - %r = sdiv i8 %a, -128 + %r = sdiv nof i8 %a, -128 ret i8 %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv i8 %a, -128 +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof i8 %a, -128 } ; Vector sdiv define <2 x i64> @fun8(<2 x i64> %a) { - %r = sdiv <2 x i64> %a, + %r = sdiv nof <2 x i64> %a, ret <2 x i64> %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv <2 x i64> %a, +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof <2 x i64> %a, } define <2 x i64> @fun9(<2 x i64> %a) { - %r = sdiv <2 x i64> %a, + %r = sdiv nof <2 x i64> %a, ret <2 x i64> %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv <2 x i64> %a, +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof <2 x i64> %a, } define <4 x i32> @fun10(<4 x i32> %a) { - %r = sdiv <4 x i32> %a, + %r = sdiv nof <4 x i32> %a, ret <4 x i32> %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv <4 x i32> %a, +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv nof <4 x i32> %a, } define <4 x i32> @fun11(<4 x i32> %a) { - %r = sdiv <4 x i32> %a, + %r = sdiv nof <4 x i32> %a, ret <4 x i32> %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv <4 x i32> %a, %a, @fun12(<8 x i16> %a) { - %r = sdiv <8 x i16> %a, + %r = sdiv nof <8 x i16> %a, ret <8 x i16> %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv <8 x i16> %a, %a, @fun13(<8 x i16> %a) { - %r = sdiv <8 x i16> %a, + %r = sdiv nof <8 x i16> %a, ret <8 x i16> %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv <8 x i16> %a, %a, @fun14(<16 x i8> %a) { - %r = sdiv <16 x i8> %a, + %r = sdiv nof <16 x i8> %a, ret <16 x i8> %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv <16 x i8> %a, %a, @fun15(<16 x i8> %a) { - %r = sdiv <16 x i8> %a, + %r = sdiv nof <16 x i8> %a, ret <16 x i8> %r -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %r = sdiv <16 x i8> %a, %a, @fun20(<2 x i64> %a) { - %r = udiv <2 x i64> %a, + %r = udiv nof <2 x i64> %a, ret <2 x i64> %r -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %r = udiv <2 x i64> %a, %a, @fun21(<4 x i32> %a) { - %r = udiv <4 x i32> %a, + %r = udiv nof <4 x i32> %a, ret <4 x i32> %r -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %r = udiv <4 x i32> %a, %a, @fun22(<8 x i16> %a) { - %r = udiv <8 x i16> %a, + %r = udiv nof <8 x i16> %a, ret <8 x i16> %r -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %r = udiv <8 x i16> %a, %a, @fun23(<16 x i8> %a) { - %r = udiv <16 x i8> %a, + %r = udiv nof <16 x i8> %a, ret <16 x i8> %r -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %r = udiv <16 x i8> %a, %a, undef, undef - %res5 = sdiv <2 x i16> undef, undef - %res6 = sdiv <2 x i32> undef, undef - %res7 = sdiv <2 x i64> undef, undef - %res8 = sdiv <4 x i8> undef, undef - %res9 = sdiv <4 x i16> undef, undef - %res10 = sdiv <4 x i32> undef, undef - %res11 = sdiv <4 x i64> undef, undef - %res12 = sdiv <8 x i8> undef, undef - %res13 = sdiv <8 x i16> undef, undef - %res14 = sdiv <8 x i32> undef, undef - %res15 = sdiv <8 x i64> undef, undef - %res16 = sdiv <16 x i8> undef, undef - %res17 = sdiv <16 x i16> undef, undef - %res18 = sdiv <16 x i32> undef, undef - %res19 = sdiv <16 x i64> undef, undef - -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %res0 = sdiv i8 undef, undef -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %res1 = sdiv i16 undef, undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %res2 = sdiv i32 undef, undef -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %res3 = sdiv i64 undef, undef -; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res4 = sdiv <2 x i8> undef, undef -; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res5 = sdiv <2 x i16> undef, undef -; CHECK: Cost Model: Found an estimated cost of 6 for instruction: %res6 = sdiv <2 x i32> undef, undef -; CHECK: Cost Model: Found an estimated cost of 3 for instruction: %res7 = sdiv <2 x i64> undef, undef -; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res8 = sdiv <4 x i8> undef, undef -; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res9 = sdiv <4 x i16> undef, undef -; CHECK: Cost Model: Found an estimated cost of 12 for instruction: %res10 = sdiv <4 x i32> undef, undef -; CHECK: Cost Model: Found an estimated cost of 6 for instruction: %res11 = sdiv <4 x i64> undef, undef -; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res12 = sdiv <8 x i8> undef, undef -; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res13 = sdiv <8 x i16> undef, undef -; CHECK: Cost Model: Found an estimated cost of 24 for instruction: %res14 = sdiv <8 x i32> undef, undef -; CHECK: Cost Model: Found an estimated cost of 12 for instruction: %res15 = sdiv <8 x i64> undef, undef -; CHECK: Cost Model: Found an estimated cost of 80 for instruction: %res16 = sdiv <16 x i8> undef, undef -; CHECK: Cost Model: Found an estimated cost of 80 for instruction: %res17 = sdiv <16 x i16> undef, undef -; CHECK: Cost Model: Found an estimated cost of 48 for instruction: %res18 = sdiv <16 x i32> undef, undef -; CHECK: Cost Model: Found an estimated cost of 24 for instruction: %res19 = sdiv <16 x i64> undef, undef + %res0 = sdiv nof i8 undef, undef + %res1 = sdiv nof i16 undef, undef + %res2 = sdiv nof i32 undef, undef + %res3 = sdiv nof i64 undef, undef + %res4 = sdiv nof <2 x i8> undef, undef + %res5 = sdiv nof <2 x i16> undef, undef + %res6 = sdiv nof <2 x i32> undef, undef + %res7 = sdiv nof <2 x i64> undef, undef + %res8 = sdiv nof <4 x i8> undef, undef + %res9 = sdiv nof <4 x i16> undef, undef + %res10 = sdiv nof <4 x i32> undef, undef + %res11 = sdiv nof <4 x i64> undef, undef + %res12 = sdiv nof <8 x i8> undef, undef + %res13 = sdiv nof <8 x i16> undef, undef + %res14 = sdiv nof <8 x i32> undef, undef + %res15 = sdiv nof <8 x i64> undef, undef + %res16 = sdiv nof <16 x i8> undef, undef + %res17 = sdiv nof <16 x i16> undef, undef + %res18 = sdiv nof <16 x i32> undef, undef + %res19 = sdiv nof <16 x i64> undef, undef + +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %res0 = sdiv nof i8 undef, undef +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %res1 = sdiv nof i16 undef, undef +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %res2 = sdiv nof i32 undef, undef +; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %res3 = sdiv nof i64 undef, undef +; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res4 = sdiv nof <2 x i8> undef, undef +; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res5 = sdiv nof <2 x i16> undef, undef +; CHECK: Cost Model: Found an estimated cost of 6 for instruction: %res6 = sdiv nof <2 x i32> undef, undef +; CHECK: Cost Model: Found an estimated cost of 3 for instruction: %res7 = sdiv nof <2 x i64> undef, undef +; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res8 = sdiv nof <4 x i8> undef, undef +; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res9 = sdiv nof <4 x i16> undef, undef +; CHECK: Cost Model: Found an estimated cost of 12 for instruction: %res10 = sdiv nof <4 x i32> undef, undef +; CHECK: Cost Model: Found an estimated cost of 6 for instruction: %res11 = sdiv nof <4 x i64> undef, undef +; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res12 = sdiv nof <8 x i8> undef, undef +; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res13 = sdiv nof <8 x i16> undef, undef +; CHECK: Cost Model: Found an estimated cost of 24 for instruction: %res14 = sdiv nof <8 x i32> undef, undef +; CHECK: Cost Model: Found an estimated cost of 12 for instruction: %res15 = sdiv nof <8 x i64> undef, undef +; CHECK: Cost Model: Found an estimated cost of 80 for instruction: %res16 = sdiv nof <16 x i8> undef, undef +; CHECK: Cost Model: Found an estimated cost of 80 for instruction: %res17 = sdiv nof <16 x i16> undef, undef +; CHECK: Cost Model: Found an estimated cost of 48 for instruction: %res18 = sdiv nof <16 x i32> undef, undef +; CHECK: Cost Model: Found an estimated cost of 24 for instruction: %res19 = sdiv nof <16 x i64> undef, undef ret void; } @@ -234,47 +234,47 @@ } define void @udiv() { - %res0 = udiv i8 undef, undef - %res1 = udiv i16 undef, undef - %res2 = udiv i32 undef, undef - %res3 = udiv i64 undef, undef - %res4 = udiv <2 x i8> undef, undef - %res5 = udiv <2 x i16> undef, undef - %res6 = udiv <2 x i32> undef, undef - %res7 = udiv <2 x i64> undef, undef - %res8 = udiv <4 x i8> undef, undef - %res9 = udiv <4 x i16> undef, undef - %res10 = udiv <4 x i32> undef, undef - %res11 = udiv <4 x i64> undef, undef - %res12 = udiv <8 x i8> undef, undef - %res13 = udiv <8 x i16> undef, undef - %res14 = udiv <8 x i32> undef, undef - %res15 = udiv <8 x i64> undef, undef - %res16 = udiv <16 x i8> undef, undef - %res17 = udiv <16 x i16> undef, undef - %res18 = udiv <16 x i32> undef, undef - %res19 = udiv <16 x i64> undef, undef - -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %res0 = udiv i8 undef, undef -; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %res1 = udiv i16 undef, undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %res2 = udiv i32 undef, undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %res3 = udiv i64 undef, undef -; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res4 = udiv <2 x i8> undef, undef -; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res5 = udiv <2 x i16> undef, undef -; CHECK: Cost Model: Found an estimated cost of 6 for instruction: %res6 = udiv <2 x i32> undef, undef -; CHECK: Cost Model: Found an estimated cost of 5 for instruction: %res7 = udiv <2 x i64> undef, undef -; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res8 = udiv <4 x i8> undef, undef -; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res9 = udiv <4 x i16> undef, undef -; CHECK: Cost Model: Found an estimated cost of 12 for instruction: %res10 = udiv <4 x i32> undef, undef -; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res11 = udiv <4 x i64> undef, undef -; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res12 = udiv <8 x i8> undef, undef -; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res13 = udiv <8 x i16> undef, undef -; CHECK: Cost Model: Found an estimated cost of 24 for instruction: %res14 = udiv <8 x i32> undef, undef -; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res15 = udiv <8 x i64> undef, undef -; CHECK: Cost Model: Found an estimated cost of 80 for instruction: %res16 = udiv <16 x i8> undef, undef -; CHECK: Cost Model: Found an estimated cost of 80 for instruction: %res17 = udiv <16 x i16> undef, undef -; CHECK: Cost Model: Found an estimated cost of 48 for instruction: %res18 = udiv <16 x i32> undef, undef -; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res19 = udiv <16 x i64> undef, undef + %res0 = udiv nof i8 undef, undef + %res1 = udiv nof i16 undef, undef + %res2 = udiv nof i32 undef, undef + %res3 = udiv nof i64 undef, undef + %res4 = udiv nof <2 x i8> undef, undef + %res5 = udiv nof <2 x i16> undef, undef + %res6 = udiv nof <2 x i32> undef, undef + %res7 = udiv nof <2 x i64> undef, undef + %res8 = udiv nof <4 x i8> undef, undef + %res9 = udiv nof <4 x i16> undef, undef + %res10 = udiv nof <4 x i32> undef, undef + %res11 = udiv nof <4 x i64> undef, undef + %res12 = udiv nof <8 x i8> undef, undef + %res13 = udiv nof <8 x i16> undef, undef + %res14 = udiv nof <8 x i32> undef, undef + %res15 = udiv nof <8 x i64> undef, undef + %res16 = udiv nof <16 x i8> undef, undef + %res17 = udiv nof <16 x i16> undef, undef + %res18 = udiv nof <16 x i32> undef, undef + %res19 = udiv nof <16 x i64> undef, undef + +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %res0 = udiv nof i8 undef, undef +; CHECK: Cost Model: Found an estimated cost of 4 for instruction: %res1 = udiv nof i16 undef, undef +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %res2 = udiv nof i32 undef, undef +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %res3 = udiv nof i64 undef, undef +; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res4 = udiv nof <2 x i8> undef, undef +; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res5 = udiv nof <2 x i16> undef, undef +; CHECK: Cost Model: Found an estimated cost of 6 for instruction: %res6 = udiv nof <2 x i32> undef, undef +; CHECK: Cost Model: Found an estimated cost of 5 for instruction: %res7 = udiv nof <2 x i64> undef, undef +; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res8 = udiv nof <4 x i8> undef, undef +; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res9 = udiv nof <4 x i16> undef, undef +; CHECK: Cost Model: Found an estimated cost of 12 for instruction: %res10 = udiv nof <4 x i32> undef, undef +; CHECK: Cost Model: Found an estimated cost of 10 for instruction: %res11 = udiv nof <4 x i64> undef, undef +; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res12 = udiv nof <8 x i8> undef, undef +; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res13 = udiv nof <8 x i16> undef, undef +; CHECK: Cost Model: Found an estimated cost of 24 for instruction: %res14 = udiv nof <8 x i32> undef, undef +; CHECK: Cost Model: Found an estimated cost of 20 for instruction: %res15 = udiv nof <8 x i64> undef, undef +; CHECK: Cost Model: Found an estimated cost of 80 for instruction: %res16 = udiv nof <16 x i8> undef, undef +; CHECK: Cost Model: Found an estimated cost of 80 for instruction: %res17 = udiv nof <16 x i16> undef, undef +; CHECK: Cost Model: Found an estimated cost of 48 for instruction: %res18 = udiv nof <16 x i32> undef, undef +; CHECK: Cost Model: Found an estimated cost of 40 for instruction: %res19 = udiv nof <16 x i64> undef, undef ret void; } Index: test/Analysis/CostModel/SystemZ/memop-folding-int-arith.ll =================================================================== --- test/Analysis/CostModel/SystemZ/memop-folding-int-arith.ll +++ test/Analysis/CostModel/SystemZ/memop-folding-int-arith.ll @@ -92,58 +92,58 @@ define void @sdiv() { %li32 = load i32, i32* undef - sdiv i32 %li32, undef + sdiv nof i32 %li32, undef %li32_0 = load i32, i32* undef %li32_1 = load i32, i32* undef - sdiv i32 %li32_0, %li32_1 + sdiv nof i32 %li32_0, %li32_1 %li64 = load i64, i64* undef - sdiv i64 %li64, undef + sdiv nof i64 %li64, undef %li64_0 = load i64, i64* undef %li64_1 = load i64, i64* undef - sdiv i64 %li64_0, %li64_1 + sdiv nof i64 %li64_0, %li64_1 ret void; ; CHECK: Cost Model: Found an estimated cost of 0 for instruction: %li32 = load i32, i32* undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %1 = sdiv i32 %li32, undef +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %1 = sdiv nof i32 %li32, undef ; CHECK: Cost Model: Found an estimated cost of 0 for instruction: %li32_0 = load i32, i32* undef ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %li32_1 = load i32, i32* undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %2 = sdiv i32 %li32_0, %li32_1 +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %2 = sdiv nof i32 %li32_0, %li32_1 ; CHECK: Cost Model: Found an estimated cost of 0 for instruction: %li64 = load i64, i64* undef -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %3 = sdiv i64 %li64, undef +; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %3 = sdiv nof i64 %li64, undef ; CHECK: Cost Model: Found an estimated cost of 0 for instruction: %li64_0 = load i64, i64* undef ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %li64_1 = load i64, i64* undef -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %4 = sdiv i64 %li64_0, %li64_1 +; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %4 = sdiv nof i64 %li64_0, %li64_1 } define void @udiv() { %li32 = load i32, i32* undef - udiv i32 %li32, undef + udiv nof i32 %li32, undef %li32_0 = load i32, i32* undef %li32_1 = load i32, i32* undef - udiv i32 %li32_0, %li32_1 + udiv nof i32 %li32_0, %li32_1 %li64 = load i64, i64* undef - udiv i64 %li64, undef + udiv nof i64 %li64, undef %li64_0 = load i64, i64* undef %li64_1 = load i64, i64* undef - udiv i64 %li64_0, %li64_1 + udiv nof i64 %li64_0, %li64_1 ret void; ; CHECK: Cost Model: Found an estimated cost of 0 for instruction: %li32 = load i32, i32* undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %1 = udiv i32 %li32, undef +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %1 = udiv nof i32 %li32, undef ; CHECK: Cost Model: Found an estimated cost of 0 for instruction: %li32_0 = load i32, i32* undef ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %li32_1 = load i32, i32* undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %2 = udiv i32 %li32_0, %li32_1 +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %2 = udiv nof i32 %li32_0, %li32_1 ; CHECK: Cost Model: Found an estimated cost of 0 for instruction: %li64 = load i64, i64* undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %3 = udiv i64 %li64, undef +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %3 = udiv nof i64 %li64, undef ; CHECK: Cost Model: Found an estimated cost of 0 for instruction: %li64_0 = load i64, i64* undef ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %li64_1 = load i64, i64* undef -; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %4 = udiv i64 %li64_0, %li64_1 +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %4 = udiv nof i64 %li64_0, %li64_1 } define void @and() { Index: test/Analysis/Lint/check-zero-divide.ll =================================================================== --- test/Analysis/Lint/check-zero-divide.ll +++ test/Analysis/Lint/check-zero-divide.ll @@ -1,7 +1,7 @@ ; RUN: opt -lint -disable-output %s 2>&1 | FileCheck %s define <2 x i32> @use_vector_sdiv(<2 x i32> %a) nounwind { - %b = sdiv <2 x i32> %a, + %b = sdiv nof <2 x i32> %a, ret <2 x i32> %b } @@ -11,7 +11,7 @@ } define <2 x i32> @use_vector_udiv(<2 x i32> %a) nounwind { - %b = udiv <2 x i32> %a, + %b = udiv nof <2 x i32> %a, ret <2 x i32> %b } @@ -22,57 +22,57 @@ define i32 @use_sdiv_by_zero(i32 %a) nounwind { ; CHECK: Undefined behavior: Division by zero -; CHECK-NEXT: %b = sdiv i32 %a, 0 - %b = sdiv i32 %a, 0 +; CHECK-NEXT: %b = sdiv nof i32 %a, 0 + %b = sdiv nof i32 %a, 0 ret i32 %b } define i32 @use_sdiv_by_zeroinitializer(i32 %a) nounwind { ; CHECK: Undefined behavior: Division by zero -; CHECK-NEXT: %b = sdiv i32 %a, 0 - %b = sdiv i32 %a, zeroinitializer +; CHECK-NEXT: %b = sdiv nof i32 %a, 0 + %b = sdiv nof i32 %a, zeroinitializer ret i32 %b } define <2 x i32> @use_vector_sdiv_by_zero_x(<2 x i32> %a) nounwind { ; CHECK: Undefined behavior: Division by zero -; CHECK-NEXT: %b = sdiv <2 x i32> %a, - %b = sdiv <2 x i32> %a, +; CHECK-NEXT: %b = sdiv nof <2 x i32> %a, + %b = sdiv nof <2 x i32> %a, ret <2 x i32> %b } define <2 x i32> @use_vector_sdiv_by_zero_y(<2 x i32> %a) nounwind { ; CHECK: Undefined behavior: Division by zero -; CHECK-NEXT: %b = sdiv <2 x i32> %a, - %b = sdiv <2 x i32> %a, +; CHECK-NEXT: %b = sdiv nof <2 x i32> %a, + %b = sdiv nof <2 x i32> %a, ret <2 x i32> %b } define <2 x i32> @use_vector_sdiv_by_zero_xy(<2 x i32> %a) nounwind { ; CHECK: Undefined behavior: Division by zero -; CHECK-NEXT: %b = sdiv <2 x i32> %a, zeroinitializer - %b = sdiv <2 x i32> %a, +; CHECK-NEXT: %b = sdiv nof <2 x i32> %a, zeroinitializer + %b = sdiv nof <2 x i32> %a, ret <2 x i32> %b } define <2 x i32> @use_vector_sdiv_by_undef_x(<2 x i32> %a) nounwind { ; CHECK: Undefined behavior: Division by zero -; CHECK-NEXT: %b = sdiv <2 x i32> %a, - %b = sdiv <2 x i32> %a, +; CHECK-NEXT: %b = sdiv nof <2 x i32> %a, + %b = sdiv nof <2 x i32> %a, ret <2 x i32> %b } define <2 x i32> @use_vector_sdiv_by_undef_y(<2 x i32> %a) nounwind { ; CHECK: Undefined behavior: Division by zero -; CHECK-NEXT: %b = sdiv <2 x i32> %a, - %b = sdiv <2 x i32> %a, +; CHECK-NEXT: %b = sdiv nof <2 x i32> %a, + %b = sdiv nof <2 x i32> %a, ret <2 x i32> %b } define <2 x i32> @use_vector_sdiv_by_undef_xy(<2 x i32> %a) nounwind { ; CHECK: Undefined behavior: Division by zero -; CHECK-NEXT: %b = sdiv <2 x i32> %a, undef - %b = sdiv <2 x i32> %a, +; CHECK-NEXT: %b = sdiv nof <2 x i32> %a, undef + %b = sdiv nof <2 x i32> %a, ret <2 x i32> %b } Index: test/Assembler/div_attrs.ll =================================================================== --- test/Assembler/div_attrs.ll +++ test/Assembler/div_attrs.ll @@ -0,0 +1,53 @@ +; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s + +define void @div_attrs(i8 %op1, i8 %op2) { + ; default + udiv i8 %op1, %op2 + sdiv i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 + + ; nof + udiv nof i8 %op1, %op2 + sdiv nof i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 + + ; mof + udiv mof i8 %op1, %op2 + sdiv mof i8 %op1, %op2 + ; CHECK: udiv mof i8 %op1, %op2 + ; CHECK: sdiv mof i8 %op1, %op2 + + ; exact + udiv exact i8 %op1, %op2 + sdiv exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 + + ; exact nof + udiv exact nof i8 %op1, %op2 + sdiv exact nof i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 + + ; nof exact + udiv nof exact i8 %op1, %op2 + sdiv nof exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 + + ; exact mof + udiv exact mof i8 %op1, %op2 + sdiv exact mof i8 %op1, %op2 + ; CHECK: udiv exact mof i8 %op1, %op2 + ; CHECK: sdiv exact mof i8 %op1, %op2 + + ; mof exact + udiv mof exact i8 %op1, %op2 + sdiv mof exact i8 %op1, %op2 + ; CHECK: udiv exact mof i8 %op1, %op2 + ; CHECK: sdiv exact mof i8 %op1, %op2 + + ret void +} Index: test/Assembler/div_not_allowed.ll =================================================================== --- test/Assembler/div_not_allowed.ll +++ test/Assembler/div_not_allowed.ll @@ -0,0 +1,10 @@ +; XFAIL: * +; This test should fail always nof/mof attributes cann't come together +; RUN: llvm-as %s -o - 2>&1 | FileCheck %s + +define void @div_attrs(i8 %op1, i8 %op2) { + ; default + udiv nof mof i8 %op1, %op2 + + ret void +} Index: test/Assembler/flags.ll =================================================================== --- test/Assembler/flags.ll +++ test/Assembler/flags.ll @@ -100,26 +100,26 @@ } define i64 @sdiv_exact(i64 %x, i64 %y) { -; CHECK: %z = sdiv exact i64 %x, %y - %z = sdiv exact i64 %x, %y +; CHECK: %z = sdiv exact nof i64 %x, %y + %z = sdiv exact nof i64 %x, %y ret i64 %z } define i64 @sdiv_plain(i64 %x, i64 %y) { -; CHECK: %z = sdiv i64 %x, %y - %z = sdiv i64 %x, %y +; CHECK: %z = sdiv nof i64 %x, %y + %z = sdiv nof i64 %x, %y ret i64 %z } define i64 @udiv_exact(i64 %x, i64 %y) { -; CHECK: %z = udiv exact i64 %x, %y - %z = udiv exact i64 %x, %y +; CHECK: %z = udiv exact nof i64 %x, %y + %z = udiv exact nof i64 %x, %y ret i64 %z } define i64 @udiv_plain(i64 %x, i64 %y) { -; CHECK: %z = udiv i64 %x, %y - %z = udiv i64 %x, %y +; CHECK: %z = udiv nof i64 %x, %y + %z = udiv nof i64 %x, %y ret i64 %z } @@ -175,13 +175,13 @@ } define i64 @sdiv_exact_ce() { -; CHECK: ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 sdiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 sdiv exact nof (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 sdiv exact nof (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @udiv_exact_ce() { -; CHECK: ret i64 udiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 udiv exact (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 udiv exact nof (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 udiv exact nof (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64 @ashr_exact_ce() { @@ -215,8 +215,8 @@ } define i64 @sdiv_plain_ce() { -; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91) - ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91) +; CHECK: ret i64 sdiv nof (i64 ptrtoint (i64* @addr to i64), i64 91) + ret i64 sdiv nof (i64 ptrtoint (i64* @addr to i64), i64 91) } define i64* @gep_plain_ce() { Index: test/Bitcode/binaryIntInstructions.3.2.ll =================================================================== --- test/Bitcode/binaryIntInstructions.3.2.ll +++ test/Bitcode/binaryIntInstructions.3.2.ll @@ -141,10 +141,10 @@ define void @udiv(i8 %x1){ entry: -; CHECK: %res1 = udiv i8 %x1, %x1 +; CHECK: %res1 = udiv nof i8 %x1, %x1 %res1 = udiv i8 %x1, %x1 -; CHECK-NEXT: %res2 = udiv exact i8 %x1, %x1 +; CHECK-NEXT: %res2 = udiv exact nof i8 %x1, %x1 %res2 = udiv exact i8 %x1, %x1 ret void @@ -152,10 +152,10 @@ define void @sdiv(i8 %x1){ entry: -; CHECK: %res1 = sdiv i8 %x1, %x1 +; CHECK: %res1 = sdiv nof i8 %x1, %x1 %res1 = sdiv i8 %x1, %x1 -; CHECK-NEXT: %res2 = sdiv exact i8 %x1, %x1 +; CHECK-NEXT: %res2 = sdiv exact nof i8 %x1, %x1 %res2 = sdiv exact i8 %x1, %x1 ret void Index: test/Bitcode/compatibility-3.6.ll =================================================================== --- test/Bitcode/compatibility-3.6.ll +++ test/Bitcode/compatibility-3.6.ll @@ -748,13 +748,13 @@ ; exact udiv i8 %op1, %op2 - ; CHECK: udiv i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 udiv exact i8 %op1, %op2 - ; CHECK: udiv exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 sdiv i8 %op1, %op2 - ; CHECK: sdiv i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 sdiv exact i8 %op1, %op2 - ; CHECK: sdiv exact i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 ; none urem i8 %op1, %op2 Index: test/Bitcode/compatibility-3.7.ll =================================================================== --- test/Bitcode/compatibility-3.7.ll +++ test/Bitcode/compatibility-3.7.ll @@ -790,13 +790,13 @@ ; exact udiv i8 %op1, %op2 - ; CHECK: udiv i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 udiv exact i8 %op1, %op2 - ; CHECK: udiv exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 sdiv i8 %op1, %op2 - ; CHECK: sdiv i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 sdiv exact i8 %op1, %op2 - ; CHECK: sdiv exact i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 ; none urem i8 %op1, %op2 Index: test/Bitcode/compatibility-3.8.ll =================================================================== --- test/Bitcode/compatibility-3.8.ll +++ test/Bitcode/compatibility-3.8.ll @@ -940,13 +940,13 @@ ; exact udiv i8 %op1, %op2 - ; CHECK: udiv i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 udiv exact i8 %op1, %op2 - ; CHECK: udiv exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 sdiv i8 %op1, %op2 - ; CHECK: sdiv i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 sdiv exact i8 %op1, %op2 - ; CHECK: sdiv exact i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 ; none urem i8 %op1, %op2 Index: test/Bitcode/compatibility-3.9.ll =================================================================== --- test/Bitcode/compatibility-3.9.ll +++ test/Bitcode/compatibility-3.9.ll @@ -1011,13 +1011,13 @@ ; exact udiv i8 %op1, %op2 - ; CHECK: udiv i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 udiv exact i8 %op1, %op2 - ; CHECK: udiv exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 sdiv i8 %op1, %op2 - ; CHECK: sdiv i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 sdiv exact i8 %op1, %op2 - ; CHECK: sdiv exact i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 ; none urem i8 %op1, %op2 Index: test/Bitcode/compatibility-4.0.ll =================================================================== --- test/Bitcode/compatibility-4.0.ll +++ test/Bitcode/compatibility-4.0.ll @@ -1011,13 +1011,13 @@ ; exact udiv i8 %op1, %op2 - ; CHECK: udiv i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 udiv exact i8 %op1, %op2 - ; CHECK: udiv exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 sdiv i8 %op1, %op2 - ; CHECK: sdiv i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 sdiv exact i8 %op1, %op2 - ; CHECK: sdiv exact i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 ; none urem i8 %op1, %op2 Index: test/Bitcode/compatibility-5.0.ll =================================================================== --- test/Bitcode/compatibility-5.0.ll +++ test/Bitcode/compatibility-5.0.ll @@ -1018,13 +1018,13 @@ ; exact udiv i8 %op1, %op2 - ; CHECK: udiv i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 udiv exact i8 %op1, %op2 - ; CHECK: udiv exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 sdiv i8 %op1, %op2 - ; CHECK: sdiv i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 sdiv exact i8 %op1, %op2 - ; CHECK: sdiv exact i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 ; none urem i8 %op1, %op2 Index: test/Bitcode/compatibility.ll =================================================================== --- test/Bitcode/compatibility.ll +++ test/Bitcode/compatibility.ll @@ -1029,13 +1029,23 @@ ; exact udiv i8 %op1, %op2 - ; CHECK: udiv i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 udiv exact i8 %op1, %op2 - ; CHECK: udiv exact i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 sdiv i8 %op1, %op2 - ; CHECK: sdiv i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 sdiv exact i8 %op1, %op2 - ; CHECK: sdiv exact i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 + + ; nof + udiv nof i8 %op1, %op2 + ; CHECK: udiv nof i8 %op1, %op2 + udiv exact nof i8 %op1, %op2 + ; CHECK: udiv exact nof i8 %op1, %op2 + sdiv nof i8 %op1, %op2 + ; CHECK: sdiv nof i8 %op1, %op2 + sdiv exact nof i8 %op1, %op2 + ; CHECK: sdiv exact nof i8 %op1, %op2 ; none urem i8 %op1, %op2 Index: test/CodeGen/ARM/vector-promotion.ll =================================================================== --- test/CodeGen/ARM/vector-promotion.ll +++ test/CodeGen/ARM/vector-promotion.ll @@ -125,9 +125,9 @@ ; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 ; Scalar version: ; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 -; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv i32 [[EXTRACT]], 7 +; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv nof i32 [[EXTRACT]], 7 ; Vector version: -; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = udiv <2 x i32> [[LOAD]], +; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = udiv nof <2 x i32> [[LOAD]], ; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1 ; ; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest @@ -135,7 +135,7 @@ define void @udivCase(<2 x i32>* %addr1, i32* %dest) { %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 %extract = extractelement <2 x i32> %in1, i32 1 - %out = udiv i32 %extract, 7 + %out = udiv nof i32 %extract, 7 store i32 %out, i32* %dest, align 4 ret void } @@ -163,9 +163,9 @@ ; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 ; Scalar version: ; IR-NORMAL-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 -; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = sdiv i32 [[EXTRACT]], 7 +; IR-NORMAL-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = sdiv nof i32 [[EXTRACT]], 7 ; Vector version: -; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = sdiv <2 x i32> [[LOAD]], +; IR-STRESS-NEXT: [[DIV:%[a-zA-Z_0-9-]+]] = sdiv nof <2 x i32> [[LOAD]], ; IR-STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[DIV]], i32 1 ; ; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest @@ -173,7 +173,7 @@ define void @sdivCase(<2 x i32>* %addr1, i32* %dest) { %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 %extract = extractelement <2 x i32> %in1, i32 1 - %out = sdiv i32 %extract, 7 + %out = sdiv nof i32 %extract, 7 store i32 %out, i32* %dest, align 4 ret void } @@ -240,13 +240,13 @@ ; IR-BOTH-LABEL: @undefDivCase ; IR-BOTH: [[LOAD:%[a-zA-Z_0-9-]+]] = load <2 x i32>, <2 x i32>* %addr1 ; IR-BOTH-NEXT: [[EXTRACT:%[a-zA-Z_0-9-]+]] = extractelement <2 x i32> [[LOAD]], i32 1 -; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv i32 7, [[EXTRACT]] +; IR-BOTH-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = udiv nof i32 7, [[EXTRACT]] ; IR-BOTH-NEXT: store i32 [[RES]], i32* %dest ; IR-BOTH-NEXT: ret define void @undefDivCase(<2 x i32>* %addr1, i32* %dest) { %in1 = load <2 x i32>, <2 x i32>* %addr1, align 8 %extract = extractelement <2 x i32> %in1, i32 1 - %out = udiv i32 7, %extract + %out = udiv nof i32 7, %extract store i32 %out, i32* %dest, align 4 ret void } Index: test/CodeGen/X86/O0-pipeline.ll =================================================================== --- test/CodeGen/X86/O0-pipeline.ll +++ test/CodeGen/X86/O0-pipeline.ll @@ -24,6 +24,7 @@ ; CHECK-NEXT: Remove unreachable blocks from the CFG ; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) ; CHECK-NEXT: Scalarize Masked Memory Intrinsics +; CHECK-NEXT: Scalarize May Overflow Div ; CHECK-NEXT: Expand reduction intrinsics ; CHECK-NEXT: Expand indirectbr instructions ; CHECK-NEXT: Rewrite Symbols Index: test/Instrumentation/DataFlowSanitizer/arith.ll =================================================================== --- test/Instrumentation/DataFlowSanitizer/arith.ll +++ test/Instrumentation/DataFlowSanitizer/arith.ll @@ -44,10 +44,10 @@ ; CHECK: load{{.*}}__dfsan_arg_tls ; CHECK: load{{.*}}__dfsan_arg_tls ; CHECK: call{{.*}}__dfsan_union - ; CHECK: sdiv i8 + ; CHECK: sdiv nof i8 ; CHECK: store{{.*}}__dfsan_retval_tls ; CHECK: ret i8 - %c = sdiv i8 %a, %b + %c = sdiv nof i8 %a, %b ret i8 %c } @@ -56,9 +56,9 @@ ; CHECK: load{{.*}}__dfsan_arg_tls ; CHECK: load{{.*}}__dfsan_arg_tls ; CHECK: call{{.*}}__dfsan_union - ; CHECK: udiv i8 + ; CHECK: udiv nof i8 ; CHECK: store{{.*}}__dfsan_retval_tls ; CHECK: ret i8 - %c = udiv i8 %a, %b + %c = udiv nof i8 %a, %b ret i8 %c } Index: test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-constant-numerator.ll =================================================================== --- test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-constant-numerator.ll +++ test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-constant-numerator.ll @@ -12,8 +12,8 @@ ; CHECK: icmp eq i64 [[AND]], 0 ; CHECK: [[TRUNC:%[0-9]+]] = trunc i64 %a to i32 - ; CHECK: udiv i32 -1, [[TRUNC]] - %d = sdiv i64 4294967295, %a ; 0xffff'ffff + ; CHECK: udiv nof i32 -1, [[TRUNC]] + %d = sdiv nof i64 4294967295, %a ; 0xffff'ffff ret i64 %d } @@ -21,15 +21,15 @@ ; into the bypass width, leave it as a plain 64-bit div with no bypass. ; CHECK-LABEL: @large_constant_numer define i64 @large_constant_numer(i64 %a) { - ; CHECK-NOT: udiv i32 - %d = sdiv i64 4294967296, %a ; 0x1'0000'0000 + ; CHECK-NOT: udiv nof i32 + %d = sdiv nof i64 4294967296, %a ; 0x1'0000'0000 ret i64 %d } ; For good measure, try a value larger than 2^32. ; CHECK-LABEL: @larger_constant_numer define i64 @larger_constant_numer(i64 %a) { - ; CHECK-NOT: udiv i32 - %d = sdiv i64 5000000000, %a + ; CHECK-NOT: udiv nof i32 + %d = sdiv nof i64 5000000000, %a ret i64 %d } Index: test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-not-exact.ll =================================================================== --- test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-not-exact.ll +++ test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-not-exact.ll @@ -9,8 +9,8 @@ ; ; CHECK-LABEL: @test define void @test(i64 %a, i64 %b, i64* %retptr) { - ; CHECK: udiv i32 - %d = sdiv i64 %a, %b + ; CHECK: udiv nof i32 + %d = sdiv nof i64 %a, %b store i64 %d, i64* %retptr ret void } Index: test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-special-cases.ll =================================================================== --- test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-special-cases.ll +++ test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div-special-cases.ll @@ -31,17 +31,17 @@ ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP8:%.*]] ; CHECK: [[TMP4:%.*]] = trunc i64 [[B_1]] to i32 ; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[A]] to i32 -; CHECK-NEXT: [[TMP6:%.*]] = udiv i32 [[TMP5]], [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = udiv nof i32 [[TMP5]], [[TMP4]] ; CHECK-NEXT: [[TMP7:%.*]] = zext i32 [[TMP6]] to i64 ; CHECK-NEXT: br label [[TMP10:%.*]] -; CHECK: [[TMP9:%.*]] = sdiv i64 [[A]], [[B_1]] +; CHECK: [[TMP9:%.*]] = sdiv nof i64 [[A]], [[B_1]] ; CHECK-NEXT: br label [[TMP10]] ; CHECK: [[TMP11:%.*]] = phi i64 [ [[TMP7]], [[TMP3]] ], [ [[TMP9]], [[TMP8]] ] ; CHECK-NEXT: store i64 [[TMP11]], i64* [[RETPTR:%.*]] ; CHECK-NEXT: ret void ; %b.1 = zext i32 %b to i64 - %res = sdiv i64 %a, %b.1 + %res = sdiv nof i64 %a, %b.1 store i64 %res, i64* %retptr ret void } @@ -54,14 +54,14 @@ ; CHECK-NEXT: [[B_1:%.*]] = zext i32 [[B:%.*]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A_1]] to i32 ; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[B_1]] to i32 -; CHECK-NEXT: [[TMP3:%.*]] = udiv i32 [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[TMP3:%.*]] = udiv nof i32 [[TMP1]], [[TMP2]] ; CHECK-NEXT: [[TMP4:%.*]] = zext i32 [[TMP3]] to i64 ; CHECK-NEXT: store i64 [[TMP4]], i64* [[RETPTR:%.*]] ; CHECK-NEXT: ret void ; %a.1 = and i64 %a, 4294967295 %b.1 = zext i32 %b to i64 - %res = udiv i64 %a.1, %b.1 + %res = udiv nof i64 %a.1, %b.1 store i64 %res, i64* %retptr ret void } @@ -75,7 +75,7 @@ ; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP9:%.*]] ; CHECK: [[TMP3:%.*]] = trunc i64 [[B]] to i32 ; CHECK-NEXT: [[TMP4:%.*]] = trunc i64 [[A_1]] to i32 -; CHECK-NEXT: [[TMP5:%.*]] = udiv i32 [[TMP4]], [[TMP3]] +; CHECK-NEXT: [[TMP5:%.*]] = udiv nof i32 [[TMP4]], [[TMP3]] ; CHECK-NEXT: [[TMP6:%.*]] = urem i32 [[TMP4]], [[TMP3]] ; CHECK-NEXT: [[TMP7:%.*]] = zext i32 [[TMP5]] to i64 ; CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP6]] to i64 @@ -87,7 +87,7 @@ ; CHECK-NEXT: ret void ; %a.1 = zext i32 %a to i64 - %div = udiv i64 %a.1, %b + %div = udiv nof i64 %a.1, %b %rem = urem i64 %a.1, %b %res = add i64 %div, %rem store i64 %res, i64* %retptr @@ -99,12 +99,12 @@ define void @Test_dont_bypass_xor(i64 %a, i64 %b, i64 %l, i64* %retptr) { ; CHECK-LABEL: @Test_dont_bypass_xor( ; CHECK-NEXT: [[C:%.*]] = xor i64 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[RES:%.*]] = udiv i64 [[C]], [[L:%.*]] +; CHECK-NEXT: [[RES:%.*]] = udiv nof i64 [[C]], [[L:%.*]] ; CHECK-NEXT: store i64 [[RES]], i64* [[RETPTR:%.*]] ; CHECK-NEXT: ret void ; %c = xor i64 %a, %b - %res = udiv i64 %c, %l + %res = udiv nof i64 %c, %l store i64 %res, i64* %retptr ret void } @@ -119,7 +119,7 @@ ; CHECK-NEXT: br label [[MERGE]] ; CHECK: merge: ; CHECK-NEXT: [[E:%.*]] = phi i64 [ undef, [[ENTRY:%.*]] ], [ [[C]], [[XORPATH]] ] -; CHECK-NEXT: [[RES:%.*]] = sdiv i64 [[E]], [[L:%.*]] +; CHECK-NEXT: [[RES:%.*]] = sdiv nof i64 [[E]], [[L:%.*]] ; CHECK-NEXT: store i64 [[RES]], i64* [[RETPTR:%.*]] ; CHECK-NEXT: ret void ; @@ -133,7 +133,7 @@ merge: %e = phi i64 [ undef, %entry ], [ %c, %xorpath ] - %res = sdiv i64 %e, %l + %res = sdiv nof i64 %e, %l store i64 %res, i64* %retptr ret void } @@ -167,10 +167,10 @@ ; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP8:%.*]] ; CHECK: [[TMP4:%.*]] = trunc i64 [[B]] to i32 ; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[LHS]] to i32 -; CHECK-NEXT: [[TMP6:%.*]] = udiv i32 [[TMP5]], [[TMP4]] +; CHECK-NEXT: [[TMP6:%.*]] = udiv nof i32 [[TMP5]], [[TMP4]] ; CHECK-NEXT: [[TMP7:%.*]] = zext i32 [[TMP6]] to i64 ; CHECK-NEXT: br label [[TMP10:%.*]] -; CHECK: [[TMP9:%.*]] = sdiv i64 [[LHS]], [[B]] +; CHECK: [[TMP9:%.*]] = sdiv nof i64 [[LHS]], [[B]] ; CHECK-NEXT: br label [[TMP10]] ; CHECK: [[TMP11:%.*]] = phi i64 [ [[TMP7]], [[TMP3]] ], [ [[TMP9]], [[TMP8]] ] ; CHECK-NEXT: store i64 [[TMP11]], i64* [[RETPTR:%.*]] @@ -186,7 +186,7 @@ merge: %lhs = phi i64 [ 42, %branch ], [ %a.mul, %entry ] - %res = sdiv i64 %lhs, %b + %res = sdiv nof i64 %lhs, %b store i64 %res, i64* %retptr ret void } Index: test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div.ll =================================================================== --- test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div.ll +++ test/Transforms/CodeGenPrepare/NVPTX/bypass-slow-div.ll @@ -6,11 +6,11 @@ ; We only use the div instruction -- the rem should be DCE'ed. ; CHECK-LABEL: @div_only define void @div_only(i64 %a, i64 %b, i64* %retptr) { - ; CHECK: udiv i32 + ; CHECK: udiv nof i32 ; CHECK-NOT: urem - ; CHECK: sdiv i64 + ; CHECK: sdiv nof i64 ; CHECK-NOT: rem - %d = sdiv i64 %a, %b + %d = sdiv nof i64 %a, %b store i64 %d, i64* %retptr ret void } @@ -32,12 +32,12 @@ define i64 @udiv_by_constant(i32 %a) { ; CHECK-NEXT: [[A_ZEXT:%.*]] = zext i32 [[A:%.*]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i64 [[A_ZEXT]] to i32 -; CHECK-NEXT: [[TMP2:%.*]] = udiv i32 [[TMP1]], 50 +; CHECK-NEXT: [[TMP2:%.*]] = udiv nof i32 [[TMP1]], 50 ; CHECK-NEXT: [[TMP3:%.*]] = zext i32 [[TMP2]] to i64 ; CHECK-NEXT: ret i64 [[TMP3]] %a.zext = zext i32 %a to i64 - %wide.div = udiv i64 %a.zext, 50 + %wide.div = udiv nof i64 %a.zext, 50 ret i64 %wide.div } @@ -60,10 +60,10 @@ ; ; CHECK-LABEL: @udiv_by_constant_negative_0( define i64 @udiv_by_constant_negative_0(i64 %a) { -; CHECK-NEXT: [[WIDE_DIV:%.*]] = udiv i64 [[A:%.*]], 50 +; CHECK-NEXT: [[WIDE_DIV:%.*]] = udiv nof i64 [[A:%.*]], 50 ; CHECK-NEXT: ret i64 [[WIDE_DIV]] - %wide.div = udiv i64 %a, 50 + %wide.div = udiv nof i64 %a, 50 ret i64 %wide.div } @@ -73,11 +73,11 @@ ; CHECK-LABEL: @udiv_by_constant_negative_1( define i64 @udiv_by_constant_negative_1(i32 %a) { ; CHECK-NEXT: [[A_ZEXT:%.*]] = zext i32 [[A:%.*]] to i64 -; CHECK-NEXT: [[WIDE_DIV:%.*]] = udiv i64 [[A_ZEXT]], 8589934592 +; CHECK-NEXT: [[WIDE_DIV:%.*]] = udiv nof i64 [[A_ZEXT]], 8589934592 ; CHECK-NEXT: ret i64 [[WIDE_DIV]] %a.zext = zext i32 %a to i64 - %wide.div = udiv i64 %a.zext, 8589934592 ;; == 1 << 33 + %wide.div = udiv nof i64 %a.zext, 8589934592 ;; == 1 << 33 ret i64 %wide.div } Index: test/Transforms/CodeGenPrepare/X86/select.ll =================================================================== --- test/Transforms/CodeGenPrepare/X86/select.ll +++ test/Transforms/CodeGenPrepare/X86/select.ll @@ -161,14 +161,14 @@ define i32 @sdiv_no_sink(i32 %a, i32 %b) { ; CHECK-LABEL: @sdiv_no_sink( -; CHECK-NEXT: [[DIV1:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[DIV2:%.*]] = sdiv i32 [[B]], [[A]] +; CHECK-NEXT: [[DIV1:%.*]] = sdiv nof i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[DIV2:%.*]] = sdiv nof i32 [[B]], [[A]] ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 5 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[DIV1]], i32 [[DIV2]] ; CHECK-NEXT: ret i32 [[SEL]] ; - %div1 = sdiv i32 %a, %b - %div2 = sdiv i32 %b, %a + %div1 = sdiv nof i32 %a, %b + %div2 = sdiv nof i32 %b, %a %cmp = icmp sgt i32 %a, 5 %sel = select i1 %cmp, i32 %div1, i32 %div2 ret i32 %sel Index: test/Transforms/ConstantHoisting/ARM/bad-cases.ll =================================================================== --- test/Transforms/ConstantHoisting/ARM/bad-cases.ll +++ test/Transforms/ConstantHoisting/ARM/bad-cases.ll @@ -50,7 +50,7 @@ ; them to a mul in the backend is larget than constant materialization savings. define void @signed_const_division(i32 %in1, i32 %in2, i32* %addr) { ; CHECK-LABEL: @signed_const_division -; CHECK: %res1 = sdiv i32 %l1, 1000000000 +; CHECK: %res1 = sdiv nof i32 %l1, 1000000000 ; CHECK: %res2 = srem i32 %l2, 1000000000 entry: br label %loop @@ -58,7 +58,7 @@ loop: %l1 = phi i32 [%res1, %loop], [%in1, %entry] %l2 = phi i32 [%res2, %loop], [%in2, %entry] - %res1 = sdiv i32 %l1, 1000000000 + %res1 = sdiv nof i32 %l1, 1000000000 store volatile i32 %res1, i32* %addr %res2 = srem i32 %l2, 1000000000 store volatile i32 %res2, i32* %addr @@ -71,7 +71,7 @@ define void @unsigned_const_division(i32 %in1, i32 %in2, i32* %addr) { ; CHECK-LABEL: @unsigned_const_division -; CHECK: %res1 = udiv i32 %l1, 1000000000 +; CHECK: %res1 = udiv nof i32 %l1, 1000000000 ; CHECK: %res2 = urem i32 %l2, 1000000000 entry: @@ -80,7 +80,7 @@ loop: %l1 = phi i32 [%res1, %loop], [%in1, %entry] %l2 = phi i32 [%res2, %loop], [%in2, %entry] - %res1 = udiv i32 %l1, 1000000000 + %res1 = udiv nof i32 %l1, 1000000000 store volatile i32 %res1, i32* %addr %res2 = urem i32 %l2, 1000000000 store volatile i32 %res2, i32* %addr Index: test/Transforms/CorrelatedValuePropagation/sdiv.ll =================================================================== --- test/Transforms/CorrelatedValuePropagation/sdiv.ll +++ test/Transforms/CorrelatedValuePropagation/sdiv.ll @@ -11,8 +11,8 @@ br i1 %cmp, label %for.body, label %for.end for.body: ; preds = %for.cond -; CHECK: %div1 = udiv i32 %j.0, 2 - %div = sdiv i32 %j.0, 2 +; CHECK: %div1 = udiv nof i32 %j.0, 2 + %div = sdiv nof i32 %j.0, 2 br label %for.cond for.end: ; preds = %for.cond @@ -30,8 +30,8 @@ br i1 %cmp, label %for.body, label %for.end for.body: ; preds = %for.cond -; CHECK: %div = sdiv i32 %j.0, 2 - %div = sdiv i32 %j.0, 2 +; CHECK: %div = sdiv nof i32 %j.0, 2 + %div = sdiv nof i32 %j.0, 2 br label %for.cond for.end: ; preds = %for.cond @@ -45,8 +45,8 @@ br i1 %cmp, label %bb, label %exit bb: -; CHECK: %div1 = udiv i32 %n, 2 - %div = sdiv i32 %n, 2 +; CHECK: %div1 = udiv nof i32 %n, 2 + %div = sdiv nof i32 %n, 2 br label %exit exit: @@ -64,11 +64,11 @@ br i1 %cmp, label %loop, label %exit loop: -; CHECK: udiv i32 %a, 6 +; CHECK: udiv nof i32 %a, 6 %a = phi i32 [ %n, %entry ], [ %div, %loop ] %cond = icmp sgt i32 %a, 4 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ] - %div = sdiv i32 %a, 6 + %div = sdiv nof i32 %a, 6 br i1 %cond, label %loop, label %exit exit: @@ -84,11 +84,11 @@ br i1 %cmp, label %loop, label %exit loop: -; CHECK: udiv i32 %a, 6 +; CHECK: udiv nof i32 %a, 6 %a = phi i32 [ %n, %entry ], [ %div, %loop ] %cond = icmp sgt i32 %a, 4 call void @llvm.assume(i1 %cond) - %div = sdiv i32 %a, 6 + %div = sdiv nof i32 %a, 6 %loopcond = icmp sgt i32 %div, 8 br i1 %loopcond, label %loop, label %exit Index: test/Transforms/DivRemPairs/PowerPC/div-rem-pairs.ll =================================================================== --- test/Transforms/DivRemPairs/PowerPC/div-rem-pairs.ll +++ test/Transforms/DivRemPairs/PowerPC/div-rem-pairs.ll @@ -4,39 +4,39 @@ define void @decompose_illegal_srem_same_block(i32 %a, i32 %b) { ; CHECK-LABEL: @decompose_illegal_srem_same_block( -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %b ; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], %b ; CHECK-NEXT: [[TMP2:%.*]] = sub i32 %a, [[TMP1]] ; CHECK-NEXT: call void @foo(i32 [[TMP2]], i32 [[DIV]]) ; CHECK-NEXT: ret void ; %rem = srem i32 %a, %b - %div = sdiv i32 %a, %b + %div = sdiv nof i32 %a, %b call void @foo(i32 %rem, i32 %div) ret void } define void @decompose_illegal_urem_same_block(i32 %a, i32 %b) { ; CHECK-LABEL: @decompose_illegal_urem_same_block( -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 %a, %b ; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], %b ; CHECK-NEXT: [[TMP2:%.*]] = sub i32 %a, [[TMP1]] ; CHECK-NEXT: call void @foo(i32 [[TMP2]], i32 [[DIV]]) ; CHECK-NEXT: ret void ; - %div = udiv i32 %a, %b + %div = udiv nof i32 %a, %b %rem = urem i32 %a, %b call void @foo(i32 %rem, i32 %div) ret void } -; Hoist and optionally decompose the sdiv because it's safe and free. +; Hoist and optionally decompose the sdiv nof because it's safe and free. ; PR31028 - https://bugs.llvm.org/show_bug.cgi?id=31028 define i32 @hoist_sdiv(i32 %a, i32 %b) { ; CHECK-LABEL: @hoist_sdiv( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %b ; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[DIV]], %b ; CHECK-NEXT: [[TMP1:%.*]] = sub i32 %a, [[TMP0]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 42 @@ -53,7 +53,7 @@ br i1 %cmp, label %if, label %end if: - %div = sdiv i32 %a, %b + %div = sdiv nof i32 %a, %b br label %end end: @@ -61,12 +61,12 @@ ret i32 %ret } -; Hoist and optionally decompose the udiv because it's safe and free. +; Hoist and optionally decompose the udiv nof because it's safe and free. define i64 @hoist_udiv(i64 %a, i64 %b) { ; CHECK-LABEL: @hoist_udiv( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = udiv i64 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i64 %a, %b ; CHECK-NEXT: [[TMP0:%.*]] = mul i64 [[DIV]], %b ; CHECK-NEXT: [[TMP1:%.*]] = sub i64 %a, [[TMP0]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], 42 @@ -83,7 +83,7 @@ br i1 %cmp, label %if, label %end if: - %div = udiv i64 %a, %b + %div = udiv nof i64 %a, %b br label %end end: @@ -96,7 +96,7 @@ define i16 @hoist_srem(i16 %a, i16 %b) { ; CHECK-LABEL: @hoist_srem( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i16 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i16 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[DIV]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: @@ -108,7 +108,7 @@ ; CHECK-NEXT: ret i16 [[RET]] ; entry: - %div = sdiv i16 %a, %b + %div = sdiv nof i16 %a, %b %cmp = icmp eq i16 %div, 42 br i1 %cmp, label %if, label %end @@ -126,7 +126,7 @@ define i8 @hoist_urem(i8 %a, i8 %b) { ; CHECK-LABEL: @hoist_urem( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i8 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[DIV]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: @@ -138,7 +138,7 @@ ; CHECK-NEXT: ret i8 [[RET]] ; entry: - %div = udiv i8 %a, %b + %div = udiv nof i8 %a, %b %cmp = icmp eq i8 %div, 42 br i1 %cmp, label %if, label %end @@ -160,7 +160,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 %a, %b ; CHECK-NEXT: br label %end ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[DIV]], %if ], [ 3, %entry ] @@ -172,7 +172,7 @@ br i1 %cmp, label %if, label %end if: - %div = udiv i32 %a, %b + %div = udiv nof i32 %a, %b br label %end end: @@ -218,7 +218,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %c +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %c ; CHECK-NEXT: br label %end ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[DIV]], %if ], [ 3, %entry ] @@ -230,7 +230,7 @@ br i1 %cmp, label %if, label %end if: - %div = sdiv i32 %a, %c + %div = sdiv nof i32 %a, %c br label %end end: @@ -243,7 +243,7 @@ define i128 @dont_hoist_urem(i128 %a, i128 %b) { ; CHECK-LABEL: @dont_hoist_urem( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = udiv i128 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i128 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i128 [[DIV]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: @@ -255,7 +255,7 @@ ; CHECK-NEXT: ret i128 [[RET]] ; entry: - %div = udiv i128 %a, %b + %div = udiv nof i128 %a, %b %cmp = icmp eq i128 %div, 42 br i1 %cmp, label %if, label %end @@ -276,7 +276,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 %cmp, label %if, label %else ; CHECK: if: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %b ; CHECK-NEXT: br label %end ; CHECK: else: ; CHECK-NEXT: [[REM:%.*]] = srem i32 %a, %b @@ -289,7 +289,7 @@ br i1 %cmp, label %if, label %else if: - %div = sdiv i32 %a, %b + %div = sdiv nof i32 %a, %b br label %end else: Index: test/Transforms/DivRemPairs/X86/div-rem-pairs.ll =================================================================== --- test/Transforms/DivRemPairs/X86/div-rem-pairs.ll +++ test/Transforms/DivRemPairs/X86/div-rem-pairs.ll @@ -5,37 +5,37 @@ define void @decompose_illegal_srem_same_block(i32 %a, i32 %b) { ; CHECK-LABEL: @decompose_illegal_srem_same_block( ; CHECK-NEXT: [[REM:%.*]] = srem i32 %a, %b -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %b ; CHECK-NEXT: call void @foo(i32 [[REM]], i32 [[DIV]]) ; CHECK-NEXT: ret void ; %rem = srem i32 %a, %b - %div = sdiv i32 %a, %b + %div = sdiv nof i32 %a, %b call void @foo(i32 %rem, i32 %div) ret void } define void @decompose_illegal_urem_same_block(i32 %a, i32 %b) { ; CHECK-LABEL: @decompose_illegal_urem_same_block( -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 %a, %b ; CHECK-NEXT: [[REM:%.*]] = urem i32 %a, %b ; CHECK-NEXT: call void @foo(i32 [[REM]], i32 [[DIV]]) ; CHECK-NEXT: ret void ; - %div = udiv i32 %a, %b + %div = udiv nof i32 %a, %b %rem = urem i32 %a, %b call void @foo(i32 %rem, i32 %div) ret void } -; Hoist and optionally decompose the sdiv because it's safe and free. +; Hoist and optionally decompose the sdiv nof because it's safe and free. ; PR31028 - https://bugs.llvm.org/show_bug.cgi?id=31028 define i32 @hoist_sdiv(i32 %a, i32 %b) { ; CHECK-LABEL: @hoist_sdiv( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[REM:%.*]] = srem i32 %a, %b -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: @@ -50,7 +50,7 @@ br i1 %cmp, label %if, label %end if: - %div = sdiv i32 %a, %b + %div = sdiv nof i32 %a, %b br label %end end: @@ -58,13 +58,13 @@ ret i32 %ret } -; Hoist and optionally decompose the udiv because it's safe and free. +; Hoist and optionally decompose the udiv nof because it's safe and free. define i64 @hoist_udiv(i64 %a, i64 %b) { ; CHECK-LABEL: @hoist_udiv( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[REM:%.*]] = urem i64 %a, %b -; CHECK-NEXT: [[DIV:%.*]] = udiv i64 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i64 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[REM]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: @@ -79,7 +79,7 @@ br i1 %cmp, label %if, label %end if: - %div = udiv i64 %a, %b + %div = udiv nof i64 %a, %b br label %end end: @@ -92,7 +92,7 @@ define i16 @hoist_srem(i16 %a, i16 %b) { ; CHECK-LABEL: @hoist_srem( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i16 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i16 %a, %b ; CHECK-NEXT: [[REM:%.*]] = srem i16 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[DIV]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end @@ -103,7 +103,7 @@ ; CHECK-NEXT: ret i16 [[RET]] ; entry: - %div = sdiv i16 %a, %b + %div = sdiv nof i16 %a, %b %cmp = icmp eq i16 %div, 42 br i1 %cmp, label %if, label %end @@ -121,7 +121,7 @@ define i8 @hoist_urem(i8 %a, i8 %b) { ; CHECK-LABEL: @hoist_urem( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i8 %a, %b ; CHECK-NEXT: [[REM:%.*]] = urem i8 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[DIV]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end @@ -132,7 +132,7 @@ ; CHECK-NEXT: ret i8 [[RET]] ; entry: - %div = udiv i8 %a, %b + %div = udiv nof i8 %a, %b %cmp = icmp eq i8 %div, 42 br i1 %cmp, label %if, label %end @@ -154,7 +154,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 %a, %b ; CHECK-NEXT: br label %end ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[DIV]], %if ], [ 3, %entry ] @@ -166,7 +166,7 @@ br i1 %cmp, label %if, label %end if: - %div = udiv i32 %a, %b + %div = udiv nof i32 %a, %b br label %end end: @@ -212,7 +212,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %c +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %c ; CHECK-NEXT: br label %end ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[DIV]], %if ], [ 3, %entry ] @@ -224,7 +224,7 @@ br i1 %cmp, label %if, label %end if: - %div = sdiv i32 %a, %c + %div = sdiv nof i32 %a, %c br label %end end: @@ -237,7 +237,7 @@ define i128 @dont_hoist_urem(i128 %a, i128 %b) { ; CHECK-LABEL: @dont_hoist_urem( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = udiv i128 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i128 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i128 [[DIV]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: @@ -249,7 +249,7 @@ ; CHECK-NEXT: ret i128 [[RET]] ; entry: - %div = udiv i128 %a, %b + %div = udiv nof i128 %a, %b %cmp = icmp eq i128 %div, 42 br i1 %cmp, label %if, label %end @@ -270,7 +270,7 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 %cmp, label %if, label %else ; CHECK: if: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %b ; CHECK-NEXT: br label %end ; CHECK: else: ; CHECK-NEXT: [[REM:%.*]] = srem i32 %a, %b @@ -283,7 +283,7 @@ br i1 %cmp, label %if, label %else if: - %div = sdiv i32 %a, %b + %div = sdiv nof i32 %a, %b br label %end else: Index: test/Transforms/GVN/calls-readonly.ll =================================================================== --- test/Transforms/GVN/calls-readonly.ll +++ test/Transforms/GVN/calls-readonly.ll @@ -11,7 +11,7 @@ br i1 %1, label %bb, label %bb1 bb: ; preds = %entry - %2 = sdiv i32 %x, %y ; [#uses=1] + %2 = sdiv nof i32 %x, %y ; [#uses=1] br label %bb1 bb1: ; preds = %bb, %entry @@ -30,7 +30,7 @@ ; CHECK-NEXT: %1 = icmp eq i32 %0, 0 ; CHECK-NEXT: br i1 %1, label %bb, label %bb1 ; CHECK: bb: -; CHECK-NEXT: %2 = sdiv i32 %x, %y +; CHECK-NEXT: %2 = sdiv nof i32 %x, %y ; CHECK-NEXT: br label %bb1 ; CHECK: bb1: ; CHECK-NEXT: %x_addr.0 = phi i32 [ %2, %bb ], [ %x, %entry ] Index: test/Transforms/IRCE/bad_expander.ll =================================================================== --- test/Transforms/IRCE/bad_expander.ll +++ test/Transforms/IRCE/bad_expander.ll @@ -69,7 +69,7 @@ br i1 %maybe_exit, label %range_check, label %exit range_check: - %div_result = udiv i64 %num, %denom + %div_result = udiv nof i64 %num, %denom %rc = icmp slt i64 %iv.next, %div_result br i1 %rc, label %guarded, label %exit @@ -87,7 +87,7 @@ ; CHECK-LABEL: test_03 ; CHECK: entry: ; CHECK-NEXT: %num = load i64, i64* %p1, align 4 -; CHECK-NEXT: [[DIV:%[^ ]+]] = udiv i64 %num, 13 +; CHECK-NEXT: [[DIV:%[^ ]+]] = udiv nof i64 %num, 13 ; CHECK-NEXT: [[DIV_MINUS_1:%[^ ]+]] = add i64 [[DIV]], -1 ; CHECK-NEXT: [[COMP1:%[^ ]+]] = icmp sgt i64 [[DIV_MINUS_1]], 0 ; CHECK-NEXT: %exit.mainloop.at = select i1 [[COMP1]], i64 [[DIV_MINUS_1]], i64 0 @@ -121,7 +121,7 @@ br i1 %maybe_exit, label %range_check, label %exit range_check: - %div_result = udiv i64 %num, 13 + %div_result = udiv nof i64 %num, 13 %rc = icmp slt i64 %iv.next, %div_result br i1 %rc, label %guarded, label %exit Index: test/Transforms/IndVarSimplify/iv-widen-elim-ext.ll =================================================================== --- test/Transforms/IndVarSimplify/iv-widen-elim-ext.ll +++ test/Transforms/IndVarSimplify/iv-widen-elim-ext.ll @@ -22,7 +22,7 @@ ; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARRAYIDX2]], align 4 ; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[TMP0]], [[TMP2]] ; CHECK-NEXT: [[TRUNC0:%.*]] = trunc i64 [[TMP1]] to i32 -; CHECK-NEXT: [[DIV0:%.*]] = udiv i32 5, [[TRUNC0]] +; CHECK-NEXT: [[DIV0:%.*]] = udiv nof i32 5, [[TRUNC0]] ; CHECK-NEXT: [[ADD4:%.*]] = add nsw i32 [[ADD3]], [[DIV0]] ; CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds i32, i32* %A, i64 [[INDVARS_IV]] ; CHECK-NEXT: store i32 [[ADD4]], i32* [[ARRAYIDX5]], align 4 @@ -54,7 +54,7 @@ %arrayidx2 = getelementptr inbounds i32, i32* %C, i64 %idxprom1 %1 = load i32, i32* %arrayidx2, align 4 %add3 = add nsw i32 %0, %1 - %div0 = udiv i32 5, %add + %div0 = udiv nof i32 5, %add %add4 = add nsw i32 %add3, %div0 %idxprom4 = zext i32 %i.02 to i64 %arrayidx5 = getelementptr inbounds i32, i32* %A, i64 %idxprom4 Index: test/Transforms/InstCombine/2008-02-16-SDivOverflow2.ll =================================================================== --- test/Transforms/InstCombine/2008-02-16-SDivOverflow2.ll +++ test/Transforms/InstCombine/2008-02-16-SDivOverflow2.ll @@ -1,9 +1,9 @@ -; RUN: opt < %s -instcombine -S | grep "sdiv i8 \%a, 9" +; RUN: opt < %s -instcombine -S | grep "sdiv nof i8 \%a, 9" ; PR2048 define i8 @i(i8 %a) { - %tmp1 = sdiv i8 %a, -3 - %tmp2 = sdiv i8 %tmp1, -3 + %tmp1 = sdiv exact nof i8 %a, -3 + %tmp2 = sdiv exact nof i8 %tmp1, -3 ret i8 %tmp2 } Index: test/Transforms/InstCombine/2012-08-28-udiv_ashl.ll =================================================================== --- test/Transforms/InstCombine/2012-08-28-udiv_ashl.ll +++ test/Transforms/InstCombine/2012-08-28-udiv_ashl.ll @@ -6,12 +6,12 @@ target triple = "x86_64-apple-macosx10.8.0" ; CHECK-LABEL: @udiv400( -; CHECK: udiv i32 %x, 400 +; CHECK: udiv nof i32 %x, 400 ; CHECK: ret define i32 @udiv400(i32 %x) { entry: %div = lshr i32 %x, 2 - %div1 = udiv i32 %div, 100 + %div1 = udiv nof i32 %div, 100 ret i32 %div1 } @@ -23,12 +23,12 @@ define i32 @udiv400_no(i32 %x) { entry: %div = ashr i32 %x, 2 - %div1 = udiv i32 %div, 100 + %div1 = udiv nof i32 %div, 100 ret i32 %div1 } ; CHECK-LABEL: @sdiv400_yes( -; CHECK: udiv i32 %x, 400 +; CHECK: udiv nof i32 %x, 400 ; CHECK: ret define i32 @sdiv400_yes(i32 %x) { entry: @@ -36,22 +36,22 @@ ; The sign bits of both operands are zero (i.e. we can prove they are ; unsigned inputs), turn this into a udiv. ; Next, optimize this just like sdiv. - %div1 = sdiv i32 %div, 100 + %div1 = sdiv nof i32 %div, 100 ret i32 %div1 } ; CHECK-LABEL: @udiv_i80( -; CHECK: udiv i80 %x, 400 +; CHECK: udiv nof i80 %x, 400 ; CHECK: ret define i80 @udiv_i80(i80 %x) { %div = lshr i80 %x, 2 - %div1 = udiv i80 %div, 100 + %div1 = udiv nof i80 %div, 100 ret i80 %div1 } define i32 @no_crash_notconst_udiv(i32 %x, i32 %notconst) { %div = lshr i32 %x, %notconst - %div1 = udiv i32 %div, 100 + %div1 = udiv nof i32 %div, 100 ret i32 %div1 } Index: test/Transforms/InstCombine/apint-add.ll =================================================================== --- test/Transforms/InstCombine/apint-add.ll +++ test/Transforms/InstCombine/apint-add.ll @@ -83,17 +83,17 @@ ; CHECK-NEXT: [[XOR:%.*]] = xor i4 %x, -8 ; CHECK-NEXT: [[ZEXT:%.*]] = zext i4 [[XOR]] to i7 ; CHECK-NEXT: [[ADD:%.*]] = sext i4 %x to i7 -; CHECK-NEXT: [[MUL:%.*]] = sdiv i7 [[ZEXT]], [[ADD]] +; CHECK-NEXT: [[MUL:%.*]] = sdiv nof i7 [[ZEXT]], [[ADD]] ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i7 [[MUL]] to i4 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i4 [[TRUNC]], [[XOR]] +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i4 [[TRUNC]], [[XOR]] ; CHECK-NEXT: ret i4 [[DIV]] ; %xor = xor i4 %x, -8 %zext = zext i4 %xor to i7 %add = add nsw i7 %zext, -8 - %mul = sdiv i7 %zext, %add + %mul = sdiv nof i7 %zext, %add %trunc = trunc i7 %mul to i4 - %div = sdiv i4 %trunc, %xor + %div = sdiv nof i4 %trunc, %xor ret i4 %div } Index: test/Transforms/InstCombine/apint-shift.ll =================================================================== --- test/Transforms/InstCombine/apint-shift.ll +++ test/Transforms/InstCombine/apint-shift.ll @@ -251,11 +251,11 @@ define <2 x i7> @shl_lshr_splat_vec(<2 x i7> %X) { ; CHECK-LABEL: @shl_lshr_splat_vec( -; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i7> %X, +; CHECK-NEXT: [[DIV:%.*]] = udiv nof <2 x i7> %X, ; CHECK-NEXT: [[SH1:%.*]] = shl nuw nsw <2 x i7> [[DIV]], ; CHECK-NEXT: ret <2 x i7> [[SH1]] ; - %div = udiv <2 x i7> %X, + %div = udiv nof <2 x i7> %X, %sh1 = shl nuw <2 x i7> %div, %sh2 = lshr exact <2 x i7> %sh1, ret <2 x i7> %sh2 Index: test/Transforms/InstCombine/apint-sub.ll =================================================================== --- test/Transforms/InstCombine/apint-sub.ll +++ test/Transforms/InstCombine/apint-sub.ll @@ -151,10 +151,10 @@ define i51 @test16(i51 %A) { ; CHECK-LABEL: @test16( -; CHECK-NEXT: [[Y:%.*]] = sdiv i51 %A, -1123 +; CHECK-NEXT: [[Y:%.*]] = sdiv nof i51 %A, -1123 ; CHECK-NEXT: ret i51 [[Y]] ; - %X = sdiv i51 %A, 1123 + %X = sdiv nof i51 %A, 1123 %Y = sub i51 0, %X ret i51 %Y } @@ -164,11 +164,11 @@ define i25 @test17(i25 %Aok) { ; CHECK-LABEL: @test17( ; CHECK-NEXT: [[B:%.*]] = sub i25 0, %Aok -; CHECK-NEXT: [[C:%.*]] = sdiv i25 [[B]], 1234 +; CHECK-NEXT: [[C:%.*]] = sdiv nof i25 [[B]], 1234 ; CHECK-NEXT: ret i25 [[C]] ; %B = sub i25 0, %Aok - %C = sdiv i25 %B, 1234 + %C = sdiv nof i25 %B, 1234 ret i25 %C } Index: test/Transforms/InstCombine/demorgan.ll =================================================================== --- test/Transforms/InstCombine/demorgan.ll +++ test/Transforms/InstCombine/demorgan.ll @@ -250,14 +250,14 @@ ; CHECK-NEXT: [[USE2A:%.*]] = mul i8 [[NOTA]], 23 ; CHECK-NEXT: [[B_NOT:%.*]] = xor i8 %B, -1 ; CHECK-NEXT: [[NOTC:%.*]] = and i8 [[B_NOT]], %A -; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2A]] +; CHECK-NEXT: [[R:%.*]] = sdiv nof i8 [[NOTC]], [[USE2A]] ; CHECK-NEXT: ret i8 [[R]] ; %nota = xor i8 %A, -1 %use2a = mul i8 %nota, 23 %c = or i8 %nota, %B %notc = xor i8 %c, -1 - %r = sdiv i8 %notc, %use2a + %r = sdiv nof i8 %notc, %use2a ret i8 %r } @@ -268,14 +268,14 @@ ; CHECK-NEXT: [[USE2B:%.*]] = mul i8 %B, 23 ; CHECK-NEXT: [[B_NOT:%.*]] = xor i8 %B, -1 ; CHECK-NEXT: [[NOTC:%.*]] = and i8 [[B_NOT]], %A -; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2B]] +; CHECK-NEXT: [[R:%.*]] = sdiv nof i8 [[NOTC]], [[USE2B]] ; CHECK-NEXT: ret i8 [[R]] ; %use2b = mul i8 %B, 23 %nota = xor i8 %A, -1 %c = or i8 %nota, %B %notc = xor i8 %c, -1 - %r = sdiv i8 %notc, %use2b + %r = sdiv nof i8 %notc, %use2b ret i8 %r } @@ -287,14 +287,14 @@ ; CHECK-NEXT: [[C:%.*]] = or i8 [[NOTA]], %B ; CHECK-NEXT: [[USE2C:%.*]] = mul i8 [[C]], 23 ; CHECK-NEXT: [[NOTC:%.*]] = xor i8 [[C]], -1 -; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[NOTC]], [[USE2C]] +; CHECK-NEXT: [[R:%.*]] = sdiv nof i8 [[NOTC]], [[USE2C]] ; CHECK-NEXT: ret i8 [[R]] ; %nota = xor i8 %A, -1 %c = or i8 %nota, %B %use2c = mul i8 %c, 23 %notc = xor i8 %c, -1 - %r = sdiv i8 %notc, %use2c + %r = sdiv nof i8 %notc, %use2c ret i8 %r } @@ -307,8 +307,8 @@ ; CHECK-NEXT: [[USE2A:%.*]] = mul i8 [[NOTA]], 17 ; CHECK-NEXT: [[B_NOT:%.*]] = xor i8 %B, -1 ; CHECK-NEXT: [[NOTC:%.*]] = and i8 [[B_NOT]], %A -; CHECK-NEXT: [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2B]] -; CHECK-NEXT: [[R2:%.*]] = sdiv i8 [[R1]], [[USE2A]] +; CHECK-NEXT: [[R1:%.*]] = sdiv nof i8 [[NOTC]], [[USE2B]] +; CHECK-NEXT: [[R2:%.*]] = sdiv nof i8 [[R1]], [[USE2A]] ; CHECK-NEXT: ret i8 [[R2]] ; %use2b = mul i8 %B, 23 @@ -316,8 +316,8 @@ %use2a = mul i8 %nota, 17 %c = or i8 %nota, %B %notc = xor i8 %c, -1 - %r1 = sdiv i8 %notc, %use2b - %r2 = sdiv i8 %r1, %use2a + %r1 = sdiv nof i8 %notc, %use2b + %r2 = sdiv nof i8 %r1, %use2a ret i8 %r2 } @@ -330,8 +330,8 @@ ; CHECK-NEXT: [[C:%.*]] = or i8 [[NOTA]], %B ; CHECK-NEXT: [[USE2C:%.*]] = mul i8 [[C]], 23 ; CHECK-NEXT: [[NOTC:%.*]] = xor i8 [[C]], -1 -; CHECK-NEXT: [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2C]] -; CHECK-NEXT: [[R2:%.*]] = sdiv i8 [[R1]], [[USE2A]] +; CHECK-NEXT: [[R1:%.*]] = sdiv nof i8 [[NOTC]], [[USE2C]] +; CHECK-NEXT: [[R2:%.*]] = sdiv nof i8 [[R1]], [[USE2A]] ; CHECK-NEXT: ret i8 [[R2]] ; %nota = xor i8 %A, -1 @@ -339,8 +339,8 @@ %c = or i8 %nota, %B %use2c = mul i8 %c, 23 %notc = xor i8 %c, -1 - %r1 = sdiv i8 %notc, %use2c - %r2 = sdiv i8 %r1, %use2a + %r1 = sdiv nof i8 %notc, %use2c + %r2 = sdiv nof i8 %r1, %use2a ret i8 %r2 } @@ -353,8 +353,8 @@ ; CHECK-NEXT: [[C:%.*]] = or i8 [[NOTA]], %B ; CHECK-NEXT: [[USE2C:%.*]] = mul i8 [[C]], 23 ; CHECK-NEXT: [[NOTC:%.*]] = xor i8 [[C]], -1 -; CHECK-NEXT: [[R1:%.*]] = sdiv i8 [[NOTC]], [[USE2C]] -; CHECK-NEXT: [[R2:%.*]] = sdiv i8 [[R1]], [[USE2B]] +; CHECK-NEXT: [[R1:%.*]] = sdiv nof i8 [[NOTC]], [[USE2C]] +; CHECK-NEXT: [[R2:%.*]] = sdiv nof i8 [[R1]], [[USE2B]] ; CHECK-NEXT: ret i8 [[R2]] ; %use2b = mul i8 %B, 23 @@ -362,8 +362,8 @@ %c = or i8 %nota, %B %use2c = mul i8 %c, 23 %notc = xor i8 %c, -1 - %r1 = sdiv i8 %notc, %use2c - %r2 = sdiv i8 %r1, %use2b + %r1 = sdiv nof i8 %notc, %use2c + %r2 = sdiv nof i8 %r1, %use2b ret i8 %r2 } Index: test/Transforms/InstCombine/div-shift.ll =================================================================== --- test/Transforms/InstCombine/div-shift.ll +++ test/Transforms/InstCombine/div-shift.ll @@ -12,7 +12,7 @@ entry: %conv = zext i16 %x to i32 %s = shl i32 2, %y - %d = sdiv i32 %conv, %s + %d = sdiv nof i32 %conv, %s ret i32 %d } @@ -27,7 +27,7 @@ entry: %conv = zext <2 x i16> %x to <2 x i32> %s = shl <2 x i32> , %y - %d = sdiv <2 x i32> %conv, %s + %d = sdiv nof <2 x i32> %conv, %s ret <2 x i32> %d } @@ -40,7 +40,7 @@ ; %1 = shl i32 1, %y %2 = zext i32 %1 to i64 - %3 = udiv i64 %x, %2 + %3 = udiv nof i64 %x, %2 ret i64 %3 } @@ -54,7 +54,7 @@ ; %1 = shl i32 4, %y %2 = zext i32 %1 to i64 - %3 = udiv i64 %x, %2 + %3 = udiv nof i64 %x, %2 ret i64 %3 } @@ -68,7 +68,7 @@ %1 = shl i32 1, %y %2 = icmp ult i32 %1, 32 %3 = select i1 %2, i32 32, i32 %1 - %4 = udiv i32 %x, %3 + %4 = udiv nof i32 %x, %3 ret i32 %4 } @@ -82,7 +82,7 @@ %1 = shl i32 1, %V %2 = select i1 %x, i32 32, i32 64 %3 = select i1 %y, i32 %2, i32 %1 - %4 = udiv i32 %V, %3 + %4 = udiv nof i32 %V, %3 ret i32 %4 } @@ -90,12 +90,12 @@ ; CHECK-LABEL: @t6( ; CHECK-NEXT: [[X_IS_ZERO:%.*]] = icmp eq i32 [[X:%.*]], 0 ; CHECK-NEXT: [[DIVISOR:%.*]] = select i1 [[X_IS_ZERO]], i32 1, i32 [[X]] -; CHECK-NEXT: [[Y:%.*]] = udiv i32 [[Z:%.*]], [[DIVISOR]] +; CHECK-NEXT: [[Y:%.*]] = udiv nof i32 [[Z:%.*]], [[DIVISOR]] ; CHECK-NEXT: ret i32 [[Y]] ; %x_is_zero = icmp eq i32 %x, 0 %divisor = select i1 %x_is_zero, i32 1, i32 %x - %y = udiv i32 %z, %divisor + %y = udiv nof i32 %z, %divisor ret i32 %y } @@ -106,7 +106,7 @@ ; CHECK-NEXT: ret i32 4 ; %shl = shl nsw i32 %x, 2 - %r = sdiv i32 %shl, %x + %r = sdiv nof i32 %shl, %x ret i32 %r } @@ -115,11 +115,11 @@ define i32 @t8(i32 %x) { ; CHECK-LABEL: @t8( ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 2 -; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[SHL]], [[X]] +; CHECK-NEXT: [[R:%.*]] = sdiv nof i32 [[SHL]], [[X]] ; CHECK-NEXT: ret i32 [[R]] ; %shl = shl i32 %x, 2 - %r = sdiv i32 %shl, %x + %r = sdiv nof i32 %shl, %x ret i32 %r } @@ -128,7 +128,7 @@ ; CHECK-NEXT: ret <2 x i32> ; %shl = shl nsw <2 x i32> %x, - %r = sdiv <2 x i32> %shl, %x + %r = sdiv nof <2 x i32> %shl, %x ret <2 x i32> %r } @@ -138,7 +138,7 @@ ; CHECK-NEXT: ret i32 [[R]] ; %shl = shl nsw i32 %x, %y - %r = sdiv i32 %shl, %x + %r = sdiv nof i32 %shl, %x ret i32 %r } @@ -148,7 +148,7 @@ ; CHECK-NEXT: ret <2 x i32> [[R]] ; %shl = shl nsw <2 x i32> %x, %y - %r = sdiv <2 x i32> %shl, %x + %r = sdiv nof <2 x i32> %shl, %x ret <2 x i32> %r } @@ -157,7 +157,7 @@ ; CHECK-NEXT: ret i32 4 ; %shl = shl nuw i32 %x, 2 - %r = udiv i32 %shl, %x + %r = udiv nof i32 %shl, %x ret i32 %r } @@ -166,11 +166,11 @@ define i32 @t13(i32 %x) { ; CHECK-LABEL: @t13( ; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[X:%.*]], 2 -; CHECK-NEXT: [[R:%.*]] = udiv i32 [[SHL]], [[X]] +; CHECK-NEXT: [[R:%.*]] = udiv nof i32 [[SHL]], [[X]] ; CHECK-NEXT: ret i32 [[R]] ; %shl = shl i32 %x, 2 - %r = udiv i32 %shl, %x + %r = udiv nof i32 %shl, %x ret i32 %r } @@ -179,7 +179,7 @@ ; CHECK-NEXT: ret <2 x i32> ; %shl = shl nuw <2 x i32> %x, - %r = udiv <2 x i32> %shl, %x + %r = udiv nof <2 x i32> %shl, %x ret <2 x i32> %r } @@ -189,7 +189,7 @@ ; CHECK-NEXT: ret i32 [[R]] ; %shl = shl nuw i32 %x, %y - %r = udiv i32 %shl, %x + %r = udiv nof i32 %shl, %x ret i32 %r } @@ -199,6 +199,6 @@ ; CHECK-NEXT: ret <2 x i32> [[R]] ; %shl = shl nuw <2 x i32> %x, %y - %r = udiv <2 x i32> %shl, %x + %r = udiv nof <2 x i32> %shl, %x ret <2 x i32> %r } Index: test/Transforms/InstCombine/div.ll =================================================================== --- test/Transforms/InstCombine/div.ll +++ test/Transforms/InstCombine/div.ll @@ -7,7 +7,7 @@ ; CHECK-LABEL: @test1( ; CHECK-NEXT: ret i32 %A ; - %B = sdiv i32 %A, 1 ; [#uses=1] + %B = sdiv nof i32 %A, 1 ; [#uses=1] ret i32 %B } @@ -17,7 +17,7 @@ ; CHECK-NEXT: [[B:%.*]] = lshr i32 %A, 3 ; CHECK-NEXT: ret i32 [[B]] ; - %B = udiv i32 %A, 8 ; [#uses=1] + %B = udiv nof i32 %A, 8 ; [#uses=1] ret i32 %B } @@ -26,7 +26,7 @@ ; CHECK-LABEL: @test3( ; CHECK-NEXT: ret i32 0 ; - %B = sdiv i32 0, %A ; [#uses=1] + %B = sdiv nof i32 0, %A ; [#uses=1] ret i32 %B } @@ -36,7 +36,7 @@ ; CHECK-NEXT: [[B:%.*]] = sub i32 0, %A ; CHECK-NEXT: ret i32 [[B]] ; - %B = sdiv i32 %A, -1 ; [#uses=1] + %B = sdiv nof i32 %A, -1 ; [#uses=1] ret i32 %B } @@ -44,8 +44,8 @@ ; CHECK-LABEL: @test5( ; CHECK-NEXT: ret i32 0 ; - %B = udiv i32 %A, -16 ; [#uses=1] - %C = udiv i32 %B, -4 ; [#uses=1] + %B = udiv nof i32 %A, -16 ; [#uses=1] + %C = udiv nof i32 %B, -4 ; [#uses=1] ret i32 %C } @@ -54,7 +54,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 %A, 123 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %B = udiv i32 %A, 123 ; [#uses=1] + %B = udiv nof i32 %A, 123 ; [#uses=1] ; A < 123 %C = icmp eq i32 %B, 0 ; [#uses=1] ret i1 %C @@ -66,7 +66,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 [[A_OFF]], 10 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %B = udiv i32 %A, 10 ; [#uses=1] + %B = udiv nof i32 %A, 10 ; [#uses=1] ; A >= 20 && A < 30 %C = icmp eq i32 %B, 2 ; [#uses=1] ret i1 %C @@ -78,7 +78,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i32> [[A_OFF]], ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %B = udiv <2 x i32> %A, + %B = udiv nof <2 x i32> %A, %C = icmp eq <2 x i32> %B, ret <2 x i1> %C } @@ -88,7 +88,7 @@ ; CHECK-NEXT: [[C:%.*]] = icmp ugt i8 %A, -11 ; CHECK-NEXT: ret i1 [[C]] ; - %B = udiv i8 %A, 123 ; [#uses=1] + %B = udiv nof i8 %A, 123 ; [#uses=1] ; A >= 246 %C = icmp eq i8 %B, 2 ; [#uses=1] ret i1 %C @@ -99,7 +99,7 @@ ; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i8> %A, ; CHECK-NEXT: ret <2 x i1> [[C]] ; - %B = udiv <2 x i8> %A, + %B = udiv nof <2 x i8> %A, %C = icmp eq <2 x i8> %B, ret <2 x i1> %C } @@ -109,7 +109,7 @@ ; CHECK-NEXT: [[C:%.*]] = icmp ult i8 %A, -10 ; CHECK-NEXT: ret i1 [[C]] ; - %B = udiv i8 %A, 123 ; [#uses=1] + %B = udiv nof i8 %A, 123 ; [#uses=1] ; A < 246 %C = icmp ne i8 %B, 2 ; [#uses=1] ret i1 %C @@ -120,7 +120,7 @@ ; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i8> %A, ; CHECK-NEXT: ret <2 x i1> [[C]] ; - %B = udiv <2 x i8> %A, + %B = udiv nof <2 x i8> %A, %C = icmp ne <2 x i8> %B, ret <2 x i1> %C } @@ -132,7 +132,7 @@ ; CHECK-NEXT: ret i32 [[R]] ; %V = select i1 %C, i32 64, i32 8 ; [#uses=1] - %R = udiv i32 %X, %V ; [#uses=1] + %R = udiv nof i32 %X, %V ; [#uses=1] ret i32 %R } @@ -143,7 +143,7 @@ ; CHECK-NEXT: ret i32 [[B]] ; %A = select i1 %C, i32 1024, i32 32 ; [#uses=1] - %B = udiv i32 %X, %A ; [#uses=1] + %B = udiv nof i32 %X, %A ; [#uses=1] ret i32 %B } @@ -152,7 +152,7 @@ ; CHECK-LABEL: @test12( ; CHECK-NEXT: ret i32 1 ; - %tmp3 = udiv i32 %x, %x ; 1 + %tmp3 = udiv nof i32 %x, %x ; 1 ret i32 %tmp3 } @@ -160,7 +160,7 @@ ; CHECK-LABEL: @test13( ; CHECK-NEXT: ret i32 1 ; - %tmp3 = sdiv i32 %x, %x ; 1 + %tmp3 = sdiv nof i32 %x, %x ; 1 ret i32 %tmp3 } @@ -169,7 +169,7 @@ ; CHECK-NEXT: ret i32 0 ; %zext = zext i8 %x to i32 - %div = udiv i32 %zext, 257 ; 0 + %div = udiv nof i32 %zext, 257 ; 0 ret i32 %div } @@ -182,27 +182,27 @@ ; %shl = shl i32 1, %b %div = lshr i32 %shl, 2 - %div2 = udiv i32 %a, %div + %div2 = udiv nof i32 %a, %div ret i32 %div2 } define <2 x i64> @test16(<2 x i64> %x) nounwind { ; CHECK-LABEL: @test16( -; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i64> %x, +; CHECK-NEXT: [[DIV:%.*]] = udiv nof <2 x i64> %x, ; CHECK-NEXT: ret <2 x i64> [[DIV]] ; %shr = lshr <2 x i64> %x, - %div = udiv <2 x i64> %shr, + %div = udiv nof <2 x i64> %shr, ret <2 x i64> %div } define <2 x i64> @test17(<2 x i64> %x) nounwind { ; CHECK-LABEL: @test17( -; CHECK-NEXT: [[DIV:%.*]] = sdiv <2 x i64> %x, +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof <2 x i64> %x, ; CHECK-NEXT: ret <2 x i64> [[DIV]] ; %neg = sub nsw <2 x i64> zeroinitializer, %x - %div = sdiv <2 x i64> %neg, + %div = sdiv nof <2 x i64> %neg, ret <2 x i64> %div } @@ -211,7 +211,7 @@ ; CHECK-NEXT: [[DIV:%.*]] = sub <2 x i64> zeroinitializer, %x ; CHECK-NEXT: ret <2 x i64> [[DIV]] ; - %div = sdiv <2 x i64> %x, + %div = sdiv nof <2 x i64> %x, ret <2 x i64> %div } @@ -221,7 +221,7 @@ ; CHECK-NEXT: [[A:%.*]] = zext i1 [[TMP1]] to i32 ; CHECK-NEXT: ret i32 [[A]] ; - %A = udiv i32 1, %x + %A = udiv nof i32 1, %x ret i32 %A } @@ -231,7 +231,7 @@ ; CHECK-NEXT: [[A:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[A]] ; - %A = udiv <2 x i32> , %x + %A = udiv nof <2 x i32> , %x ret <2 x i32> %A } @@ -242,7 +242,7 @@ ; CHECK-NEXT: [[A:%.*]] = select i1 [[TMP2]], i32 %x, i32 0 ; CHECK-NEXT: ret i32 [[A]] ; - %A = sdiv i32 1, %x + %A = sdiv nof i32 1, %x ret i32 %A } @@ -253,37 +253,37 @@ ; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> [[X]], <2 x i32> zeroinitializer ; CHECK-NEXT: ret <2 x i32> [[A]] ; - %A = sdiv <2 x i32> , %x + %A = sdiv nof <2 x i32> , %x ret <2 x i32> %A } define i32 @test21(i32 %a) { ; CHECK-LABEL: @test21( -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, 3 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, 3 ; CHECK-NEXT: ret i32 [[DIV]] ; %shl = shl nsw i32 %a, 2 - %div = sdiv i32 %shl, 12 + %div = sdiv nof i32 %shl, 12 ret i32 %div } define i32 @test22(i32 %a) { ; CHECK-LABEL: @test22( -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, 4 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, 4 ; CHECK-NEXT: ret i32 [[DIV]] ; %mul = mul nsw i32 %a, 3 - %div = sdiv i32 %mul, 12 + %div = sdiv nof i32 %mul, 12 ret i32 %div } define i32 @test23(i32 %a) { ; CHECK-LABEL: @test23( -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 %a, 3 +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 %a, 3 ; CHECK-NEXT: ret i32 [[DIV]] ; %shl = shl nuw i32 %a, 2 - %div = udiv i32 %shl, 12 + %div = udiv nof i32 %shl, 12 ret i32 %div } @@ -293,7 +293,7 @@ ; CHECK-NEXT: ret i32 [[DIV]] ; %mul = mul nuw i32 %a, 3 - %div = udiv i32 %mul, 12 + %div = udiv nof i32 %mul, 12 ret i32 %div } @@ -303,7 +303,7 @@ ; CHECK-NEXT: ret i32 [[DIV]] ; %shl = shl nsw i32 %a, 2 - %div = sdiv i32 %shl, 2 + %div = sdiv nof i32 %shl, 2 ret i32 %div } @@ -313,7 +313,7 @@ ; CHECK-NEXT: ret i32 [[DIV]] ; %mul = mul nsw i32 %a, 12 - %div = sdiv i32 %mul, 3 + %div = sdiv nof i32 %mul, 3 ret i32 %div } @@ -323,7 +323,7 @@ ; CHECK-NEXT: ret i32 [[DIV]] ; %shl = shl nuw i32 %a, 2 - %div = udiv i32 %shl, 2 + %div = udiv nof i32 %shl, 2 ret i32 %div } @@ -333,7 +333,7 @@ ; CHECK-NEXT: ret i32 [[DIV]] ; %mul = mul nuw i32 %a, 36 - %div = udiv i32 %mul, 3 + %div = udiv nof i32 %mul, 3 ret i32 %div } @@ -343,7 +343,7 @@ ; CHECK-NEXT: ret i32 [[MUL_LOBIT]] ; %mul = shl nsw i32 %a, 31 - %div = sdiv i32 %mul, -2147483648 + %div = sdiv nof i32 %mul, -2147483648 ret i32 %div } @@ -352,7 +352,7 @@ ; CHECK-NEXT: ret i32 %a ; %mul = shl nuw i32 %a, 31 - %div = udiv i32 %mul, -2147483648 + %div = udiv nof i32 %mul, -2147483648 ret i32 %div } @@ -361,7 +361,7 @@ ; CHECK-NEXT: ret <2 x i32> zeroinitializer ; %shr = lshr <2 x i32> %x, - %div = udiv <2 x i32> %shr, + %div = udiv nof <2 x i32> %shr, ret <2 x i32> %div } @@ -369,54 +369,54 @@ ; CHECK-LABEL: @test32( ; CHECK-NEXT: [[SHL:%.*]] = shl i32 2, %b ; CHECK-NEXT: [[DIV:%.*]] = lshr i32 [[SHL]], 2 -; CHECK-NEXT: [[DIV2:%.*]] = udiv i32 %a, [[DIV]] +; CHECK-NEXT: [[DIV2:%.*]] = udiv nof i32 %a, [[DIV]] ; CHECK-NEXT: ret i32 [[DIV2]] ; %shl = shl i32 2, %b %div = lshr i32 %shl, 2 - %div2 = udiv i32 %a, %div + %div2 = udiv nof i32 %a, %div ret i32 %div2 } define <2 x i64> @test33(<2 x i64> %x) nounwind { ; CHECK-LABEL: @test33( -; CHECK-NEXT: [[DIV:%.*]] = udiv exact <2 x i64> %x, +; CHECK-NEXT: [[DIV:%.*]] = udiv exact nof <2 x i64> %x, ; CHECK-NEXT: ret <2 x i64> [[DIV]] ; %shr = lshr exact <2 x i64> %x, - %div = udiv exact <2 x i64> %shr, + %div = udiv exact nof <2 x i64> %shr, ret <2 x i64> %div } define <2 x i64> @test34(<2 x i64> %x) nounwind { ; CHECK-LABEL: @test34( -; CHECK-NEXT: [[DIV:%.*]] = sdiv exact <2 x i64> %x, +; CHECK-NEXT: [[DIV:%.*]] = sdiv exact nof <2 x i64> %x, ; CHECK-NEXT: ret <2 x i64> [[DIV]] ; %neg = sub nsw <2 x i64> zeroinitializer, %x - %div = sdiv exact <2 x i64> %neg, + %div = sdiv exact nof <2 x i64> %neg, ret <2 x i64> %div } define i32 @test35(i32 %A) { ; CHECK-LABEL: @test35( ; CHECK-NEXT: [[AND:%.*]] = and i32 %A, 2147483647 -; CHECK-NEXT: [[MUL:%.*]] = udiv exact i32 [[AND]], 2147483647 +; CHECK-NEXT: [[MUL:%.*]] = udiv exact nof i32 [[AND]], 2147483647 ; CHECK-NEXT: ret i32 [[MUL]] ; %and = and i32 %A, 2147483647 - %mul = sdiv exact i32 %and, 2147483647 + %mul = sdiv exact nof i32 %and, 2147483647 ret i32 %mul } define <2 x i32> @test35vec(<2 x i32> %A) { ; CHECK-LABEL: @test35vec( ; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[A:%.*]], -; CHECK-NEXT: [[MUL:%.*]] = udiv exact <2 x i32> [[AND]], +; CHECK-NEXT: [[MUL:%.*]] = udiv exact nof <2 x i32> [[AND]], ; CHECK-NEXT: ret <2 x i32> [[MUL]] ; %and = and <2 x i32> %A, - %mul = sdiv exact <2 x i32> %and, + %mul = sdiv exact nof <2 x i32> %and, ret <2 x i32> %mul } @@ -428,7 +428,7 @@ ; %and = and i32 %A, 2147483647 %shl = shl nsw i32 1, %A - %mul = sdiv exact i32 %and, %shl + %mul = sdiv exact nof i32 %and, %shl ret i32 %mul } @@ -440,7 +440,7 @@ ; %and = and <2 x i32> %A, %shl = shl nsw <2 x i32> , %A - %mul = sdiv exact <2 x i32> %and, %shl + %mul = sdiv exact nof <2 x i32> %and, %shl ret <2 x i32> %mul } @@ -465,7 +465,7 @@ lor.end: ; preds = %lor.rhs, %entry %t.0 = phi i32 [ %0, %entry ], [ %mul, %lor.rhs ] - %div = sdiv i32 %t.0, 2 + %div = sdiv nof i32 %t.0, 2 ret i32 %div } @@ -473,12 +473,12 @@ define i32 @shrink(i8 %x) { ; CHECK-LABEL: @shrink( -; CHECK-NEXT: [[TMP1:%.*]] = sdiv i8 %x, 127 +; CHECK-NEXT: [[TMP1:%.*]] = sdiv nof i8 %x, 127 ; CHECK-NEXT: [[DIV:%.*]] = sext i8 [[TMP1]] to i32 ; CHECK-NEXT: ret i32 [[DIV]] ; %conv = sext i8 %x to i32 - %div = sdiv i32 %conv, 127 + %div = sdiv nof i32 %conv, 127 ret i32 %div } @@ -491,7 +491,7 @@ ; CHECK-NEXT: ret i32 [[DIV]] ; %conv = sext i8 %x to i32 - %div = sdiv i32 %conv, -128 + %div = sdiv nof i32 %conv, -128 ret i32 %div } @@ -499,12 +499,12 @@ define <3 x i32> @shrink_vec(<3 x i8> %x) { ; CHECK-LABEL: @shrink_vec( -; CHECK-NEXT: [[TMP1:%.*]] = sdiv <3 x i8> %x, +; CHECK-NEXT: [[TMP1:%.*]] = sdiv nof <3 x i8> %x, ; CHECK-NEXT: [[DIV:%.*]] = sext <3 x i8> [[TMP1]] to <3 x i32> ; CHECK-NEXT: ret <3 x i32> [[DIV]] ; %conv = sext <3 x i8> %x to <3 x i32> - %div = sdiv <3 x i32> %conv, + %div = sdiv nof <3 x i32> %conv, ret <3 x i32> %div } @@ -515,7 +515,7 @@ ; CHECK-NEXT: ret <2 x i32> [[DIV]] ; %conv = sext <2 x i8> %x to <2 x i32> - %div = sdiv <2 x i32> %conv, + %div = sdiv nof <2 x i32> %conv, ret <2 x i32> %div } @@ -524,11 +524,11 @@ define i32 @shrink_no(i8 %x) { ; CHECK-LABEL: @shrink_no( ; CHECK-NEXT: [[CONV:%.*]] = sext i8 %x to i32 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 128 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[CONV]], 128 ; CHECK-NEXT: ret i32 [[DIV]] ; %conv = sext i8 %x to i32 - %div = sdiv i32 %conv, 128 + %div = sdiv nof i32 %conv, 128 ret i32 %div } @@ -540,7 +540,7 @@ ; CHECK-NEXT: ret i32 0 ; %conv = sext i8 %x to i32 - %div = sdiv i32 %conv, -129 + %div = sdiv nof i32 %conv, -129 ret i32 %div } @@ -549,7 +549,7 @@ ; CHECK-NEXT: ret i32 0 ; %conv = sext i16 %x to i32 - %div = sdiv i32 %conv, 65535 + %div = sdiv nof i32 %conv, 65535 ret i32 %div } @@ -559,7 +559,7 @@ ; CHECK-NEXT: ret <2 x i8> zeroinitializer ; %neg = and <2 x i8> %x, - %div = udiv <2 x i8> , %neg + %div = udiv nof <2 x i8> , %neg ret <2 x i8> %div } Index: test/Transforms/InstCombine/exact.ll =================================================================== --- test/Transforms/InstCombine/exact.ll +++ test/Transforms/InstCombine/exact.ll @@ -3,10 +3,10 @@ define i32 @sdiv1(i32 %x) { ; CHECK-LABEL: @sdiv1( -; CHECK-NEXT: [[Y:%.*]] = sdiv i32 %x, 8 +; CHECK-NEXT: [[Y:%.*]] = sdiv nof i32 %x, 8 ; CHECK-NEXT: ret i32 [[Y]] ; - %y = sdiv i32 %x, 8 + %y = sdiv nof i32 %x, 8 ret i32 %y } @@ -15,7 +15,7 @@ ; CHECK-NEXT: [[Y:%.*]] = ashr exact i32 %x, 3 ; CHECK-NEXT: ret i32 [[Y]] ; - %y = sdiv exact i32 %x, 8 + %y = sdiv exact nof i32 %x, 8 ret i32 %y } @@ -24,7 +24,7 @@ ; CHECK-NEXT: [[Y:%.*]] = ashr exact <2 x i32> %x, ; CHECK-NEXT: ret <2 x i32> [[Y]] ; - %y = sdiv exact <2 x i32> %x, + %y = sdiv exact nof <2 x i32> %x, ret <2 x i32> %y } @@ -34,7 +34,7 @@ ; CHECK-NEXT: [[Z:%.*]] = sub i32 %x, [[Y]] ; CHECK-NEXT: ret i32 [[Z]] ; - %y = sdiv i32 %x, 3 + %y = sdiv nof i32 %x, 3 %z = mul i32 %y, 3 ret i32 %z } @@ -43,7 +43,7 @@ ; CHECK-LABEL: @sdiv4( ; CHECK-NEXT: ret i32 %x ; - %y = sdiv exact i32 %x, 3 + %y = sdiv exact nof i32 %x, 3 %z = mul i32 %y, 3 ret i32 %z } @@ -54,7 +54,7 @@ ; CHECK-NEXT: [[Z:%.*]] = sub i32 [[Y]], %x ; CHECK-NEXT: ret i32 [[Z]] ; - %y = sdiv i32 %x, 3 + %y = sdiv nof i32 %x, 3 %z = mul i32 %y, -3 ret i32 %z } @@ -64,7 +64,7 @@ ; CHECK-NEXT: [[Z:%.*]] = sub i32 0, %x ; CHECK-NEXT: ret i32 [[Z]] ; - %y = sdiv exact i32 %x, 3 + %y = sdiv exact nof i32 %x, 3 %z = mul i32 %y, -3 ret i32 %z } @@ -73,7 +73,7 @@ ; CHECK-LABEL: @udiv1( ; CHECK-NEXT: ret i32 %x ; - %y = udiv exact i32 %x, %w + %y = udiv exact nof i32 %x, %w %z = mul i32 %y, %w ret i32 %z } @@ -84,7 +84,7 @@ ; CHECK-NEXT: ret i32 [[Z]] ; %y = shl i32 1, %w - %z = udiv exact i32 %x, %y + %z = udiv exact nof i32 %x, %y ret i32 %z } @@ -179,7 +179,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 %X, 0 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %A = udiv exact i64 %X, 5 ; X/5 + %A = udiv exact nof i64 %X, 5 ; X/5 %B = icmp ne i64 %A, 0 ret i1 %B } @@ -189,7 +189,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <2 x i64> %X, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %A = udiv exact <2 x i64> %X, + %A = udiv exact nof <2 x i64> %X, %B = icmp ne <2 x i64> %A, zeroinitializer ret <2 x i1> %B } @@ -199,7 +199,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %A = udiv exact i64 %X, 5 ; X/5 == 0 --> x == 0 + %A = udiv exact nof i64 %X, 5 ; X/5 == 0 --> x == 0 %B = icmp eq i64 %A, 0 ret i1 %B } @@ -209,7 +209,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %A = udiv exact <2 x i64> %X, + %A = udiv exact nof <2 x i64> %X, %B = icmp eq <2 x i64> %A, zeroinitializer ret <2 x i1> %B } @@ -219,7 +219,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %A = sdiv exact i64 %X, 5 ; X/5 == 0 --> x == 0 + %A = sdiv exact nof i64 %X, 5 ; X/5 == 0 --> x == 0 %B = icmp eq i64 %A, 0 ret i1 %B } @@ -229,7 +229,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %A = sdiv exact <2 x i64> %X, + %A = sdiv exact nof <2 x i64> %X, %B = icmp eq <2 x i64> %A, zeroinitializer ret <2 x i1> %B } @@ -239,7 +239,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 5 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %A = sdiv exact i64 %X, 5 ; X/5 == 1 --> x == 5 + %A = sdiv exact nof i64 %X, 5 ; X/5 == 1 --> x == 5 %B = icmp eq i64 %A, 1 ret i1 %B } @@ -249,7 +249,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %A = sdiv exact <2 x i64> %X, + %A = sdiv exact nof <2 x i64> %X, %B = icmp eq <2 x i64> %A, ret <2 x i1> %B } @@ -259,7 +259,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, -5 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %A = sdiv exact i64 %X, 5 ; X/5 == -1 --> x == -5 + %A = sdiv exact nof i64 %X, 5 ; X/5 == -1 --> x == -5 %B = icmp eq i64 %A, -1 ret i1 %B } @@ -269,7 +269,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %A = sdiv exact <2 x i64> %X, + %A = sdiv exact nof <2 x i64> %X, %B = icmp eq <2 x i64> %A, ret <2 x i1> %B } @@ -279,7 +279,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 0 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %A = sdiv exact i64 %X, -5 ; X/-5 == 0 --> x == 0 + %A = sdiv exact nof i64 %X, -5 ; X/-5 == 0 --> x == 0 %B = icmp eq i64 %A, 0 ret i1 %B } @@ -289,7 +289,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, zeroinitializer ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %A = sdiv exact <2 x i64> %X, + %A = sdiv exact nof <2 x i64> %X, %B = icmp eq <2 x i64> %A, zeroinitializer ret <2 x i1> %B } @@ -299,7 +299,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, -5 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %A = sdiv exact i64 %X, -5 ; X/-5 == 1 --> x == -5 + %A = sdiv exact nof i64 %X, -5 ; X/-5 == 1 --> x == -5 %B = icmp eq i64 %A, 1 ret i1 %B } @@ -309,7 +309,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %A = sdiv exact <2 x i64> %X, + %A = sdiv exact nof <2 x i64> %X, %B = icmp eq <2 x i64> %A, ret <2 x i1> %B } @@ -319,7 +319,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 %X, 5 ; CHECK-NEXT: ret i1 [[TMP1]] ; - %A = sdiv exact i64 %X, -5 ; X/-5 == -1 --> x == 5 + %A = sdiv exact nof i64 %X, -5 ; X/-5 == -1 --> x == 5 %B = icmp eq i64 %A, -1 ret i1 %B } @@ -329,7 +329,7 @@ ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> %X, ; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; - %A = sdiv exact <2 x i64> %X, + %A = sdiv exact nof <2 x i64> %X, %B = icmp eq <2 x i64> %A, ret <2 x i1> %B } Index: test/Transforms/InstCombine/getelementptr.ll =================================================================== --- test/Transforms/InstCombine/getelementptr.ll +++ test/Transforms/InstCombine/getelementptr.ll @@ -843,7 +843,7 @@ define %struct.C* @test44(%struct.C* %c1, %struct.C* %c2) { %ptrtoint = ptrtoint %struct.C* %c1 to i64 %sub = sub i64 0, %ptrtoint - %shr = sdiv i64 %sub, 7 + %shr = sdiv nof i64 %sub, 7 %gep = getelementptr inbounds %struct.C, %struct.C* %c2, i64 %shr ret %struct.C* %gep @@ -859,7 +859,7 @@ %ptrtoint1 = ptrtoint %struct.C* %c1 to i64 %ptrtoint2 = ptrtoint %struct.C** %c2 to i64 %sub = sub i64 %ptrtoint2, %ptrtoint1 ; C2 - C1 - %shr = sdiv i64 %sub, 7 + %shr = sdiv nof i64 %sub, 7 %gep = getelementptr inbounds %struct.C, %struct.C* %c1, i64 %shr ; C1 + (C2 - C1) ret %struct.C* %gep @@ -871,14 +871,14 @@ define %struct.C* @test46(%struct.C* %c1, %struct.C* %c2, i64 %N) { %ptrtoint = ptrtoint %struct.C* %c1 to i64 %sub = sub i64 0, %ptrtoint - %sdiv = sdiv i64 %sub, %N + %sdiv = sdiv nof i64 %sub, %N %gep = getelementptr inbounds %struct.C, %struct.C* %c2, i64 %sdiv ret %struct.C* %gep ; CHECK-LABEL: @test46( ; CHECK-NEXT: [[PTRTOINT:%.*]] = ptrtoint %struct.C* %c1 to i64 ; CHECK-NEXT: [[SUB:%.*]] = sub i64 0, [[PTRTOINT]] -; CHECK-NEXT: [[SDIV:%.*]] = sdiv i64 [[SUB]], %N +; CHECK-NEXT: [[SDIV:%.*]] = sdiv nof i64 [[SUB]], %N ; CHECK-NEXT: [[GEP:%.*]] = getelementptr inbounds %struct.C, %struct.C* %c2, i64 %sdiv ; CHECK-NEXT: ret %struct.C* [[GEP]] } Index: test/Transforms/InstCombine/hoist_instr.ll =================================================================== --- test/Transforms/InstCombine/hoist_instr.ll +++ test/Transforms/InstCombine/hoist_instr.ll @@ -7,12 +7,12 @@ then: ; preds = %entry ; CHECK: then: -; CHECK-NEXT: sdiv i32 +; CHECK-NEXT: sdiv nof i32 br label %endif endif: ; preds = %then, %entry %X = phi i32 [ %A, %then ], [ 15, %entry ] ; [#uses=1] - %Y = sdiv i32 %X, 42 ; [#uses=1] + %Y = sdiv nof i32 %X, 42 ; [#uses=1] ret i32 %Y } Index: test/Transforms/InstCombine/icmp.ll =================================================================== --- test/Transforms/InstCombine/icmp.ll +++ test/Transforms/InstCombine/icmp.ll @@ -371,7 +371,7 @@ ; CHECK-NEXT: [[I4:%.*]] = icmp sgt i32 %x, 1328634634 ; CHECK-NEXT: ret i1 [[I4]] ; - %i3 = sdiv i32 %x, -1328634635 + %i3 = sdiv nof i32 %x, -1328634635 %i4 = icmp eq i32 %i3, -1 ret i1 %i4 } @@ -381,7 +381,7 @@ ; CHECK-NEXT: [[I4:%.*]] = icmp sgt <2 x i32> %x, ; CHECK-NEXT: ret <2 x i1> [[I4]] ; - %i3 = sdiv <2 x i32> %x, + %i3 = sdiv nof <2 x i32> %x, %i4 = icmp eq <2 x i32> %i3, ret <2 x i1> %i4 } @@ -710,8 +710,8 @@ ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 %X, %Y ; CHECK-NEXT: ret i1 [[C]] ; - %A = sdiv exact i32 %X, %Z - %B = sdiv exact i32 %Y, %Z + %A = sdiv exact nof i32 %X, %Z + %B = sdiv exact nof i32 %Y, %Z %C = icmp eq i32 %A, %B ret i1 %C } @@ -720,13 +720,13 @@ define i1 @PR32949(i32 %X, i32 %Y, i32 %Z) { ; CHECK-LABEL: @PR32949( -; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 %X, %Z -; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 %Y, %Z +; CHECK-NEXT: [[A:%.*]] = sdiv exact nof i32 %X, %Z +; CHECK-NEXT: [[B:%.*]] = sdiv exact nof i32 %Y, %Z ; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], [[B]] ; CHECK-NEXT: ret i1 [[C]] ; - %A = sdiv exact i32 %X, %Z - %B = sdiv exact i32 %Y, %Z + %A = sdiv exact nof i32 %X, %Z + %B = sdiv exact nof i32 %Y, %Z %C = icmp sgt i32 %A, %B ret i1 %C } @@ -802,13 +802,13 @@ ; PR9838 define i1 @test53(i32 %a, i32 %b) { ; CHECK-LABEL: @test53( -; CHECK-NEXT: [[X:%.*]] = sdiv exact i32 %a, 30 -; CHECK-NEXT: [[Y:%.*]] = sdiv i32 %b, 30 +; CHECK-NEXT: [[X:%.*]] = sdiv exact nof i32 %a, 30 +; CHECK-NEXT: [[Y:%.*]] = sdiv nof i32 %b, 30 ; CHECK-NEXT: [[Z:%.*]] = icmp eq i32 [[X]], [[Y]] ; CHECK-NEXT: ret i1 [[Z]] ; - %x = sdiv exact i32 %a, 30 - %y = sdiv i32 %b, 30 + %x = sdiv exact nof i32 %a, 30 + %y = sdiv nof i32 %b, 30 %z = icmp eq i32 %x, %y ret i1 %z } Index: test/Transforms/InstCombine/nsw.ll =================================================================== --- test/Transforms/InstCombine/nsw.ll +++ test/Transforms/InstCombine/nsw.ll @@ -2,20 +2,20 @@ ; CHECK-LABEL: @sub1( ; CHECK: %y = sub i32 0, %x -; CHECK: %z = sdiv i32 %y, 337 +; CHECK: %z = sdiv nof i32 %y, 337 ; CHECK: ret i32 %z define i32 @sub1(i32 %x) { %y = sub i32 0, %x - %z = sdiv i32 %y, 337 + %z = sdiv nof i32 %y, 337 ret i32 %z } ; CHECK-LABEL: @sub2( -; CHECK: %z = sdiv i32 %x, -337 +; CHECK: %z = sdiv nof i32 %x, -337 ; CHECK: ret i32 %z define i32 @sub2(i32 %x) { %y = sub nsw i32 0, %x - %z = sdiv i32 %y, 337 + %z = sdiv nof i32 %y, 337 ret i32 %z } Index: test/Transforms/InstCombine/preserve-sminmax.ll =================================================================== --- test/Transforms/InstCombine/preserve-sminmax.ll +++ test/Transforms/InstCombine/preserve-sminmax.ll @@ -1,31 +1,31 @@ ; RUN: opt < %s -instcombine -S | FileCheck %s -; Instcombine normally would fold the sdiv into the comparison, -; making "icmp slt i32 %h, 2", but in this case the sdiv has +; Instcombine normally would fold the sdiv nof into the comparison, +; making "icmp slt i32 %h, 2", but in this case the sdiv nof has ; another use, so it wouldn't a big win, and it would also ; obfuscate an otherise obvious smax pattern to the point where ; other analyses wouldn't recognize it. define i32 @foo(i32 %h) { - %sd = sdiv i32 %h, 2 + %sd = sdiv nof i32 %h, 2 %t = icmp slt i32 %sd, 1 %r = select i1 %t, i32 %sd, i32 1 ret i32 %r } -; CHECK: %sd = sdiv i32 %h, 2 +; CHECK: %sd = sdiv nof i32 %h, 2 ; CHECK: %t = icmp slt i32 %sd, 1 ; CHECK: %r = select i1 %t, i32 %sd, i32 1 ; CHECK: ret i32 %r define i32 @bar(i32 %h) { - %sd = sdiv i32 %h, 2 + %sd = sdiv nof i32 %h, 2 %t = icmp sgt i32 %sd, 1 %r = select i1 %t, i32 %sd, i32 1 ret i32 %r } -; CHECK: %sd = sdiv i32 %h, 2 +; CHECK: %sd = sdiv nof i32 %h, 2 ; CHECK: %t = icmp sgt i32 %sd, 1 ; CHECK: %r = select i1 %t, i32 %sd, i32 1 ; CHECK: ret i32 %r Index: test/Transforms/InstCombine/rem.ll =================================================================== --- test/Transforms/InstCombine/rem.ll +++ test/Transforms/InstCombine/rem.ll @@ -6,7 +6,7 @@ ; CHECK-NEXT: [[R:%.*]] = srem i64 %x1, %y2 ; CHECK-NEXT: ret i64 [[R]] ; - %r = sdiv i64 %x1, %y2 + %r = sdiv nof i64 %x1, %y2 %r7 = mul i64 %r, %y2 %r8 = sub i64 %x1, %r7 ret i64 %r8 @@ -17,7 +17,7 @@ ; CHECK-NEXT: [[K:%.*]] = srem <4 x i32> %t, %u ; CHECK-NEXT: ret <4 x i32> [[K]] ; - %k = sdiv <4 x i32> %t, %u + %k = sdiv nof <4 x i32> %t, %u %l = mul <4 x i32> %k, %u %m = sub <4 x i32> %t, %l ret <4 x i32> %m @@ -28,7 +28,7 @@ ; CHECK-NEXT: [[R:%.*]] = urem i64 %x1, %y2 ; CHECK-NEXT: ret i64 [[R]] ; - %r = udiv i64 %x1, %y2 + %r = udiv nof i64 %x1, %y2 %r7 = mul i64 %r, %y2 %r8 = sub i64 %x1, %r7 ret i64 %r8 @@ -74,7 +74,7 @@ ; CHECK-NEXT: [[A:%.*]] = urem i8 %x, %y ; CHECK-NEXT: ret i8 [[A]] ; - %A = udiv i8 %x, %y + %A = udiv nof i8 %x, %y %B = mul i8 %A, %y %C = sub i8 %x, %B ret i8 %C @@ -85,7 +85,7 @@ ; CHECK-NEXT: [[A:%.*]] = srem i8 %x, %y ; CHECK-NEXT: ret i8 [[A]] ; - %A = sdiv i8 %x, %y + %A = sdiv nof i8 %x, %y %B = mul i8 %A, %y %C = sub i8 %x, %B ret i8 %C @@ -97,7 +97,7 @@ ; CHECK-NEXT: [[C:%.*]] = sub i8 0, [[A]] ; CHECK-NEXT: ret i8 [[C]] ; - %A = udiv i8 %x, %y + %A = udiv nof i8 %x, %y %B = mul i8 %A, %y %C = sub i8 %B, %x ret i8 %C @@ -110,7 +110,7 @@ ; CHECK-NEXT: [[C:%.*]] = add i8 [[B1]], %x ; CHECK-NEXT: ret i8 [[C]] ; - %A = udiv i8 %x, 3 + %A = udiv nof i8 %x, 3 %B = mul i8 %A, -3 %C = sub i8 %x, %B ret i8 %C @@ -120,12 +120,12 @@ define i32 @sdiv_mul_sdiv(i32 %x, i32 %y) { ; CHECK-LABEL: @sdiv_mul_sdiv( -; CHECK-NEXT: [[R:%.*]] = sdiv i32 %x, %y +; CHECK-NEXT: [[R:%.*]] = sdiv nof i32 %x, %y ; CHECK-NEXT: ret i32 [[R]] ; - %div = sdiv i32 %x, %y + %div = sdiv nof i32 %x, %y %mul = mul i32 %div, %y - %r = sdiv i32 %mul, %y + %r = sdiv nof i32 %mul, %y ret i32 %r } @@ -133,12 +133,12 @@ define i32 @udiv_mul_udiv(i32 %x, i32 %y) { ; CHECK-LABEL: @udiv_mul_udiv( -; CHECK-NEXT: [[R:%.*]] = udiv i32 %x, %y +; CHECK-NEXT: [[R:%.*]] = udiv nof i32 %x, %y ; CHECK-NEXT: ret i32 [[R]] ; - %div = udiv i32 %x, %y + %div = udiv nof i32 %x, %y %mul = mul i32 %div, %y - %r = udiv i32 %mul, %y + %r = udiv nof i32 %mul, %y ret i32 %r } Index: test/Transforms/InstCombine/select.ll =================================================================== --- test/Transforms/InstCombine/select.ll +++ test/Transforms/InstCombine/select.ll @@ -495,10 +495,10 @@ define i32 @test18(i32 %X, i32 %Y, i1 %C) { %R = select i1 %C, i32 %X, i32 0 - %V = sdiv i32 %Y, %R + %V = sdiv nof i32 %Y, %R ret i32 %V ; CHECK-LABEL: @test18( -; CHECK: %V = sdiv i32 %Y, %X +; CHECK: %V = sdiv nof i32 %Y, %X ; CHECK: ret i32 %V } @@ -1016,7 +1016,7 @@ lor.end: %t.1 = phi i32 [ 0, %entry ], [ %phitmp, %lor.rhs ] %conv6 = zext i16 %b to i32 - %div = udiv i32 %conv6, %t.1 + %div = udiv nof i32 %conv6, %t.1 %tobool8 = icmp eq i32 %div, 0 %cmp = icmp eq i32 %t.1, 0 %cmp12 = icmp ult i32 %conv2, 2 Index: test/Transforms/InstCombine/sext.ll =================================================================== --- test/Transforms/InstCombine/sext.ll +++ test/Transforms/InstCombine/sext.ll @@ -42,11 +42,11 @@ define i64 @test4(i32 %x) { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[T:%.*]] = udiv i32 %x, 3 +; CHECK-NEXT: [[T:%.*]] = udiv nof i32 %x, 3 ; CHECK-NEXT: [[S1:%.*]] = zext i32 [[T]] to i64 ; CHECK-NEXT: ret i64 [[S1]] ; - %t = udiv i32 %x, 3 + %t = udiv nof i32 %x, 3 %s = sext i32 %t to i64 ret i64 %s } Index: test/Transforms/InstCombine/shift.ll =================================================================== --- test/Transforms/InstCombine/shift.ll +++ test/Transforms/InstCombine/shift.ll @@ -227,13 +227,13 @@ ; CHECK-NEXT: [[A:%.*]] = ashr i8 [[X:%.*]], 6 ; CHECK-NEXT: [[B:%.*]] = and i8 [[X]], -64 ; CHECK-NEXT: [[EXTRA_USE_OF_A:%.*]] = mul nsw i8 [[A]], 5 -; CHECK-NEXT: [[R:%.*]] = sdiv i8 [[EXTRA_USE_OF_A]], [[B]] +; CHECK-NEXT: [[R:%.*]] = sdiv nof i8 [[EXTRA_USE_OF_A]], [[B]] ; CHECK-NEXT: ret i8 [[R]] ; %a = ashr i8 %x, 6 %b = shl i8 %a, 6 %extra_use_of_a = mul i8 %a, 5 - %r = sdiv i8 %extra_use_of_a, %b + %r = sdiv nof i8 %extra_use_of_a, %b ret i8 %r } @@ -739,7 +739,7 @@ ; %shl1 = shl i32 1, %b %shl2 = shl i32 %shl1, 2 - %div = udiv i32 %a, %shl2 + %div = udiv nof i32 %a, %shl2 ret i32 %div } @@ -756,22 +756,22 @@ define i32 @test42(i32 %a, i32 %b) nounwind { ; CHECK-LABEL: @test42( ; CHECK-NEXT: [[DIV:%.*]] = lshr exact i32 4096, %b -; CHECK-NEXT: [[DIV2:%.*]] = udiv i32 %a, [[DIV]] +; CHECK-NEXT: [[DIV2:%.*]] = udiv nof i32 %a, [[DIV]] ; CHECK-NEXT: ret i32 [[DIV2]] ; %div = lshr i32 4096, %b ; must be exact otherwise we'd divide by zero - %div2 = udiv i32 %a, %div + %div2 = udiv nof i32 %a, %div ret i32 %div2 } define <2 x i32> @test42vec(<2 x i32> %a, <2 x i32> %b) { ; CHECK-LABEL: @test42vec( ; CHECK-NEXT: [[DIV:%.*]] = lshr exact <2 x i32> , %b -; CHECK-NEXT: [[DIV2:%.*]] = udiv <2 x i32> %a, [[DIV]] +; CHECK-NEXT: [[DIV2:%.*]] = udiv nof <2 x i32> %a, [[DIV]] ; CHECK-NEXT: ret <2 x i32> [[DIV2]] ; %div = lshr <2 x i32> , %b ; must be exact otherwise we'd divide by zero - %div2 = udiv <2 x i32> %a, %div + %div2 = udiv nof <2 x i32> %a, %div ret <2 x i32> %div2 } @@ -782,7 +782,7 @@ ; CHECK-NEXT: ret i32 [[DIV2]] ; %div = shl i32 4096, %b ; must be exact otherwise we'd divide by zero - %div2 = udiv i32 %a, %div + %div2 = udiv nof i32 %a, %div ret i32 %div2 } Index: test/Transforms/InstCombine/sink_instruction.ll =================================================================== --- test/Transforms/InstCombine/sink_instruction.ll +++ test/Transforms/InstCombine/sink_instruction.ll @@ -6,7 +6,7 @@ define i32 @test1(i1 %C, i32 %A, i32 %B) { ; CHECK-LABEL: @test1( entry: - %tmp.2 = sdiv i32 %A, %B ; [#uses=1] + %tmp.2 = sdiv nof i32 %A, %B ; [#uses=1] %tmp.9 = add i32 %B, %A ; [#uses=1] br i1 %C, label %then, label %endif @@ -14,7 +14,7 @@ ret i32 %tmp.9 endif: ; preds = %entry -; CHECK: sdiv i32 +; CHECK: sdiv nof i32 ; CHECK-NEXT: ret i32 ret i32 %tmp.2 } @@ -23,7 +23,7 @@ ;; PHI use, sink divide before call. define i32 @test2(i32 %x) nounwind ssp { ; CHECK-LABEL: @test2( -; CHECK-NOT: sdiv i32 +; CHECK-NOT: sdiv nof i32 entry: br label %bb @@ -31,14 +31,14 @@ %x_addr.17 = phi i32 [ %x, %entry ], [ %x_addr.0, %bb2 ] ; [#uses=4] %i.06 = phi i32 [ 0, %entry ], [ %4, %bb2 ] ; [#uses=1] %0 = add nsw i32 %x_addr.17, 1 ; [#uses=1] - %1 = sdiv i32 %0, %x_addr.17 ; [#uses=1] + %1 = sdiv nof i32 %0, %x_addr.17 ; [#uses=1] %2 = icmp eq i32 %x_addr.17, 0 ; [#uses=1] br i1 %2, label %bb1, label %bb2 bb1: ; preds = %bb ; CHECK: bb1: ; CHECK-NEXT: add nsw i32 %x_addr.17, 1 -; CHECK-NEXT: sdiv i32 +; CHECK-NEXT: sdiv nof i32 ; CHECK-NEXT: tail call i32 @bar() %3 = tail call i32 @bar() nounwind ; [#uses=0] br label %bb2 Index: test/Transforms/InstCombine/sub.ll =================================================================== --- test/Transforms/InstCombine/sub.ll +++ test/Transforms/InstCombine/sub.ll @@ -196,10 +196,10 @@ define i32 @test16(i32 %A) { ; CHECK-LABEL: @test16( -; CHECK-NEXT: [[Y:%.*]] = sdiv i32 [[A:%.*]], -1123 +; CHECK-NEXT: [[Y:%.*]] = sdiv nof i32 [[A:%.*]], -1123 ; CHECK-NEXT: ret i32 [[Y]] ; - %X = sdiv i32 %A, 1123 + %X = sdiv nof i32 %A, 1123 %Y = sub i32 0, %X ret i32 %Y } @@ -209,11 +209,11 @@ define i32 @test17(i32 %A) { ; CHECK-LABEL: @test17( ; CHECK-NEXT: [[B:%.*]] = sub i32 0, [[A:%.*]] -; CHECK-NEXT: [[C:%.*]] = sdiv i32 [[B]], 1234 +; CHECK-NEXT: [[C:%.*]] = sdiv nof i32 [[B]], 1234 ; CHECK-NEXT: ret i32 [[C]] ; %B = sub i32 0, %A - %C = sdiv i32 %B, 1234 + %C = sdiv nof i32 %B, 1234 ret i32 %C } @@ -616,7 +616,7 @@ ; CHECK-NEXT: [[SUB:%.*]] = sext <2 x i1> [[TMP1]] to <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[SUB]] ; - %div = sdiv <2 x i32> %A, + %div = sdiv nof <2 x i32> %A, %sub = sub nsw <2 x i32> zeroinitializer, %div ret <2 x i32> %sub } @@ -627,7 +627,7 @@ ; CHECK-NEXT: [[SUB:%.*]] = sext i1 [[TMP1]] to i32 ; CHECK-NEXT: ret i32 [[SUB]] ; - %div = sdiv i32 %A, -2147483648 + %div = sdiv nof i32 %A, -2147483648 %sub = sub nsw i32 0, %div ret i32 %sub } Index: test/Transforms/InstCombine/trunc-binop-ext.ll =================================================================== --- test/Transforms/InstCombine/trunc-binop-ext.ll +++ test/Transforms/InstCombine/trunc-binop-ext.ll @@ -149,12 +149,12 @@ define <2 x i16> @narrow_sext_and_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_and_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = sext <2 x i16> %x16 to <2 x i32> %b = and <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -163,12 +163,12 @@ define <2 x i16> @narrow_zext_and_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_and_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = and <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = zext <2 x i16> %x16 to <2 x i32> %b = and <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -177,12 +177,12 @@ define <2 x i16> @narrow_sext_or_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_or_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = or <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = sext <2 x i16> %x16 to <2 x i32> %b = or <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -191,12 +191,12 @@ define <2 x i16> @narrow_zext_or_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_or_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = or <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = zext <2 x i16> %x16 to <2 x i32> %b = or <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -205,12 +205,12 @@ define <2 x i16> @narrow_sext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_xor_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = xor <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = sext <2 x i16> %x16 to <2 x i32> %b = xor <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -219,12 +219,12 @@ define <2 x i16> @narrow_zext_xor_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_xor_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = xor <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = zext <2 x i16> %x16 to <2 x i32> %b = xor <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -233,12 +233,12 @@ define <2 x i16> @narrow_sext_add_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_add_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = add <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = sext <2 x i16> %x16 to <2 x i32> %b = add <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -247,12 +247,12 @@ define <2 x i16> @narrow_zext_add_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_add_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = add <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = zext <2 x i16> %x16 to <2 x i32> %b = add <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -261,12 +261,12 @@ define <2 x i16> @narrow_sext_sub_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_sub_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = sub <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = sext <2 x i16> %x16 to <2 x i32> %b = sub <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -275,12 +275,12 @@ define <2 x i16> @narrow_zext_sub_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_sub_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = sub <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = zext <2 x i16> %x16 to <2 x i32> %b = sub <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -289,12 +289,12 @@ define <2 x i16> @narrow_sext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_sext_mul_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = mul <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = sext <2 x i16> %x16 to <2 x i32> %b = mul <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> @@ -303,12 +303,12 @@ define <2 x i16> @narrow_zext_mul_commute(<2 x i16> %x16, <2 x i32> %y32) { ; CHECK-LABEL: @narrow_zext_mul_commute( -; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv <2 x i32> %y32, +; CHECK-NEXT: [[Y32OP0:%.*]] = sdiv nof <2 x i32> %y32, ; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[Y32OP0]] to <2 x i16> ; CHECK-NEXT: [[R:%.*]] = mul <2 x i16> [[TMP1]], %x16 ; CHECK-NEXT: ret <2 x i16> [[R]] ; - %y32op0 = sdiv <2 x i32> %y32, + %y32op0 = sdiv nof <2 x i32> %y32, %x32 = zext <2 x i16> %x16 to <2 x i32> %b = mul <2 x i32> %y32op0, %x32 %r = trunc <2 x i32> %b to <2 x i16> Index: test/Transforms/InstCombine/udiv-simplify.ll =================================================================== --- test/Transforms/InstCombine/udiv-simplify.ll +++ test/Transforms/InstCombine/udiv-simplify.ll @@ -6,7 +6,7 @@ ; CHECK-NEXT: ret i64 0 ; %y = lshr i32 %x, 1 - %r = udiv i32 %y, -1 + %r = udiv nof i32 %y, -1 %z = sext i32 %r to i64 ret i64 %z } @@ -15,7 +15,7 @@ ; CHECK-NEXT: ret i64 0 ; %y = lshr i32 %x, 31 - %r = udiv i32 %y, 3 + %r = udiv nof i32 %y, 3 %z = sext i32 %r to i64 ret i64 %z } @@ -26,24 +26,24 @@ define i64 @test1_PR2274(i32 %x, i32 %g) nounwind { ; CHECK-LABEL: @test1_PR2274( ; CHECK-NEXT: [[Y:%.*]] = lshr i32 [[X:%.*]], 30 -; CHECK-NEXT: [[R:%.*]] = udiv i32 [[Y]], [[G:%.*]] +; CHECK-NEXT: [[R:%.*]] = udiv nof i32 [[Y]], [[G:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[R]] to i64 ; CHECK-NEXT: ret i64 [[TMP1]] ; %y = lshr i32 %x, 30 - %r = udiv i32 %y, %g + %r = udiv nof i32 %y, %g %z = sext i32 %r to i64 ret i64 %z } define i64 @test2_PR2274(i32 %x, i32 %v) nounwind { ; CHECK-LABEL: @test2_PR2274( ; CHECK-NEXT: [[Y:%.*]] = lshr i32 [[X:%.*]], 31 -; CHECK-NEXT: [[R:%.*]] = udiv i32 [[Y]], [[V:%.*]] +; CHECK-NEXT: [[R:%.*]] = udiv nof i32 [[Y]], [[V:%.*]] ; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[R]] to i64 ; CHECK-NEXT: ret i64 [[TMP1]] ; %y = lshr i32 %x, 31 - %r = udiv i32 %y, %v + %r = udiv nof i32 %y, %v %z = sext i32 %r to i64 ret i64 %z } @@ -59,7 +59,7 @@ ; CHECK-NEXT: ret i32 [[D]] ; %z = zext i1 %a to i32 - %d = udiv i32 %z, zext (i16 shl (i16 1, i16 ptrtoint ([1 x i16]* @b to i16)) to i32) + %d = udiv nof i32 %z, zext (i16 shl (i16 1, i16 ptrtoint ([1 x i16]* @b to i16)) to i32) ret i32 %d } @@ -70,7 +70,7 @@ ; CHECK-NEXT: store i1 false, i1* undef, align 1 ; CHECK-NEXT: ret i177 0 ; - %B5 = udiv i177 %Y, -1 + %B5 = udiv nof i177 %Y, -1 %B4 = add i177 %B5, -1 %B2 = add i177 %B4, -1 %B6 = mul i177 %B5, %B2 @@ -78,7 +78,7 @@ %B9 = xor i177 %B4, %B3 %B13 = ashr i177 %Y, %B2 %B22 = add i177 %B9, %B13 - %B1 = udiv i177 %B5, %B6 + %B1 = udiv nof i177 %B5, %B6 %C9 = icmp ult i177 %Y, %B22 store i1 %C9, i1* undef ret i177 %B1 Index: test/Transforms/InstCombine/udivrem-change-width.ll =================================================================== --- test/Transforms/InstCombine/udivrem-change-width.ll +++ test/Transforms/InstCombine/udivrem-change-width.ll @@ -5,24 +5,24 @@ ; PR4548 define i8 @udiv_i8(i8 %a, i8 %b) { ; CHECK-LABEL: @udiv_i8( -; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i8 %a, %b ; CHECK-NEXT: ret i8 [[DIV]] ; %za = zext i8 %a to i32 %zb = zext i8 %b to i32 - %udiv = udiv i32 %za, %zb + %udiv = udiv nof i32 %za, %zb %conv3 = trunc i32 %udiv to i8 ret i8 %conv3 } define <2 x i8> @udiv_i8_vec(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @udiv_i8_vec( -; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i8> %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof <2 x i8> %a, %b ; CHECK-NEXT: ret <2 x i8> [[DIV]] ; %za = zext <2 x i8> %a to <2 x i32> %zb = zext <2 x i8> %b to <2 x i32> - %udiv = udiv <2 x i32> %za, %zb + %udiv = udiv nof <2 x i32> %za, %zb %conv3 = trunc <2 x i32> %udiv to <2 x i8> ret <2 x i8> %conv3 } @@ -53,25 +53,25 @@ define i32 @udiv_i32(i8 %a, i8 %b) { ; CHECK-LABEL: @udiv_i32( -; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i8 %a, %b ; CHECK-NEXT: [[UDIV:%.*]] = zext i8 [[DIV]] to i32 ; CHECK-NEXT: ret i32 [[UDIV]] ; %za = zext i8 %a to i32 %zb = zext i8 %b to i32 - %udiv = udiv i32 %za, %zb + %udiv = udiv nof i32 %za, %zb ret i32 %udiv } define <2 x i32> @udiv_i32_vec(<2 x i8> %a, <2 x i8> %b) { ; CHECK-LABEL: @udiv_i32_vec( -; CHECK-NEXT: [[DIV:%.*]] = udiv <2 x i8> %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof <2 x i8> %a, %b ; CHECK-NEXT: [[UDIV:%.*]] = zext <2 x i8> [[DIV]] to <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[UDIV]] ; %za = zext <2 x i8> %a to <2 x i32> %zb = zext <2 x i8> %b to <2 x i32> - %udiv = udiv <2 x i32> %za, %zb + %udiv = udiv nof <2 x i32> %za, %zb ret <2 x i32> %udiv } @@ -79,14 +79,14 @@ ; CHECK-LABEL: @udiv_i32_multiuse( ; CHECK-NEXT: [[ZA:%.*]] = zext i8 %a to i32 ; CHECK-NEXT: [[ZB:%.*]] = zext i8 %b to i32 -; CHECK-NEXT: [[UDIV:%.*]] = udiv i32 [[ZA]], [[ZB]] +; CHECK-NEXT: [[UDIV:%.*]] = udiv nof i32 [[ZA]], [[ZB]] ; CHECK-NEXT: [[EXTRA_USES:%.*]] = add nuw nsw i32 [[ZA]], [[ZB]] ; CHECK-NEXT: [[R:%.*]] = mul nuw nsw i32 [[UDIV]], [[EXTRA_USES]] ; CHECK-NEXT: ret i32 [[R]] ; %za = zext i8 %a to i32 %zb = zext i8 %b to i32 - %udiv = udiv i32 %za, %zb + %udiv = udiv nof i32 %za, %zb %extra_uses = add i32 %za, %zb %r = mul i32 %udiv, %extra_uses ret i32 %r @@ -94,13 +94,13 @@ define i32 @udiv_illegal_type(i9 %a, i9 %b) { ; CHECK-LABEL: @udiv_illegal_type( -; CHECK-NEXT: [[DIV:%.*]] = udiv i9 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i9 %a, %b ; CHECK-NEXT: [[UDIV:%.*]] = zext i9 [[DIV]] to i32 ; CHECK-NEXT: ret i32 [[UDIV]] ; %za = zext i9 %a to i32 %zb = zext i9 %b to i32 - %udiv = udiv i32 %za, %zb + %udiv = udiv nof i32 %za, %zb ret i32 %udiv } @@ -159,47 +159,47 @@ define i32 @udiv_i32_c(i8 %a) { ; CHECK-LABEL: @udiv_i32_c( -; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, 10 +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i8 %a, 10 ; CHECK-NEXT: [[UDIV:%.*]] = zext i8 [[DIV]] to i32 ; CHECK-NEXT: ret i32 [[UDIV]] ; %za = zext i8 %a to i32 - %udiv = udiv i32 %za, 10 + %udiv = udiv nof i32 %za, 10 ret i32 %udiv } define <2 x i32> @udiv_i32_c_vec(<2 x i8> %a) { ; CHECK-LABEL: @udiv_i32_c_vec( -; CHECK-NEXT: [[TMP1:%.*]] = udiv <2 x i8> %a, +; CHECK-NEXT: [[TMP1:%.*]] = udiv nof <2 x i8> %a, ; CHECK-NEXT: [[UDIV:%.*]] = zext <2 x i8> [[TMP1]] to <2 x i32> ; CHECK-NEXT: ret <2 x i32> [[UDIV]] ; %za = zext <2 x i8> %a to <2 x i32> - %udiv = udiv <2 x i32> %za, + %udiv = udiv nof <2 x i32> %za, ret <2 x i32> %udiv } define i32 @udiv_i32_c_multiuse(i8 %a) { ; CHECK-LABEL: @udiv_i32_c_multiuse( ; CHECK-NEXT: [[ZA:%.*]] = zext i8 %a to i32 -; CHECK-NEXT: [[UDIV:%.*]] = udiv i32 [[ZA]], 10 +; CHECK-NEXT: [[UDIV:%.*]] = udiv nof i32 [[ZA]], 10 ; CHECK-NEXT: [[EXTRA_USE:%.*]] = add nuw nsw i32 [[UDIV]], [[ZA]] ; CHECK-NEXT: ret i32 [[EXTRA_USE]] ; %za = zext i8 %a to i32 - %udiv = udiv i32 %za, 10 + %udiv = udiv nof i32 %za, 10 %extra_use = add i32 %za, %udiv ret i32 %extra_use } define i32 @udiv_illegal_type_c(i9 %a) { ; CHECK-LABEL: @udiv_illegal_type_c( -; CHECK-NEXT: [[DIV:%.*]] = udiv i9 %a, 10 +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i9 %a, 10 ; CHECK-NEXT: [[UDIV:%.*]] = zext i9 [[DIV]] to i32 ; CHECK-NEXT: ret i32 [[UDIV]] ; %za = zext i9 %a to i32 - %udiv = udiv i32 %za, 10 + %udiv = udiv nof i32 %za, 10 ret i32 %udiv } @@ -251,12 +251,12 @@ define i32 @udiv_c_i32(i8 %a) { ; CHECK-LABEL: @udiv_c_i32( -; CHECK-NEXT: [[TMP1:%.*]] = udiv i8 10, %a +; CHECK-NEXT: [[TMP1:%.*]] = udiv nof i8 10, %a ; CHECK-NEXT: [[UDIV:%.*]] = zext i8 [[TMP1]] to i32 ; CHECK-NEXT: ret i32 [[UDIV]] ; %za = zext i8 %a to i32 - %udiv = udiv i32 10, %za + %udiv = udiv nof i32 10, %za ret i32 %udiv } @@ -277,12 +277,12 @@ define i32 @udiv_constexpr(i8 %a) { ; CHECK-LABEL: @udiv_constexpr( -; CHECK-NEXT: [[TMP1:%.*]] = udiv i8 %a, ptrtoint ([1 x i8]* @b to i8) +; CHECK-NEXT: [[TMP1:%.*]] = udiv nof i8 %a, ptrtoint ([1 x i8]* @b to i8) ; CHECK-NEXT: [[D:%.*]] = zext i8 [[TMP1]] to i32 ; CHECK-NEXT: ret i32 [[D]] ; %za = zext i8 %a to i32 - %d = udiv i32 %za, zext (i8 ptrtoint ([1 x i8]* @b to i8) to i32) + %d = udiv nof i32 %za, zext (i8 ptrtoint ([1 x i8]* @b to i8) to i32) ret i32 %d } Index: test/Transforms/InstSimplify/compare.ll =================================================================== --- test/Transforms/InstSimplify/compare.ll +++ test/Transforms/InstSimplify/compare.ll @@ -580,20 +580,20 @@ ; CHECK-LABEL: @udiv2( ; CHECK-NEXT: ret i1 true ; - %A = udiv exact i32 10, %Z - %B = udiv exact i32 20, %Z + %A = udiv exact nof i32 10, %Z + %B = udiv exact nof i32 20, %Z %C = icmp ult i32 %A, %B ret i1 %C } -; Exact sdiv and equality preds can simplify. +; Exact sdiv nof and equality preds can simplify. define i1 @sdiv_exact_equality(i32 %Z) { ; CHECK-LABEL: @sdiv_exact_equality( ; CHECK-NEXT: ret i1 false ; - %A = sdiv exact i32 10, %Z - %B = sdiv exact i32 20, %Z + %A = sdiv exact nof i32 10, %Z + %B = sdiv exact nof i32 20, %Z %C = icmp eq i32 %A, %B ret i1 %C } @@ -602,20 +602,20 @@ define i1 @sdiv_exact_not_equality(i32 %Z) { ; CHECK-LABEL: @sdiv_exact_not_equality( -; CHECK-NEXT: [[A:%.*]] = sdiv exact i32 10, %Z -; CHECK-NEXT: [[B:%.*]] = sdiv exact i32 20, %Z +; CHECK-NEXT: [[A:%.*]] = sdiv exact nof i32 10, %Z +; CHECK-NEXT: [[B:%.*]] = sdiv exact nof i32 20, %Z ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]] ; CHECK-NEXT: ret i1 [[C]] ; - %A = sdiv exact i32 10, %Z - %B = sdiv exact i32 20, %Z + %A = sdiv exact nof i32 10, %Z + %B = sdiv exact nof i32 20, %Z %C = icmp ult i32 %A, %B ret i1 %C } define i1 @udiv3(i32 %X, i32 %Y) { ; CHECK-LABEL: @udiv3( - %A = udiv i32 %X, %Y + %A = udiv nof i32 %X, %Y %C = icmp ugt i32 %A, %X ret i1 %C ; CHECK: ret i1 false @@ -623,7 +623,7 @@ define i1 @udiv4(i32 %X, i32 %Y) { ; CHECK-LABEL: @udiv4( - %A = udiv i32 %X, %Y + %A = udiv nof i32 %X, %Y %C = icmp ule i32 %A, %X ret i1 %C ; CHECK: ret i1 true @@ -632,7 +632,7 @@ ; PR11340 define i1 @udiv6(i32 %X) nounwind { ; CHECK-LABEL: @udiv6( - %A = udiv i32 1, %X + %A = udiv nof i32 1, %X %C = icmp eq i32 %A, 0 ret i1 %C ; CHECK: ret i1 %C @@ -640,7 +640,7 @@ define i1 @udiv7(i32 %X, i32 %Y) { ; CHECK-LABEL: @udiv7( - %A = udiv i32 %X, %Y + %A = udiv nof i32 %X, %Y %C = icmp ult i32 %X, %A ret i1 %C ; CHECK: ret i1 false @@ -648,7 +648,7 @@ define i1 @udiv8(i32 %X, i32 %Y) { ; CHECK-LABEL: @udiv8( - %A = udiv i32 %X, %Y + %A = udiv nof i32 %X, %Y %C = icmp uge i32 %X, %A ret i1 %C ; CHECK: ret i1 true @@ -970,34 +970,34 @@ } define i1 @icmp_sdiv_int_min(i32 %a) { - %div = sdiv i32 -2147483648, %a + %div = sdiv nof i32 -2147483648, %a %cmp = icmp ne i32 %div, -1073741824 ret i1 %cmp ; CHECK-LABEL: @icmp_sdiv_int_min -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 -2147483648, %a +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 -2147483648, %a ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[DIV]], -1073741824 ; CHECK-NEXT: ret i1 [[CMP]] } define i1 @icmp_sdiv_pr20288(i64 %a) { - %div = sdiv i64 %a, -8589934592 + %div = sdiv nof i64 %a, -8589934592 %cmp = icmp ne i64 %div, 1073741824 ret i1 %cmp ; CHECK-LABEL: @icmp_sdiv_pr20288 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 %a, -8589934592 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i64 %a, -8589934592 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[DIV]], 1073741824 ; CHECK-NEXT: ret i1 [[CMP]] } define i1 @icmp_sdiv_neg1(i64 %a) { - %div = sdiv i64 %a, -1 + %div = sdiv nof i64 %a, -1 %cmp = icmp ne i64 %div, 1073741824 ret i1 %cmp ; CHECK-LABEL: @icmp_sdiv_neg1 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 %a, -1 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i64 %a, -1 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i64 [[DIV]], 1073741824 ; CHECK-NEXT: ret i1 [[CMP]] } Index: test/Transforms/InstSimplify/div.ll =================================================================== --- test/Transforms/InstSimplify/div.ll +++ test/Transforms/InstSimplify/div.ll @@ -6,7 +6,7 @@ ; CHECK-LABEL: @sdiv_zero_elt_vec_constfold( ; CHECK-NEXT: ret <2 x i8> undef ; - %div = sdiv <2 x i8> , + %div = sdiv nof <2 x i8> , ret <2 x i8> %div } @@ -14,7 +14,7 @@ ; CHECK-LABEL: @udiv_zero_elt_vec_constfold( ; CHECK-NEXT: ret <2 x i8> undef ; - %div = udiv <2 x i8> , + %div = udiv nof <2 x i8> , ret <2 x i8> %div } @@ -22,7 +22,7 @@ ; CHECK-LABEL: @sdiv_zero_elt_vec( ; CHECK-NEXT: ret <2 x i8> undef ; - %div = sdiv <2 x i8> %x, + %div = sdiv nof <2 x i8> %x, ret <2 x i8> %div } @@ -30,7 +30,7 @@ ; CHECK-LABEL: @udiv_zero_elt_vec( ; CHECK-NEXT: ret <2 x i8> undef ; - %div = udiv <2 x i8> %x, + %div = udiv nof <2 x i8> %x, ret <2 x i8> %div } @@ -58,7 +58,7 @@ ; CHECK-LABEL: @sdiv_bool_vec( ; CHECK-NEXT: ret <2 x i1> %x ; - %div = sdiv <2 x i1> %x, %y + %div = sdiv nof <2 x i1> %x, %y ret <2 x i1> %div } @@ -66,7 +66,7 @@ ; CHECK-LABEL: @udiv_bool_vec( ; CHECK-NEXT: ret <2 x i1> %x ; - %div = udiv <2 x i1> %x, %y + %div = udiv nof <2 x i1> %x, %y ret <2 x i1> %div } @@ -75,18 +75,18 @@ ; CHECK-NEXT: ret i32 0 ; %and = and i32 %x, 250 - %div = udiv i32 %and, 251 + %div = udiv nof i32 %and, 251 ret i32 %div } define i32 @not_udiv_dividend_known_smaller_than_constant_divisor(i32 %x) { ; CHECK-LABEL: @not_udiv_dividend_known_smaller_than_constant_divisor( ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 251 -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[AND]], 251 +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 [[AND]], 251 ; CHECK-NEXT: ret i32 [[DIV]] ; %and = and i32 %x, 251 - %div = udiv i32 %and, 251 + %div = udiv nof i32 %and, 251 ret i32 %div } @@ -95,18 +95,18 @@ ; CHECK-NEXT: ret i32 0 ; %or = or i32 %x, 251 - %div = udiv i32 250, %or + %div = udiv nof i32 250, %or ret i32 %div } define i32 @not_udiv_constant_dividend_known_smaller_than_divisor(i32 %x) { ; CHECK-LABEL: @not_udiv_constant_dividend_known_smaller_than_divisor( ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, 251 -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 251, [[OR]] +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 251, [[OR]] ; CHECK-NEXT: ret i32 [[DIV]] ; %or = or i32 %x, 251 - %div = udiv i32 251, %or + %div = udiv nof i32 251, %or ret i32 %div } @@ -116,12 +116,12 @@ ; CHECK-LABEL: @udiv_dividend_known_smaller_than_divisor( ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 250 ; CHECK-NEXT: [[OR:%.*]] = or i32 %y, 251 -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[AND]], [[OR]] +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 [[AND]], [[OR]] ; CHECK-NEXT: ret i32 [[DIV]] ; %and = and i32 %x, 250 %or = or i32 %y, 251 - %div = udiv i32 %and, %or + %div = udiv nof i32 %and, %or ret i32 %div } @@ -129,12 +129,12 @@ ; CHECK-LABEL: @not_udiv_dividend_known_smaller_than_divisor( ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 251 ; CHECK-NEXT: [[OR:%.*]] = or i32 %y, 251 -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[AND]], [[OR]] +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 [[AND]], [[OR]] ; CHECK-NEXT: ret i32 [[DIV]] ; %and = and i32 %x, 251 %or = or i32 %y, 251 - %div = udiv i32 %and, %or + %div = udiv nof i32 %and, %or ret i32 %div } @@ -146,7 +146,7 @@ ; CHECK-NEXT: ret i32 0 ; %call = call i32 @external(), !range !0 - %urem = udiv i32 %call, 3 + %urem = udiv nof i32 %call, 3 ret i32 %urem } Index: test/Transforms/InstSimplify/reassociate.ll =================================================================== --- test/Transforms/InstSimplify/reassociate.ll +++ test/Transforms/InstSimplify/reassociate.ll @@ -113,7 +113,7 @@ ; CHECK-NEXT: ret i32 [[X:%.*]] ; %mul = mul nsw i32 %x, %y - %r = sdiv i32 %mul, %y + %r = sdiv nof i32 %mul, %y ret i32 %r } @@ -122,7 +122,7 @@ ; CHECK-NEXT: ret <2 x i32> [[X:%.*]] ; %mul = mul nsw <2 x i32> %y, %x - %r = sdiv <2 x i32> %mul, %y + %r = sdiv nof <2 x i32> %mul, %y ret <2 x i32> %r } @@ -133,7 +133,7 @@ ; CHECK-NEXT: ret <2 x i8> [[X:%.*]] ; %mul = mul nuw <2 x i8> %x, %y - %r = udiv <2 x i8> %mul, %y + %r = udiv nof <2 x i8> %mul, %y ret <2 x i8> %r } @@ -142,7 +142,7 @@ ; CHECK-NEXT: ret i32 [[X:%.*]] ; %mul = mul nuw i32 %y, %x - %r = udiv i32 %mul, %y + %r = udiv nof i32 %mul, %y ret i32 %r } @@ -150,23 +150,23 @@ define i32 @sdiv_mul_sdiv(i32 %x, i32 %y) { ; CHECK-LABEL: @sdiv_mul_sdiv( -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: ret i32 [[DIV]] ; - %div = sdiv i32 %x, %y + %div = sdiv nof i32 %x, %y %mul = mul i32 %div, %y - %r = sdiv i32 %mul, %y + %r = sdiv nof i32 %mul, %y ret i32 %r } define i32 @sdiv_mul_sdiv_commute(i32 %x, i32 %y) { ; CHECK-LABEL: @sdiv_mul_sdiv_commute( -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: ret i32 [[DIV]] ; - %div = sdiv i32 %x, %y + %div = sdiv nof i32 %x, %y %mul = mul i32 %y, %div - %r = sdiv i32 %mul, %y + %r = sdiv nof i32 %mul, %y ret i32 %r } @@ -174,23 +174,23 @@ define i32 @udiv_mul_udiv(i32 %x, i32 %y) { ; CHECK-LABEL: @udiv_mul_udiv( -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: ret i32 [[DIV]] ; - %div = udiv i32 %x, %y + %div = udiv nof i32 %x, %y %mul = mul i32 %div, %y - %r = udiv i32 %mul, %y + %r = udiv nof i32 %mul, %y ret i32 %r } define i32 @udiv_mul_udiv_commute(i32 %x, i32 %y) { ; CHECK-LABEL: @udiv_mul_udiv_commute( -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: ret i32 [[DIV]] ; - %div = udiv i32 %x, %y + %div = udiv nof i32 %x, %y %mul = mul i32 %y, %div - %r = udiv i32 %mul, %y + %r = udiv nof i32 %mul, %y ret i32 %r } @@ -200,7 +200,7 @@ ; ; (X rem Y) / Y -> 0 %rem = srem i32 %x, %y - %div = sdiv i32 %rem, %y + %div = sdiv nof i32 %rem, %y ret i32 %div } @@ -209,7 +209,7 @@ ; CHECK-NEXT: ret i32 [[X:%.*]] ; ; (X / Y) * Y -> X if the division is exact - %div = sdiv exact i32 %x, %y + %div = sdiv exact nof i32 %x, %y %mul = mul i32 %div, %y ret i32 %mul } @@ -219,7 +219,7 @@ ; CHECK-NEXT: ret i32 [[X:%.*]] ; ; Y * (X / Y) -> X if the division is exact - %div = sdiv exact i32 %x, %y + %div = sdiv exact nof i32 %x, %y %mul = mul i32 %y, %div ret i32 %mul } @@ -230,7 +230,7 @@ ; ; (X rem Y) / Y -> 0 %rem = urem i32 %x, %y - %div = udiv i32 %rem, %y + %div = udiv nof i32 %rem, %y ret i32 %div } @@ -239,7 +239,7 @@ ; CHECK-NEXT: ret i32 [[X:%.*]] ; ; (X / Y) * Y -> X if the division is exact - %div = udiv exact i32 %x, %y + %div = udiv exact nof i32 %x, %y %mul = mul i32 %div, %y ret i32 %mul } @@ -249,7 +249,7 @@ ; CHECK-NEXT: ret i32 [[X:%.*]] ; ; Y * (X / Y) -> X if the division is exact - %div = udiv exact i32 %x, %y + %div = udiv exact nof i32 %x, %y %mul = mul i32 %y, %div ret i32 %mul } Index: test/Transforms/InstSimplify/signed-div-rem.ll =================================================================== --- test/Transforms/InstSimplify/signed-div-rem.ll +++ test/Transforms/InstSimplify/signed-div-rem.ll @@ -5,18 +5,18 @@ ; CHECK-NEXT: ret i32 0 ; %conv = sext i8 %x to i32 - %div = sdiv i32 %conv, 129 + %div = sdiv nof i32 %conv, 129 ret i32 %div } define i32 @not_sdiv_sext_big_divisor(i8 %x) { ; CHECK-LABEL: @not_sdiv_sext_big_divisor( ; CHECK-NEXT: [[CONV:%.*]] = sext i8 %x to i32 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 128 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[CONV]], 128 ; CHECK-NEXT: ret i32 [[DIV]] ; %conv = sext i8 %x to i32 - %div = sdiv i32 %conv, 128 + %div = sdiv nof i32 %conv, 128 ret i32 %div } @@ -25,18 +25,18 @@ ; CHECK-NEXT: ret i32 0 ; %conv = sext i8 %x to i32 - %div = sdiv i32 %conv, -129 + %div = sdiv nof i32 %conv, -129 ret i32 %div } define i32 @not_sdiv_sext_small_divisor(i8 %x) { ; CHECK-LABEL: @not_sdiv_sext_small_divisor( ; CHECK-NEXT: [[CONV:%.*]] = sext i8 %x to i32 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], -128 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[CONV]], -128 ; CHECK-NEXT: ret i32 [[DIV]] ; %conv = sext i8 %x to i32 - %div = sdiv i32 %conv, -128 + %div = sdiv nof i32 %conv, -128 ret i32 %div } @@ -45,18 +45,18 @@ ; CHECK-NEXT: ret i32 0 ; %conv = zext i8 %x to i32 - %div = sdiv i32 %conv, 256 + %div = sdiv nof i32 %conv, 256 ret i32 %div } define i32 @not_sdiv_zext_big_divisor(i8 %x) { ; CHECK-LABEL: @not_sdiv_zext_big_divisor( ; CHECK-NEXT: [[CONV:%.*]] = zext i8 %x to i32 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], 255 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[CONV]], 255 ; CHECK-NEXT: ret i32 [[DIV]] ; %conv = zext i8 %x to i32 - %div = sdiv i32 %conv, 255 + %div = sdiv nof i32 %conv, 255 ret i32 %div } @@ -65,18 +65,18 @@ ; CHECK-NEXT: ret i32 0 ; %conv = zext i8 %x to i32 - %div = sdiv i32 %conv, -256 + %div = sdiv nof i32 %conv, -256 ret i32 %div } define i32 @not_sdiv_zext_small_divisor(i8 %x) { ; CHECK-LABEL: @not_sdiv_zext_small_divisor( ; CHECK-NEXT: [[CONV:%.*]] = zext i8 %x to i32 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[CONV]], -255 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[CONV]], -255 ; CHECK-NEXT: ret i32 [[DIV]] ; %conv = zext i8 %x to i32 - %div = sdiv i32 %conv, -255 + %div = sdiv nof i32 %conv, -255 ret i32 %div } @@ -85,18 +85,18 @@ ; CHECK-NEXT: ret i32 0 ; %and = and i32 %x, 253 - %div = sdiv i32 %and, 254 + %div = sdiv nof i32 %and, 254 ret i32 %div } define i32 @not_sdiv_dividend_known_smaller_than_pos_divisor_clear_bits(i32 %x) { ; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_pos_divisor_clear_bits( ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 253 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[AND]], 253 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[AND]], 253 ; CHECK-NEXT: ret i32 [[DIV]] ; %and = and i32 %x, 253 - %div = sdiv i32 %and, 253 + %div = sdiv nof i32 %and, 253 ret i32 %div } @@ -105,18 +105,18 @@ ; CHECK-NEXT: ret i32 0 ; %and = and i32 %x, 253 - %div = sdiv i32 %and, -254 + %div = sdiv nof i32 %and, -254 ret i32 %div } define i32 @not_sdiv_dividend_known_smaller_than_neg_divisor_clear_bits(i32 %x) { ; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_neg_divisor_clear_bits( ; CHECK-NEXT: [[AND:%.*]] = and i32 %x, 253 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[AND]], -253 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[AND]], -253 ; CHECK-NEXT: ret i32 [[DIV]] ; %and = and i32 %x, 253 - %div = sdiv i32 %and, -253 + %div = sdiv nof i32 %and, -253 ret i32 %div } @@ -125,18 +125,18 @@ ; CHECK-NEXT: ret i32 0 ; %or = or i32 %x, -253 - %div = sdiv i32 %or, 254 + %div = sdiv nof i32 %or, 254 ret i32 %div } define i32 @not_sdiv_dividend_known_smaller_than_pos_divisor_set_bits(i32 %x) { ; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_pos_divisor_set_bits( ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, -253 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[OR]], 253 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[OR]], 253 ; CHECK-NEXT: ret i32 [[DIV]] ; %or = or i32 %x, -253 - %div = sdiv i32 %or, 253 + %div = sdiv nof i32 %or, 253 ret i32 %div } @@ -145,18 +145,18 @@ ; CHECK-NEXT: ret i32 0 ; %or = or i32 %x, -253 - %div = sdiv i32 %or, -254 + %div = sdiv nof i32 %or, -254 ret i32 %div } define i32 @not_sdiv_dividend_known_smaller_than_neg_divisor_set_bits(i32 %x) { ; CHECK-LABEL: @not_sdiv_dividend_known_smaller_than_neg_divisor_set_bits( ; CHECK-NEXT: [[OR:%.*]] = or i32 %x, -253 -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[OR]], -253 +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 [[OR]], -253 ; CHECK-NEXT: ret i32 [[DIV]] ; %or = or i32 %x, -253 - %div = sdiv i32 %or, -253 + %div = sdiv nof i32 %or, -253 ret i32 %div } @@ -333,11 +333,11 @@ define i16 @sdiv_min_dividend(i8 %x) { ; CHECK-LABEL: @sdiv_min_dividend( ; CHECK-NEXT: [[Z:%.*]] = zext i8 %x to i16 -; CHECK-NEXT: [[D:%.*]] = sdiv i16 -32768, [[Z]] +; CHECK-NEXT: [[D:%.*]] = sdiv nof i16 -32768, [[Z]] ; CHECK-NEXT: ret i16 [[D]] ; %z = zext i8 %x to i16 - %d = sdiv i16 -32768, %z + %d = sdiv nof i16 -32768, %z ret i16 %d } @@ -348,7 +348,7 @@ ; CHECK-NEXT: ret i16 0 ; %z = zext i8 %x to i16 - %d = sdiv i16 %z, -32768 + %d = sdiv nof i16 %z, -32768 ret i16 %d } Index: test/Transforms/LICM/hoist-nounwind.ll =================================================================== --- test/Transforms/LICM/hoist-nounwind.ll +++ test/Transforms/LICM/hoist-nounwind.ll @@ -35,11 +35,11 @@ br i1 %cmp4, label %for.body, label %for.cond.cleanup ; CHECK: tail call void @f() -; CHECK-NEXT: sdiv i32 +; CHECK-NEXT: sdiv nof i32 for.body: %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ] tail call void @f() nounwind - %div = sdiv i32 5, %c + %div = sdiv nof i32 5, %c %add = add i32 %i.05, 1 %inc = add i32 %add, %div %cmp = icmp slt i32 %inc, %N Index: test/Transforms/LICM/hoisting.ll =================================================================== --- test/Transforms/LICM/hoisting.ll +++ test/Transforms/LICM/hoisting.ll @@ -19,8 +19,8 @@ IfUnEqual: ; preds = %Loop ; CHECK: IfUnEqual: -; CHECK-NEXT: sdiv i32 4, %A - %B1 = sdiv i32 4, %A ; [#uses=1] +; CHECK-NEXT: sdiv nof i32 4, %A + %B1 = sdiv nof i32 4, %A ; [#uses=1] br label %LoopTail LoopTail: ; preds = %IfUnEqual, %Loop @@ -39,13 +39,13 @@ define i32 @test2(i1 %c) { ; CHECK-LABEL: @test2( ; CHECK-NEXT: load i32, i32* @X -; CHECK-NEXT: %B = sdiv i32 4, %A +; CHECK-NEXT: %B = sdiv nof i32 4, %A %A = load i32, i32* @X br label %Loop Loop: ;; Should have hoisted this div! - %B = sdiv i32 4, %A + %B = sdiv nof i32 4, %A br label %loop2 loop2: @@ -85,7 +85,7 @@ %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ] %n.01 = phi i32 [ 0, %entry ], [ %add, %for.body ] call void @foo_may_call_exit(i32 0) - %div = sdiv i32 %x, %y + %div = sdiv nof i32 %x, %y %add = add nsw i32 %n.01, %div %inc = add nsw i32 %i.02, 1 %cmp = icmp slt i32 %inc, 10000 Index: test/Transforms/LICM/preheader-safe.ll =================================================================== --- test/Transforms/LICM/preheader-safe.ll +++ test/Transforms/LICM/preheader-safe.ll @@ -7,14 +7,14 @@ define void @nothrow(i64 %x, i64 %y, i1* %cond) { ; CHECK-LABEL: nothrow ; CHECK-LABEL: entry -; CHECK: %div = udiv i64 %x, %y +; CHECK: %div = udiv nof i64 %x, %y ; CHECK-LABEL: loop ; CHECK: call void @use_nothrow(i64 %div) entry: br label %loop loop: ; preds = %entry, %for.inc - %div = udiv i64 %x, %y + %div = udiv nof i64 %x, %y br label %loop2 loop2: @@ -25,13 +25,13 @@ define void @throw_header(i64 %x, i64 %y, i1* %cond) { ; CHECK-LABEL: throw_header ; CHECK-LABEL: loop -; CHECK: %div = udiv i64 %x, %y +; CHECK: %div = udiv nof i64 %x, %y ; CHECK: call void @use(i64 %div) entry: br label %loop loop: ; preds = %entry, %for.inc - %div = udiv i64 %x, %y + %div = udiv nof i64 %x, %y call void @use(i64 %div) br label %loop } @@ -41,13 +41,13 @@ define void @nothrow_header(i64 %x, i64 %y, i1 %cond) { ; CHECK-LABEL: nothrow_header ; CHECK-LABEL: entry -; CHECK: %div = udiv i64 %x, %y +; CHECK: %div = udiv nof i64 %x, %y ; CHECK-LABEL: loop ; CHECK: call void @use(i64 %div) entry: br label %loop loop: ; preds = %entry, %for.inc - %div = udiv i64 %x, %y + %div = udiv nof i64 %x, %y br i1 %cond, label %loop-if, label %exit loop-if: call void @use(i64 %div) @@ -60,14 +60,14 @@ ; CHECK-LABEL: nothrow_header_neg ; CHECK-LABEL: entry ; CHECK-LABEL: loop -; CHECK: %div = udiv i64 %x, %y +; CHECK: %div = udiv nof i64 %x, %y ; CHECK: call void @use(i64 %div) entry: br label %loop loop: ; preds = %entry, %for.inc br label %loop-if loop-if: - %div = udiv i64 %x, %y + %div = udiv nof i64 %x, %y call void @use(i64 %div) br label %loop } Index: test/Transforms/LICM/sinking.ll =================================================================== --- test/Transforms/LICM/sinking.ll +++ test/Transforms/LICM/sinking.ll @@ -224,7 +224,7 @@ br label %Loop Loop: ; preds = %Loop, %Entry %N_addr.0.pn = phi i32 [ %dec, %Loop ], [ %N, %Entry ] ; [#uses=3] - %tmp.6 = sdiv i32 %N, %N_addr.0.pn ; [#uses=1] + %tmp.6 = sdiv nof i32 %N, %N_addr.0.pn ; [#uses=1] %dec = add i32 %N_addr.0.pn, -1 ; [#uses=1] %tmp.1 = icmp ne i32 %N_addr.0.pn, 0 ; [#uses=1] br i1 %tmp.1, label %Loop, label %Out @@ -234,7 +234,7 @@ ; CHECK-LABEL: @test10( ; CHECK: Out: ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn -; CHECK-NEXT: %tmp.6.le = sdiv i32 %N, %[[LCSSAPHI]] +; CHECK-NEXT: %tmp.6.le = sdiv nof i32 %N, %[[LCSSAPHI]] ; CHECK-NEXT: ret i32 %tmp.6.le } Index: test/Transforms/LICM/speculate.ll =================================================================== --- test/Transforms/LICM/speculate.ll +++ test/Transforms/LICM/speculate.ll @@ -4,7 +4,7 @@ ; UDiv is safe to speculate if the denominator is known non-zero. ; CHECK-LABEL: @safe_udiv( -; CHECK: %div = udiv i64 %x, 2 +; CHECK: %div = udiv nof i64 %x, 2 ; CHECK-NEXT: br label %for.body define void @safe_udiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { @@ -19,7 +19,7 @@ br i1 %tobool, label %for.inc, label %if.then if.then: ; preds = %for.body - %div = udiv i64 %x, 2 + %div = udiv nof i64 %x, 2 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02 store i64 %div, i64* %arrayidx1, align 8 br label %for.inc @@ -51,7 +51,7 @@ br i1 %tobool, label %for.inc, label %if.then if.then: ; preds = %for.body - %div = udiv i64 %x, %m + %div = udiv nof i64 %x, %m %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02 store i64 %div, i64* %arrayidx1, align 8 br label %for.inc @@ -69,7 +69,7 @@ ; known to have at least one zero bit. ; CHECK-LABEL: @safe_sdiv( -; CHECK: %div = sdiv i64 %x, 2 +; CHECK: %div = sdiv nof i64 %x, 2 ; CHECK-NEXT: br label %for.body define void @safe_sdiv(i64 %x, i64 %m, i64 %n, i32* %p, i64* %q) nounwind { @@ -85,7 +85,7 @@ br i1 %tobool, label %for.inc, label %if.then if.then: ; preds = %for.body - %div = sdiv i64 %x, 2 + %div = sdiv nof i64 %x, 2 %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02 store i64 %div, i64* %arrayidx1, align 8 br label %for.inc @@ -118,7 +118,7 @@ br i1 %tobool, label %for.inc, label %if.then if.then: ; preds = %for.body - %div = sdiv i64 %x, %or + %div = sdiv nof i64 %x, %or %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02 store i64 %div, i64* %arrayidx1, align 8 br label %for.inc @@ -151,7 +151,7 @@ br i1 %tobool, label %for.inc, label %if.then if.then: ; preds = %for.body - %div = sdiv i64 %x, %and + %div = sdiv nof i64 %x, %and %arrayidx1 = getelementptr inbounds i64, i64* %q, i64 %i.02 store i64 %div, i64* %arrayidx1, align 8 br label %for.inc @@ -179,7 +179,7 @@ br i1 %c, label %backedge, label %if.then if.then: - %d = sdiv i64 %a, %b + %d = sdiv nof i64 %a, %b store i64 %d, i64* %p br label %backedge Index: test/Transforms/LoopPredication/basic.ll =================================================================== --- test/Transforms/LoopPredication/basic.ll +++ test/Transforms/LoopPredication/basic.ll @@ -1004,12 +1004,12 @@ ; CHECK: loop: ; CHECK-NEXT: %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] ; CHECK-NEXT: %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] -; CHECK-NEXT: %length.udiv = udiv i32 %length, %divider +; CHECK-NEXT: %length.udiv = udiv nof i32 %length, %divider ; CHECK-NEXT: %within.bounds = icmp ult i32 %i, %length.udiv ; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] %loop.acc = phi i32 [ %loop.acc.next, %loop ], [ 0, %loop.preheader ] %i = phi i32 [ %i.next, %loop ], [ 0, %loop.preheader ] - %length.udiv = udiv i32 %length, %divider + %length.udiv = udiv nof i32 %length, %divider %within.bounds = icmp ult i32 %i, %length.udiv call void (i1, ...) @llvm.experimental.guard(i1 %within.bounds, i32 9) [ "deopt"() ] Index: test/Transforms/LoopVectorize/AArch64/aarch64-predication.ll =================================================================== --- test/Transforms/LoopVectorize/AArch64/aarch64-predication.ll +++ test/Transforms/LoopVectorize/AArch64/aarch64-predication.ll @@ -12,7 +12,7 @@ ; %tmp4 a lower scalarization overhead. ; ; COST-LABEL: predicated_udiv_scalarized_operand -; COST: LV: Found an estimated cost of 4 for VF 2 For instruction: %tmp4 = udiv i64 %tmp2, %tmp3 +; COST: LV: Found an estimated cost of 4 for VF 2 For instruction: %tmp4 = udiv nof i64 %tmp2, %tmp3 ; ; CHECK-LABEL: @predicated_udiv_scalarized_operand( ; CHECK: vector.body: @@ -28,7 +28,7 @@ ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[WIDE_LOAD]], i32 0 ; CHECK-NEXT: [[TMP5:%.*]] = add nsw i64 [[TMP4]], %x ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i64> [[WIDE_LOAD]], i32 0 -; CHECK-NEXT: [[TMP7:%.*]] = udiv i64 [[TMP6]], [[TMP5]] +; CHECK-NEXT: [[TMP7:%.*]] = udiv nof i64 [[TMP6]], [[TMP5]] ; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i64> undef, i64 [[TMP7]], i32 0 ; CHECK-NEXT: br label %[[PRED_UDIV_CONTINUE]] ; CHECK: [[PRED_UDIV_CONTINUE]]: @@ -39,7 +39,7 @@ ; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i64> [[WIDE_LOAD]], i32 1 ; CHECK-NEXT: [[TMP12:%.*]] = add nsw i64 [[TMP11]], %x ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i64> [[WIDE_LOAD]], i32 1 -; CHECK-NEXT: [[TMP14:%.*]] = udiv i64 [[TMP13]], [[TMP12]] +; CHECK-NEXT: [[TMP14:%.*]] = udiv nof i64 [[TMP13]], [[TMP12]] ; CHECK-NEXT: [[TMP15:%.*]] = insertelement <2 x i64> [[TMP9]], i64 [[TMP14]], i32 1 ; CHECK-NEXT: br label %[[PRED_UDIV_CONTINUE2]] ; CHECK: [[PRED_UDIV_CONTINUE2]]: @@ -63,7 +63,7 @@ if.then: %tmp3 = add nsw i64 %tmp2, %x - %tmp4 = udiv i64 %tmp2, %tmp3 + %tmp4 = udiv nof i64 %tmp2, %tmp3 br label %for.inc for.inc: Index: test/Transforms/LoopVectorize/AArch64/predication_costs.ll =================================================================== --- test/Transforms/LoopVectorize/AArch64/predication_costs.ll +++ test/Transforms/LoopVectorize/AArch64/predication_costs.ll @@ -18,8 +18,8 @@ ; Cost of udiv: ; (udiv(2) + extractelement(6) + insertelement(3)) / 2 = 5 ; -; CHECK: Scalarizing and predicating: %tmp4 = udiv i32 %tmp2, %tmp3 -; CHECK: Found an estimated cost of 5 for VF 2 For instruction: %tmp4 = udiv i32 %tmp2, %tmp3 +; CHECK: Scalarizing and predicating: %tmp4 = udiv nof i32 %tmp2, %tmp3 +; CHECK: Found an estimated cost of 5 for VF 2 For instruction: %tmp4 = udiv nof i32 %tmp2, %tmp3 ; define i32 @predicated_udiv(i32* %a, i32* %b, i1 %c, i64 %n) { entry: @@ -35,7 +35,7 @@ br i1 %c, label %if.then, label %for.inc if.then: - %tmp4 = udiv i32 %tmp2, %tmp3 + %tmp4 = udiv nof i32 %tmp2, %tmp3 br label %for.inc for.inc: @@ -99,9 +99,9 @@ ; (udiv(2) + extractelement(3) + insertelement(3)) / 2 = 4 ; ; CHECK: Scalarizing: %tmp3 = add nsw i32 %tmp2, %x -; CHECK: Scalarizing and predicating: %tmp4 = udiv i32 %tmp2, %tmp3 +; CHECK: Scalarizing and predicating: %tmp4 = udiv nof i32 %tmp2, %tmp3 ; CHECK: Found an estimated cost of 2 for VF 2 For instruction: %tmp3 = add nsw i32 %tmp2, %x -; CHECK: Found an estimated cost of 4 for VF 2 For instruction: %tmp4 = udiv i32 %tmp2, %tmp3 +; CHECK: Found an estimated cost of 4 for VF 2 For instruction: %tmp4 = udiv nof i32 %tmp2, %tmp3 ; define i32 @predicated_udiv_scalarized_operand(i32* %a, i1 %c, i32 %x, i64 %n) { entry: @@ -116,7 +116,7 @@ if.then: %tmp3 = add nsw i32 %tmp2, %x - %tmp4 = udiv i32 %tmp2, %tmp3 + %tmp4 = udiv nof i32 %tmp2, %tmp3 br label %for.inc for.inc: @@ -177,7 +177,7 @@ ; This test checks that we correctly compute the cost of multiple predicated ; instructions in the same block. The sdiv, udiv, and store must be scalarized ; and predicated. The sub feeding the store is scalarized and sunk inside the -; store's predicated block. However, the add feeding the sdiv and udiv cannot +; store's predicated block. However, the add feeding the sdiv nof and udiv nof cannot ; be sunk and is not scalarized. If we assume the block probability is 50%, we ; compute the cost as: ; @@ -193,13 +193,13 @@ ; store(4) / 2 = 2 ; ; CHECK-NOT: Scalarizing: %tmp2 = add i32 %tmp1, %x -; CHECK: Scalarizing and predicating: %tmp3 = sdiv i32 %tmp1, %tmp2 -; CHECK: Scalarizing and predicating: %tmp4 = udiv i32 %tmp3, %tmp2 +; CHECK: Scalarizing and predicating: %tmp3 = sdiv nof i32 %tmp1, %tmp2 +; CHECK: Scalarizing and predicating: %tmp4 = udiv nof i32 %tmp3, %tmp2 ; CHECK: Scalarizing: %tmp5 = sub i32 %tmp4, %x ; CHECK: Scalarizing and predicating: store i32 %tmp5, i32* %tmp0, align 4 ; CHECK: Found an estimated cost of 1 for VF 2 For instruction: %tmp2 = add i32 %tmp1, %x -; CHECK: Found an estimated cost of 5 for VF 2 For instruction: %tmp3 = sdiv i32 %tmp1, %tmp2 -; CHECK: Found an estimated cost of 5 for VF 2 For instruction: %tmp4 = udiv i32 %tmp3, %tmp2 +; CHECK: Found an estimated cost of 5 for VF 2 For instruction: %tmp3 = sdiv nof i32 %tmp1, %tmp2 +; CHECK: Found an estimated cost of 5 for VF 2 For instruction: %tmp4 = udiv nof i32 %tmp3, %tmp2 ; CHECK: Found an estimated cost of 2 for VF 2 For instruction: %tmp5 = sub i32 %tmp4, %x ; CHECK: Found an estimated cost of 2 for VF 2 For instruction: store i32 %tmp5, i32* %tmp0, align 4 ; @@ -215,8 +215,8 @@ if.then: %tmp2 = add i32 %tmp1, %x - %tmp3 = sdiv i32 %tmp1, %tmp2 - %tmp4 = udiv i32 %tmp3, %tmp2 + %tmp3 = sdiv nof i32 %tmp1, %tmp2 + %tmp4 = udiv nof i32 %tmp3, %tmp2 %tmp5 = sub i32 %tmp4, %x store i32 %tmp5, i32* %tmp0, align 4 br label %for.inc Index: test/Transforms/LoopVectorize/AArch64/sdiv-pow2.ll =================================================================== --- test/Transforms/LoopVectorize/AArch64/sdiv-pow2.ll +++ test/Transforms/LoopVectorize/AArch64/sdiv-pow2.ll @@ -8,7 +8,7 @@ ; CHECK-LABEL: @foo( ; CHECK: load <4 x i32>, <4 x i32>* -; CHECK: sdiv <4 x i32> +; CHECK: sdiv nof <4 x i32> ; CHECK: store <4 x i32> define void @foo(){ @@ -19,7 +19,7 @@ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] %arrayidx = getelementptr inbounds %struct.anon, %struct.anon* @Foo, i64 0, i32 2, i64 %indvars.iv %0 = load i32, i32* %arrayidx, align 4 - %div = sdiv i32 %0, 2 + %div = sdiv nof i32 %0, 2 %arrayidx2 = getelementptr inbounds %struct.anon, %struct.anon* @Foo, i64 0, i32 0, i64 %indvars.iv store i32 %div, i32* %arrayidx2, align 4 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 Index: test/Transforms/LoopVectorize/X86/powof2div.ll =================================================================== --- test/Transforms/LoopVectorize/X86/powof2div.ll +++ test/Transforms/LoopVectorize/X86/powof2div.ll @@ -8,7 +8,7 @@ ; CHECK-LABEL: @foo( ; CHECK: load <4 x i32>, <4 x i32>* -; CHECK: sdiv <4 x i32> +; CHECK: sdiv nof <4 x i32> ; CHECK: store <4 x i32> define void @foo(){ @@ -19,7 +19,7 @@ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] %arrayidx = getelementptr inbounds %struct.anon, %struct.anon* @Foo, i64 0, i32 2, i64 %indvars.iv %0 = load i32, i32* %arrayidx, align 4 - %div = sdiv i32 %0, 2 + %div = sdiv nof i32 %0, 2 %arrayidx2 = getelementptr inbounds %struct.anon, %struct.anon* @Foo, i64 0, i32 0, i64 %indvars.iv store i32 %div, i32* %arrayidx2, align 4 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 Index: test/Transforms/LoopVectorize/X86/x86-predication.ll =================================================================== --- test/Transforms/LoopVectorize/X86/x86-predication.ll +++ test/Transforms/LoopVectorize/X86/x86-predication.ll @@ -15,7 +15,7 @@ ; CHECK: br i1 {{.*}}, label %[[IF0:.+]], label %[[CONT0:.+]] ; CHECK: [[IF0]]: ; CHECK: %[[T0:.+]] = extractelement <2 x i32> %wide.masked.load, i32 0 -; CHECK: %[[T1:.+]] = sdiv i32 %[[T0]], %x +; CHECK: %[[T1:.+]] = sdiv nof i32 %[[T0]], %x ; CHECK: %[[T2:.+]] = insertelement <2 x i32> undef, i32 %[[T1]], i32 0 ; CHECK: br label %[[CONT0]] ; CHECK: [[CONT0]]: @@ -23,7 +23,7 @@ ; CHECK: br i1 {{.*}}, label %[[IF1:.+]], label %[[CONT1:.+]] ; CHECK: [[IF1]]: ; CHECK: %[[T4:.+]] = extractelement <2 x i32> %wide.masked.load, i32 1 -; CHECK: %[[T5:.+]] = sdiv i32 %[[T4]], %x +; CHECK: %[[T5:.+]] = sdiv nof i32 %[[T4]], %x ; CHECK: %[[T6:.+]] = insertelement <2 x i32> %[[T3]], i32 %[[T5]], i32 1 ; CHECK: br label %[[CONT1]] ; CHECK: [[CONT1]]: @@ -44,7 +44,7 @@ if.then: %tmp2 = getelementptr inbounds i32, i32* %b, i64 %i %tmp3 = load i32, i32* %tmp2, align 4 - %tmp4 = sdiv i32 %tmp3, %x + %tmp4 = sdiv nof i32 %tmp3, %x %tmp5 = add nsw i32 %tmp4, %tmp1 br label %for.inc @@ -67,7 +67,7 @@ ; SINK-GATHER: vector.body: ; SINK-GATHER: pred.udiv.if: ; SINK-GATHER: %[[T0:.+]] = load i32, i32* %{{.*}}, align 4 -; SINK-GATHER: %{{.*}} = udiv i32 %[[T0]], %{{.*}} +; SINK-GATHER: %{{.*}} = udiv nof i32 %[[T0]], %{{.*}} ; SINK-GATHER: pred.udiv.continue: define i32 @scalarize_and_sink_gather(i32* %a, i1 %c, i32 %x, i64 %n) { entry: @@ -82,7 +82,7 @@ if.then: %tmp0 = getelementptr inbounds i32, i32* %a, i64 %i7 %tmp2 = load i32, i32* %tmp0, align 4 - %tmp4 = udiv i32 %tmp2, %x + %tmp4 = udiv nof i32 %tmp2, %x br label %for.inc for.inc: Index: test/Transforms/LoopVectorize/if-pred-non-void.ll =================================================================== --- test/Transforms/LoopVectorize/if-pred-non-void.ll +++ test/Transforms/LoopVectorize/if-pred-non-void.ll @@ -23,7 +23,7 @@ ; CHECK: [[CSD]]: ; CHECK: %[[SDA0:[a-zA-Z0-9]+]] = extractelement <2 x i32> %{{.*}}, i32 0 ; CHECK: %[[SDA1:[a-zA-Z0-9]+]] = extractelement <2 x i32> %{{.*}}, i32 0 -; CHECK: %[[SD0:[a-zA-Z0-9]+]] = sdiv i32 %[[SDA0]], %[[SDA1]] +; CHECK: %[[SD0:[a-zA-Z0-9]+]] = sdiv nof i32 %[[SDA0]], %[[SDA1]] ; CHECK: %[[SD1:[a-zA-Z0-9]+]] = insertelement <2 x i32> undef, i32 %[[SD0]], i32 0 ; CHECK: br label %[[ESD]] ; CHECK: [[ESD]]: @@ -33,7 +33,7 @@ ; CHECK: [[CSDH]]: ; CHECK: %[[SDA0H:[a-zA-Z0-9]+]] = extractelement <2 x i32> %{{.*}}, i32 1 ; CHECK: %[[SDA1H:[a-zA-Z0-9]+]] = extractelement <2 x i32> %{{.*}}, i32 1 -; CHECK: %[[SD0H:[a-zA-Z0-9]+]] = sdiv i32 %[[SDA0H]], %[[SDA1H]] +; CHECK: %[[SD0H:[a-zA-Z0-9]+]] = sdiv nof i32 %[[SDA0H]], %[[SDA1H]] ; CHECK: %[[SD1H:[a-zA-Z0-9]+]] = insertelement <2 x i32> %[[SDR]], i32 %[[SD0H]], i32 1 ; CHECK: br label %[[ESDH]] ; CHECK: [[ESDH]]: @@ -44,7 +44,7 @@ ; CHECK: [[CUD]]: ; CHECK: %[[UDA0:[a-zA-Z0-9]+]] = extractelement <2 x i32> %{{.*}}, i32 0 ; CHECK: %[[UDA1:[a-zA-Z0-9]+]] = extractelement <2 x i32> %{{.*}}, i32 0 -; CHECK: %[[UD0:[a-zA-Z0-9]+]] = udiv i32 %[[UDA0]], %[[UDA1]] +; CHECK: %[[UD0:[a-zA-Z0-9]+]] = udiv nof i32 %[[UDA0]], %[[UDA1]] ; CHECK: %[[UD1:[a-zA-Z0-9]+]] = insertelement <2 x i32> undef, i32 %[[UD0]], i32 0 ; CHECK: br label %[[EUD]] ; CHECK: [[EUD]]: @@ -90,8 +90,8 @@ br i1 %cmp1, label %if.then, label %if.end if.then: ; preds = %for.body - %rsd = sdiv i32 %psd, %lsd - %rud = udiv i32 %pud, %lud + %rsd = sdiv nof i32 %psd, %lsd + %rud = udiv nof i32 %pud, %lud %rsr = srem i32 %psr, %lsr %rur = urem i32 %pur, %lur br label %if.end @@ -121,7 +121,7 @@ ; CHECK: vector.body: ; CHECK: br i1 %{{.*}}, label %[[THEN:[a-zA-Z0-9.]+]], label %[[FI:[a-zA-Z0-9.]+]] ; CHECK: [[THEN]]: -; CHECK: %[[PD:[a-zA-Z0-9]+]] = sdiv i32 %{{.*}}, %{{.*}} +; CHECK: %[[PD:[a-zA-Z0-9]+]] = sdiv nof i32 %{{.*}}, %{{.*}} ; CHECK: br label %[[FI]] ; CHECK: [[FI]]: ; CHECK: %{{.*}} = phi i32 [ undef, %vector.body ], [ %[[PD]], %[[THEN]] ] @@ -137,8 +137,8 @@ br i1 %cmp1, label %if.then, label %if.end if.then: ; preds = %for.body - %sd1 = sdiv i32 %psd, %lsd - %rsd = sdiv i32 %lsd.b, %sd1 + %sd1 = sdiv nof i32 %psd, %lsd + %rsd = sdiv nof i32 %lsd.b, %sd1 br label %if.end if.end: ; preds = %if.then, %for.body @@ -166,7 +166,7 @@ ; CHECK: %[[EXTRACT:.+]] = extractelement <2 x i1> %[[OR]], i32 0 ; CHECK: br i1 %[[EXTRACT]], label %[[THEN:[a-zA-Z0-9.]+]], label %[[FI:[a-zA-Z0-9.]+]] ; CHECK: [[THEN]]: -; CHECK: %[[PD:[a-zA-Z0-9]+]] = sdiv i32 %{{.*}}, %{{.*}} +; CHECK: %[[PD:[a-zA-Z0-9]+]] = sdiv nof i32 %{{.*}}, %{{.*}} ; CHECK: br label %[[FI]] ; CHECK: [[FI]]: ; CHECK: %{{.*}} = phi i32 [ undef, %vector.body ], [ %[[PD]], %[[THEN]] ] @@ -187,8 +187,8 @@ br i1 %cmp2, label %if.then, label %if.end if.then: ; preds = %check, %for.body - %sd1 = sdiv i32 %psd, %lsd - %rsd = sdiv i32 %lsd.b, %sd1 + %sd1 = sdiv nof i32 %psd, %lsd + %rsd = sdiv nof i32 %lsd.b, %sd1 br label %if.end if.end: ; preds = %if.then, %check @@ -212,7 +212,7 @@ ; CHECK: %[[T00:.+]] = extractelement <2 x i32> %wide.load, i32 0 ; CHECK: %[[T01:.+]] = add nsw i32 %[[T00]], %x ; CHECK: %[[T02:.+]] = extractelement <2 x i32> %wide.load, i32 0 -; CHECK: %[[T03:.+]] = udiv i32 %[[T02]], %[[T01]] +; CHECK: %[[T03:.+]] = udiv nof i32 %[[T02]], %[[T01]] ; CHECK: %[[T04:.+]] = insertelement <2 x i32> undef, i32 %[[T03]], i32 0 ; CHECK: br label %[[CONT0]] ; CHECK: [[CONT0]]: @@ -222,7 +222,7 @@ ; CHECK: %[[T06:.+]] = extractelement <2 x i32> %wide.load, i32 1 ; CHECK: %[[T07:.+]] = add nsw i32 %[[T06]], %x ; CHECK: %[[T08:.+]] = extractelement <2 x i32> %wide.load, i32 1 -; CHECK: %[[T09:.+]] = udiv i32 %[[T08]], %[[T07]] +; CHECK: %[[T09:.+]] = udiv nof i32 %[[T08]], %[[T07]] ; CHECK: %[[T10:.+]] = insertelement <2 x i32> %[[T05]], i32 %[[T09]], i32 1 ; CHECK: br label %[[CONT1]] ; CHECK: [[CONT1]]: @@ -239,14 +239,14 @@ ; UNROLL-NO-VF: br i1 {{.*}}, label %[[IF0:.+]], label %[[CONT0:.+]] ; UNROLL-NO-VF: [[IF0]]: ; UNROLL-NO-VF: %[[ADD0:.+]] = add nsw i32 %[[LOAD0]], %x -; UNROLL-NO-VF: %[[DIV0:.+]] = udiv i32 %[[LOAD0]], %[[ADD0]] +; UNROLL-NO-VF: %[[DIV0:.+]] = udiv nof i32 %[[LOAD0]], %[[ADD0]] ; UNROLL-NO-VF: br label %[[CONT0]] ; UNROLL-NO-VF: [[CONT0]]: ; UNROLL-NO-VF: phi i32 [ undef, %vector.body ], [ %[[DIV0]], %[[IF0]] ] ; UNROLL-NO-VF: br i1 {{.*}}, label %[[IF1:.+]], label %[[CONT1:.+]] ; UNROLL-NO-VF: [[IF1]]: ; UNROLL-NO-VF: %[[ADD1:.+]] = add nsw i32 %[[LOAD1]], %x -; UNROLL-NO-VF: %[[DIV1:.+]] = udiv i32 %[[LOAD1]], %[[ADD1]] +; UNROLL-NO-VF: %[[DIV1:.+]] = udiv nof i32 %[[LOAD1]], %[[ADD1]] ; UNROLL-NO-VF: br label %[[CONT1]] ; UNROLL-NO-VF: [[CONT1]]: ; UNROLL-NO-VF: phi i32 [ undef, %[[CONT0]] ], [ %[[DIV1]], %[[IF1]] ] @@ -261,7 +261,7 @@ if.then: %tmp3 = add nsw i32 %tmp2, %x - %tmp4 = udiv i32 %tmp2, %tmp3 + %tmp4 = udiv nof i32 %tmp2, %tmp3 br label %for.inc for.inc: Index: test/Transforms/LoopVectorize/if-pred-not-when-safe.ll =================================================================== --- test/Transforms/LoopVectorize/if-pred-not-when-safe.ll +++ test/Transforms/LoopVectorize/if-pred-not-when-safe.ll @@ -17,12 +17,12 @@ ; CHECK-LABEL: test ; CHECK: vector.body: -; CHECK: %{{.*}} = sdiv <2 x i32> %{{.*}}, -; CHECK: %{{.*}} = udiv <2 x i32> %{{.*}}, +; CHECK: %{{.*}} = sdiv nof <2 x i32> %{{.*}}, +; CHECK: %{{.*}} = udiv nof <2 x i32> %{{.*}}, ; CHECK: %{{.*}} = srem <2 x i32> %{{.*}}, ; CHECK: %{{.*}} = urem <2 x i32> %{{.*}}, -; CHECK-NOT: %{{.*}} = sdiv <2 x i32> %{{.*}}, -; CHECK-NOT: %{{.*}} = udiv <2 x i32> %{{.*}}, +; CHECK-NOT: %{{.*}} = sdiv nof <2 x i32> %{{.*}}, +; CHECK-NOT: %{{.*}} = udiv nof <2 x i32> %{{.*}}, ; CHECK-NOT: %{{.*}} = srem <2 x i32> %{{.*}}, ; CHECK-NOT: %{{.*}} = urem <2 x i32> %{{.*}}, @@ -56,12 +56,12 @@ br i1 %cmp1, label %if.then, label %if.end if.then: ; preds = %for.body - %rsd = sdiv i32 %psd, 11 - %rud = udiv i32 %pud, 13 + %rsd = sdiv nof i32 %psd, 11 + %rud = udiv nof i32 %pud, 13 %rsr = srem i32 %psr, 17 %rur = urem i32 %pur, 19 - %rsd0 = sdiv i32 %psd0, 0 - %rud0 = udiv i32 %pud0, 0 + %rsd0 = sdiv nof i32 %psd0, 0 + %rud0 = udiv nof i32 %pud0, 0 %rsr0 = srem i32 %psr0, 0 %rur0 = urem i32 %pur0, 0 br label %if.end Index: test/Transforms/LoopVectorize/induction.ll =================================================================== --- test/Transforms/LoopVectorize/induction.ll +++ test/Transforms/LoopVectorize/induction.ll @@ -297,7 +297,7 @@ ; PR30542. Ensure we generate all the scalar steps for the induction variable. ; The scalar induction variable is used by a getelementptr instruction -; (uniform), and a udiv (non-uniform). +; (uniform), and a udiv nof (non-uniform). ; ; int sum = 0; ; for (int i = 0; i < n; ++i) { @@ -313,10 +313,10 @@ ; CHECK: %[[I0:.+]] = add i32 %index, 0 ; CHECK: getelementptr inbounds i32, i32* %a, i32 %[[I0]] ; CHECK: pred.udiv.if: -; CHECK: udiv i32 {{.*}}, %[[I0]] +; CHECK: udiv nof i32 {{.*}}, %[[I0]] ; CHECK: pred.udiv.if{{[0-9]+}}: ; CHECK: %[[I1:.+]] = add i32 %index, 1 -; CHECK: udiv i32 {{.*}}, %[[I1]] +; CHECK: udiv nof i32 {{.*}}, %[[I1]] ; ; UNROLL-NO_IC-LABEL: @scalarize_induction_variable_05( ; UNROLL-NO-IC: vector.body: @@ -326,15 +326,15 @@ ; UNROLL-NO-IC: getelementptr inbounds i32, i32* %a, i32 %[[I0]] ; UNROLL-NO-IC: getelementptr inbounds i32, i32* %a, i32 %[[I2]] ; UNROLL-NO-IC: pred.udiv.if: -; UNROLL-NO-IC: udiv i32 {{.*}}, %[[I0]] +; UNROLL-NO-IC: udiv nof i32 {{.*}}, %[[I0]] ; UNROLL-NO-IC: pred.udiv.if{{[0-9]+}}: ; UNROLL-NO-IC: %[[I1:.+]] = add i32 %index, 1 -; UNROLL-NO-IC: udiv i32 {{.*}}, %[[I1]] +; UNROLL-NO-IC: udiv nof i32 {{.*}}, %[[I1]] ; UNROLL-NO-IC: pred.udiv.if{{[0-9]+}}: -; UNROLL-NO-IC: udiv i32 {{.*}}, %[[I2]] +; UNROLL-NO-IC: udiv nof i32 {{.*}}, %[[I2]] ; UNROLL-NO-IC: pred.udiv.if{{[0-9]+}}: ; UNROLL-NO-IC: %[[I3:.+]] = add i32 %index, 3 -; UNROLL-NO-IC: udiv i32 {{.*}}, %[[I3]] +; UNROLL-NO-IC: udiv nof i32 {{.*}}, %[[I3]] ; ; IND-LABEL: @scalarize_induction_variable_05( ; IND: vector.body: @@ -342,10 +342,10 @@ ; IND: %[[E0:.+]] = sext i32 %index to i64 ; IND: getelementptr inbounds i32, i32* %a, i64 %[[E0]] ; IND: pred.udiv.if: -; IND: udiv i32 {{.*}}, %index +; IND: udiv nof i32 {{.*}}, %index ; IND: pred.udiv.if{{[0-9]+}}: ; IND: %[[I1:.+]] = or i32 %index, 1 -; IND: udiv i32 {{.*}}, %[[I1]] +; IND: udiv nof i32 {{.*}}, %[[I1]] ; ; UNROLL-LABEL: @scalarize_induction_variable_05( ; UNROLL: vector.body: @@ -355,15 +355,15 @@ ; UNROLL: %[[G0:.+]] = getelementptr inbounds i32, i32* %a, i64 %[[E0]] ; UNROLL: getelementptr i32, i32* %[[G0]], i64 2 ; UNROLL: pred.udiv.if: -; UNROLL: udiv i32 {{.*}}, %index +; UNROLL: udiv nof i32 {{.*}}, %index ; UNROLL: pred.udiv.if{{[0-9]+}}: ; UNROLL: %[[I1:.+]] = or i32 %index, 1 -; UNROLL: udiv i32 {{.*}}, %[[I1]] +; UNROLL: udiv nof i32 {{.*}}, %[[I1]] ; UNROLL: pred.udiv.if{{[0-9]+}}: -; UNROLL: udiv i32 {{.*}}, %[[I2]] +; UNROLL: udiv nof i32 {{.*}}, %[[I2]] ; UNROLL: pred.udiv.if{{[0-9]+}}: ; UNROLL: %[[I3:.+]] = or i32 %index, 3 -; UNROLL: udiv i32 {{.*}}, %[[I3]] +; UNROLL: udiv nof i32 {{.*}}, %[[I3]] define i32 @scalarize_induction_variable_05(i32* %a, i32 %x, i1 %c, i32 %n) { entry: @@ -377,7 +377,7 @@ br i1 %c, label %if.then, label %if.end if.then: - %tmp2 = udiv i32 %tmp1, %i + %tmp2 = udiv nof i32 %tmp1, %i br label %if.end if.end: Index: test/Transforms/NewGVN/calls-readonly.ll =================================================================== --- test/Transforms/NewGVN/calls-readonly.ll +++ test/Transforms/NewGVN/calls-readonly.ll @@ -11,7 +11,7 @@ br i1 %1, label %bb, label %bb1 bb: ; preds = %entry - %2 = sdiv i32 %x, %y ; [#uses=1] + %2 = sdiv nof i32 %x, %y ; [#uses=1] br label %bb1 bb1: ; preds = %bb, %entry @@ -30,7 +30,7 @@ ; CHECK-NEXT: %1 = icmp eq i32 %0, 0 ; CHECK-NEXT: br i1 %1, label %bb, label %bb1 ; CHECK: bb: -; CHECK-NEXT: %2 = sdiv i32 %x, %y +; CHECK-NEXT: %2 = sdiv nof i32 %x, %y ; CHECK-NEXT: br label %bb1 ; CHECK: bb1: ; CHECK-NEXT: %x_addr.0 = phi i32 [ %2, %bb ], [ %x, %entry ] Index: test/Transforms/NewGVN/pr32838.ll =================================================================== --- test/Transforms/NewGVN/pr32838.ll +++ test/Transforms/NewGVN/pr32838.ll @@ -20,7 +20,7 @@ ; CHECK: for.cond17thread-pre-split: ; CHECK-NEXT: br label [[COND_TRUE]] ; CHECK: cond.true: -; CHECK-NEXT: [[DIV]] = sdiv i64 [[ARG:%.*]], 4 +; CHECK-NEXT: [[DIV]] = sdiv nof i64 [[ARG:%.*]], 4 ; CHECK-NEXT: br label [[THIRDPHIBLOCK]] ; CHECK: temp: ; CHECK-NEXT: ret void @@ -42,7 +42,7 @@ br label %cond.true cond.true: %fourthphi = phi i64 [ %arg, %entry ], [ %firstphi, %for.cond17thread-pre-split ] - %div = sdiv i64 %fourthphi, 4 + %div = sdiv nof i64 %fourthphi, 4 br label %thirdphiblock temp: ret void @@ -66,7 +66,7 @@ ; CHECK-NEXT: br label [[COND_TRUE]] ; CHECK: cond.true: ; CHECK-NEXT: [[FOURTHPHI:%.*]] = phi i64 [ [[ARG:%.*]], [[ENTRY:%.*]] ], [ [[FIRSTPHI]], %for.cond17thread-pre-split ] -; CHECK-NEXT: [[DIV]] = sdiv i64 [[FOURTHPHI]], 4 +; CHECK-NEXT: [[DIV]] = sdiv nof i64 [[FOURTHPHI]], 4 ; CHECK-NEXT: br label [[THIRDPHIBLOCK]] ; CHECK: temp: ; CHECK-NEXT: ret void @@ -88,7 +88,7 @@ br label %cond.true cond.true: %fourthphi = phi i64 [ %arg, %entry ], [ %firstphi, %for.cond17thread-pre-split ] - %div = sdiv i64 %fourthphi, 4 + %div = sdiv nof i64 %fourthphi, 4 br label %thirdphiblock temp: ret void Index: test/Transforms/NewGVN/pr33185.ll =================================================================== --- test/Transforms/NewGVN/pr33185.ll +++ test/Transforms/NewGVN/pr33185.ll @@ -16,7 +16,7 @@ ; CHECK-NEXT: [[MUL_I:%.*]] = select i1 [[CMP1_I]], i32 [[F_08_I]], i32 0 ; CHECK-NEXT: br i1 [[TMP1]], label [[COND_END_I]], label [[COND_TRUE_I:%.*]] ; CHECK: cond.true.i: -; CHECK-NEXT: [[DIV_I:%.*]] = udiv i32 [[MUL_I]], [[F_08_I]] +; CHECK-NEXT: [[DIV_I:%.*]] = udiv nof i32 [[MUL_I]], [[F_08_I]] ; CHECK-NEXT: br label [[COND_END_I]] ; CHECK: cond.end.i: ; CHECK-NEXT: [[COND_I:%.*]] = phi i32 [ [[DIV_I]], [[COND_TRUE_I]] ], [ 0, [[FOR_BODY_I]] ] @@ -40,7 +40,7 @@ cond.true.i: ;; Ensure we don't replace this divide with a phi of ops that merges the wrong loop iteration value - %div.i = udiv i32 %mul.i, %f.08.i + %div.i = udiv nof i32 %mul.i, %f.08.i br label %cond.end.i cond.end.i: @@ -57,10 +57,10 @@ declare i32 @printf(i8* nocapture readonly, ...) -;; Variant of the above where we have made the udiv available in each predecessor with the wrong values. +;; Variant of the above where we have made the udiv nof available in each predecessor with the wrong values. ;; In the entry block, it is always 0, so we don't try to create a leader there, only in %cond.end.i. ;; We should not create a phi of ops for it using these leaders. -;; A correct phi of ops for this udiv would be phi(0, 1), which we are not smart enough to figure out. +;; A correct phi of ops for this udiv nof would be phi(0, 1), which we are not smart enough to figure out. ;; If we reuse the incorrect leaders, we will get phi(0, 0). define i32 @test2() local_unnamed_addr { ; CHECK-LABEL: @test2( @@ -74,7 +74,7 @@ ; CHECK-NEXT: [[MUL_I:%.*]] = select i1 [[CMP1_I]], i32 [[F_08_I]], i32 0 ; CHECK-NEXT: br i1 [[TMP1]], label [[COND_END_I]], label [[COND_TRUE_I:%.*]] ; CHECK: cond.true.i: -; CHECK-NEXT: [[DIV_I:%.*]] = udiv i32 [[MUL_I]], [[F_08_I]] +; CHECK-NEXT: [[DIV_I:%.*]] = udiv nof i32 [[MUL_I]], [[F_08_I]] ; CHECK-NEXT: br label [[COND_END_I]] ; CHECK: cond.end.i: ; CHECK-NEXT: [[COND_I:%.*]] = phi i32 [ [[DIV_I]], [[COND_TRUE_I]] ], [ 0, [[FOR_BODY_I]] ] @@ -99,13 +99,13 @@ cond.true.i: ;; Ensure we don't replace this divide with a phi of ops that merges the wrong loop iteration value - %div.i = udiv i32 %mul.i, %f.08.i + %div.i = udiv nof i32 %mul.i, %f.08.i br label %cond.end.i cond.end.i: %cond.i = phi i32 [ %div.i, %cond.true.i ], [ 0, %for.body.i ] %inc.i = add nuw nsw i32 %f.08.i, 1 - %test = udiv i32 %mul.i, %inc.i + %test = udiv nof i32 %mul.i, %inc.i %call5= tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str4, i64 0, i64 0), i32 %test) %exitcond.i = icmp eq i32 %inc.i, 4 br i1 %exitcond.i, label %fn1.exit, label %for.body.i Index: test/Transforms/SLPVectorizer/AArch64/sdiv-pow2.ll =================================================================== --- test/Transforms/SLPVectorizer/AArch64/sdiv-pow2.ll +++ test/Transforms/SLPVectorizer/AArch64/sdiv-pow2.ll @@ -5,21 +5,21 @@ ; CHECK-LABEL: @test1 ; CHECK: load <4 x i32> ; CHECK: add nsw <4 x i32> -; CHECK: sdiv <4 x i32> +; CHECK: sdiv nof <4 x i32> define void @test1(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* noalias nocapture readonly %c) { entry: %0 = load i32, i32* %b, align 4 %1 = load i32, i32* %c, align 4 %add = add nsw i32 %1, %0 - %div = sdiv i32 %add, 2 + %div = sdiv nof i32 %add, 2 store i32 %div, i32* %a, align 4 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 1 %2 = load i32, i32* %arrayidx3, align 4 %arrayidx4 = getelementptr inbounds i32, i32* %c, i64 1 %3 = load i32, i32* %arrayidx4, align 4 %add5 = add nsw i32 %3, %2 - %div6 = sdiv i32 %add5, 2 + %div6 = sdiv nof i32 %add5, 2 %arrayidx7 = getelementptr inbounds i32, i32* %a, i64 1 store i32 %div6, i32* %arrayidx7, align 4 %arrayidx8 = getelementptr inbounds i32, i32* %b, i64 2 @@ -27,7 +27,7 @@ %arrayidx9 = getelementptr inbounds i32, i32* %c, i64 2 %5 = load i32, i32* %arrayidx9, align 4 %add10 = add nsw i32 %5, %4 - %div11 = sdiv i32 %add10, 2 + %div11 = sdiv nof i32 %add10, 2 %arrayidx12 = getelementptr inbounds i32, i32* %a, i64 2 store i32 %div11, i32* %arrayidx12, align 4 %arrayidx13 = getelementptr inbounds i32, i32* %b, i64 3 @@ -35,7 +35,7 @@ %arrayidx14 = getelementptr inbounds i32, i32* %c, i64 3 %7 = load i32, i32* %arrayidx14, align 4 %add15 = add nsw i32 %7, %6 - %div16 = sdiv i32 %add15, 2 + %div16 = sdiv nof i32 %add15, 2 %arrayidx17 = getelementptr inbounds i32, i32* %a, i64 3 store i32 %div16, i32* %arrayidx17, align 4 ret void Index: test/Transforms/SLPVectorizer/X86/blending-shuffle.ll =================================================================== --- test/Transforms/SLPVectorizer/X86/blending-shuffle.ll +++ test/Transforms/SLPVectorizer/X86/blending-shuffle.ll @@ -92,7 +92,7 @@ ; CHECK-NEXT: [[TMP5:%.*]] = add <2 x i8> [[TMP2]], [[TMP4]] ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i8> [[TMP5]], i32 0 ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i8> [[TMP5]], i32 1 -; CHECK-NEXT: [[TMP8:%.*]] = sdiv i8 [[TMP6]], [[TMP7]] +; CHECK-NEXT: [[TMP8:%.*]] = sdiv nof i8 [[TMP6]], [[TMP7]] ; CHECK-NEXT: ret i8 [[TMP8]] ; %x0 = extractelement <4 x i8> %x, i32 0 @@ -105,7 +105,7 @@ %y2y2 = mul i8 %y2, %y2 %1 = add i8 %x0x0, %x3x3 %2 = add i8 %y1y1, %y2y2 - %3 = sdiv i8 %1, %2 + %3 = sdiv nof i8 %1, %2 ret i8 %3 } @@ -118,7 +118,7 @@ ; CHECK-NEXT: [[TMP5:%.*]] = add <2 x i8> [[TMP2]], [[TMP4]] ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i8> [[TMP5]], i32 0 ; CHECK-NEXT: [[TMP7:%.*]] = extractelement <2 x i8> [[TMP5]], i32 1 -; CHECK-NEXT: [[TMP8:%.*]] = sdiv i8 [[TMP6]], [[TMP7]] +; CHECK-NEXT: [[TMP8:%.*]] = sdiv nof i8 [[TMP6]], [[TMP7]] ; CHECK-NEXT: ret i8 [[TMP8]] ; %x0 = extractelement <4 x i8> %x, i32 0 @@ -131,7 +131,7 @@ %x2x2 = mul i8 %x2, %x2 %1 = add i8 %x0x0, %x3x3 %2 = add i8 %x1x1, %x2x2 - %3 = sdiv i8 %1, %2 + %3 = sdiv nof i8 %1, %2 ret i8 %3 } @@ -148,7 +148,7 @@ ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <4 x i8> [[TMP1]], i32 1 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <4 x i8> [[TMP1]], i32 2 ; CHECK-NEXT: [[TMP5:%.*]] = add i8 [[TMP3]], [[TMP4]] -; CHECK-NEXT: [[TMP6:%.*]] = sdiv i8 [[TMP2]], [[TMP5]] +; CHECK-NEXT: [[TMP6:%.*]] = sdiv nof i8 [[TMP2]], [[TMP5]] ; CHECK-NEXT: ret i8 [[TMP6]] ; %x0 = extractelement <4 x i8> %x, i32 0 @@ -163,6 +163,6 @@ %x2x2 = mul i8 %x2, %x2 %1 = add i8 %x0x0, %x3x3 %2 = add i8 %x1x1, %x2x2 - %3 = sdiv i8 %1, %2 + %3 = sdiv nof i8 %1, %2 ret i8 %3 } Index: test/Transforms/SLPVectorizer/X86/powof2div.ll =================================================================== --- test/Transforms/SLPVectorizer/X86/powof2div.ll +++ test/Transforms/SLPVectorizer/X86/powof2div.ll @@ -6,20 +6,20 @@ ;CHECK-LABEL: @powof2div( ;CHECK: load <4 x i32>, <4 x i32>* ;CHECK: add nsw <4 x i32> -;CHECK: sdiv <4 x i32> +;CHECK: sdiv nof <4 x i32> define void @powof2div(i32* noalias nocapture %a, i32* noalias nocapture readonly %b, i32* noalias nocapture readonly %c){ entry: %0 = load i32, i32* %b, align 4 %1 = load i32, i32* %c, align 4 %add = add nsw i32 %1, %0 - %div = sdiv i32 %add, 2 + %div = sdiv nof i32 %add, 2 store i32 %div, i32* %a, align 4 %arrayidx3 = getelementptr inbounds i32, i32* %b, i64 1 %2 = load i32, i32* %arrayidx3, align 4 %arrayidx4 = getelementptr inbounds i32, i32* %c, i64 1 %3 = load i32, i32* %arrayidx4, align 4 %add5 = add nsw i32 %3, %2 - %div6 = sdiv i32 %add5, 2 + %div6 = sdiv nof i32 %add5, 2 %arrayidx7 = getelementptr inbounds i32, i32* %a, i64 1 store i32 %div6, i32* %arrayidx7, align 4 %arrayidx8 = getelementptr inbounds i32, i32* %b, i64 2 @@ -27,7 +27,7 @@ %arrayidx9 = getelementptr inbounds i32, i32* %c, i64 2 %5 = load i32, i32* %arrayidx9, align 4 %add10 = add nsw i32 %5, %4 - %div11 = sdiv i32 %add10, 2 + %div11 = sdiv nof i32 %add10, 2 %arrayidx12 = getelementptr inbounds i32, i32* %a, i64 2 store i32 %div11, i32* %arrayidx12, align 4 %arrayidx13 = getelementptr inbounds i32, i32* %b, i64 3 @@ -35,7 +35,7 @@ %arrayidx14 = getelementptr inbounds i32, i32* %c, i64 3 %7 = load i32, i32* %arrayidx14, align 4 %add15 = add nsw i32 %7, %6 - %div16 = sdiv i32 %add15, 2 + %div16 = sdiv nof i32 %add15, 2 %arrayidx17 = getelementptr inbounds i32, i32* %a, i64 3 store i32 %div16, i32* %arrayidx17, align 4 ret void Index: test/Transforms/ScalarizeMayOverflowDiv/scalarize-may-overflow-div.ll =================================================================== --- test/Transforms/ScalarizeMayOverflowDiv/scalarize-may-overflow-div.ll +++ test/Transforms/ScalarizeMayOverflowDiv/scalarize-may-overflow-div.ll @@ -0,0 +1,330 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt %s -mcpu=atom -scalarize-may-overflow-div -S -o - | FileCheck %s --check-prefix=ATOM +; RUN: opt %s -mcpu=core-avx2 -scalarize-may-overflow-div -S -o - | FileCheck %s --check-prefix=AVX2 +target triple = "x86_64-unknown-unknown" + +define i32 @udiv_scalarize_i32(i32 %op1, i32 %op2) { +; ATOM-LABEL: @udiv_scalarize_i32( +; ATOM-NEXT: [[TMP1:%.*]] = icmp ne i32 [[OP2:%.*]], 0 +; ATOM-NEXT: br i1 [[TMP1]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; ATOM: cond.div: +; ATOM-NEXT: [[TMP2:%.*]] = udiv nof i32 [[OP1:%.*]], [[OP2]] +; ATOM-NEXT: br label [[ELSE]] +; ATOM: else: +; ATOM-NEXT: [[RES_PHI_SELECT:%.*]] = phi i32 [ [[TMP2]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; ATOM-NEXT: ret i32 [[RES_PHI_SELECT]] +; +; AVX2-LABEL: @udiv_scalarize_i32( +; AVX2-NEXT: [[TMP1:%.*]] = icmp ne i32 [[OP2:%.*]], 0 +; AVX2-NEXT: br i1 [[TMP1]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; AVX2: cond.div: +; AVX2-NEXT: [[TMP2:%.*]] = udiv nof i32 [[OP1:%.*]], [[OP2]] +; AVX2-NEXT: br label [[ELSE]] +; AVX2: else: +; AVX2-NEXT: [[RES_PHI_SELECT:%.*]] = phi i32 [ [[TMP2]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; AVX2-NEXT: ret i32 [[RES_PHI_SELECT]] +; + %res = udiv mof i32 %op1, %op2 + ret i32 %res; +} + +define <1 x i32> @udiv_scalarize_v1i32(<1 x i32> %op1, <1 x i32> %op2) { +; ATOM-LABEL: @udiv_scalarize_v1i32( +; ATOM-NEXT: [[TMP1:%.*]] = icmp ne <1 x i32> [[OP2:%.*]], zeroinitializer +; ATOM-NEXT: [[TMP2:%.*]] = extractelement <1 x i1> [[TMP1]], i64 0 +; ATOM-NEXT: br i1 [[TMP2]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; ATOM: cond.div: +; ATOM-NEXT: [[TMP3:%.*]] = extractelement <1 x i32> [[OP1:%.*]], i64 0 +; ATOM-NEXT: [[TMP4:%.*]] = extractelement <1 x i32> [[OP2]], i64 0 +; ATOM-NEXT: [[TMP5:%.*]] = udiv nof i32 [[TMP3]], [[TMP4]] +; ATOM-NEXT: [[TMP6:%.*]] = insertelement <1 x i32> undef, i32 [[TMP5]], i64 0 +; ATOM-NEXT: br label [[ELSE]] +; ATOM: else: +; ATOM-NEXT: [[RES_PHI_SELECT:%.*]] = phi <1 x i32> [ [[TMP6]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; ATOM-NEXT: ret <1 x i32> [[RES_PHI_SELECT]] +; +; AVX2-LABEL: @udiv_scalarize_v1i32( +; AVX2-NEXT: [[TMP1:%.*]] = icmp ne <1 x i32> [[OP2:%.*]], zeroinitializer +; AVX2-NEXT: [[TMP2:%.*]] = extractelement <1 x i1> [[TMP1]], i64 0 +; AVX2-NEXT: br i1 [[TMP2]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; AVX2: cond.div: +; AVX2-NEXT: [[TMP3:%.*]] = extractelement <1 x i32> [[OP1:%.*]], i64 0 +; AVX2-NEXT: [[TMP4:%.*]] = extractelement <1 x i32> [[OP2]], i64 0 +; AVX2-NEXT: [[TMP5:%.*]] = udiv nof i32 [[TMP3]], [[TMP4]] +; AVX2-NEXT: [[TMP6:%.*]] = insertelement <1 x i32> undef, i32 [[TMP5]], i64 0 +; AVX2-NEXT: br label [[ELSE]] +; AVX2: else: +; AVX2-NEXT: [[RES_PHI_SELECT:%.*]] = phi <1 x i32> [ [[TMP6]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; AVX2-NEXT: ret <1 x i32> [[RES_PHI_SELECT]] +; + %res = udiv mof <1 x i32> %op1, %op2 + ret <1 x i32> %res; +} + +define i32 @sdiv_scalarize_i32(i32 %op1, i32 %op2) { +; ATOM-LABEL: @sdiv_scalarize_i32( +; ATOM-NEXT: [[TMP1:%.*]] = icmp ne i32 [[OP2:%.*]], 0 +; ATOM-NEXT: [[TMP2:%.*]] = icmp ne i32 [[OP2]], -1 +; ATOM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[OP1:%.*]], -2147483648 +; ATOM-NEXT: [[TMP4:%.*]] = or i1 [[TMP2]], [[TMP3]] +; ATOM-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP1]] +; ATOM-NEXT: br i1 [[TMP5]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; ATOM: cond.div: +; ATOM-NEXT: [[TMP6:%.*]] = sdiv nof i32 [[OP1]], [[OP2]] +; ATOM-NEXT: br label [[ELSE]] +; ATOM: else: +; ATOM-NEXT: [[RES_PHI_SELECT:%.*]] = phi i32 [ [[TMP6]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; ATOM-NEXT: ret i32 [[RES_PHI_SELECT]] +; +; AVX2-LABEL: @sdiv_scalarize_i32( +; AVX2-NEXT: [[TMP1:%.*]] = icmp ne i32 [[OP2:%.*]], 0 +; AVX2-NEXT: [[TMP2:%.*]] = icmp ne i32 [[OP2]], -1 +; AVX2-NEXT: [[TMP3:%.*]] = icmp ne i32 [[OP1:%.*]], -2147483648 +; AVX2-NEXT: [[TMP4:%.*]] = or i1 [[TMP2]], [[TMP3]] +; AVX2-NEXT: [[TMP5:%.*]] = and i1 [[TMP4]], [[TMP1]] +; AVX2-NEXT: br i1 [[TMP5]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; AVX2: cond.div: +; AVX2-NEXT: [[TMP6:%.*]] = sdiv nof i32 [[OP1]], [[OP2]] +; AVX2-NEXT: br label [[ELSE]] +; AVX2: else: +; AVX2-NEXT: [[RES_PHI_SELECT:%.*]] = phi i32 [ [[TMP6]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; AVX2-NEXT: ret i32 [[RES_PHI_SELECT]] +; + %res = sdiv mof i32 %op1, %op2 + ret i32 %res; +} + +define <1 x i32> @sdiv_scalarize_v1i32(<1 x i32> %op1, <1 x i32> %op2) { +; ATOM-LABEL: @sdiv_scalarize_v1i32( +; ATOM-NEXT: [[TMP1:%.*]] = icmp ne <1 x i32> [[OP2:%.*]], zeroinitializer +; ATOM-NEXT: [[TMP2:%.*]] = icmp ne <1 x i32> [[OP2]], +; ATOM-NEXT: [[TMP3:%.*]] = icmp ne <1 x i32> [[OP1:%.*]], +; ATOM-NEXT: [[TMP4:%.*]] = or <1 x i1> [[TMP2]], [[TMP3]] +; ATOM-NEXT: [[TMP5:%.*]] = and <1 x i1> [[TMP4]], [[TMP1]] +; ATOM-NEXT: [[TMP6:%.*]] = extractelement <1 x i1> [[TMP5]], i64 0 +; ATOM-NEXT: br i1 [[TMP6]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; ATOM: cond.div: +; ATOM-NEXT: [[TMP7:%.*]] = extractelement <1 x i32> [[OP1]], i64 0 +; ATOM-NEXT: [[TMP8:%.*]] = extractelement <1 x i32> [[OP2]], i64 0 +; ATOM-NEXT: [[TMP9:%.*]] = sdiv nof i32 [[TMP7]], [[TMP8]] +; ATOM-NEXT: [[TMP10:%.*]] = insertelement <1 x i32> undef, i32 [[TMP9]], i64 0 +; ATOM-NEXT: br label [[ELSE]] +; ATOM: else: +; ATOM-NEXT: [[RES_PHI_SELECT:%.*]] = phi <1 x i32> [ [[TMP10]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; ATOM-NEXT: ret <1 x i32> [[RES_PHI_SELECT]] +; +; AVX2-LABEL: @sdiv_scalarize_v1i32( +; AVX2-NEXT: [[TMP1:%.*]] = icmp ne <1 x i32> [[OP2:%.*]], zeroinitializer +; AVX2-NEXT: [[TMP2:%.*]] = icmp ne <1 x i32> [[OP2]], +; AVX2-NEXT: [[TMP3:%.*]] = icmp ne <1 x i32> [[OP1:%.*]], +; AVX2-NEXT: [[TMP4:%.*]] = or <1 x i1> [[TMP2]], [[TMP3]] +; AVX2-NEXT: [[TMP5:%.*]] = and <1 x i1> [[TMP4]], [[TMP1]] +; AVX2-NEXT: [[TMP6:%.*]] = extractelement <1 x i1> [[TMP5]], i64 0 +; AVX2-NEXT: br i1 [[TMP6]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; AVX2: cond.div: +; AVX2-NEXT: [[TMP7:%.*]] = extractelement <1 x i32> [[OP1]], i64 0 +; AVX2-NEXT: [[TMP8:%.*]] = extractelement <1 x i32> [[OP2]], i64 0 +; AVX2-NEXT: [[TMP9:%.*]] = sdiv nof i32 [[TMP7]], [[TMP8]] +; AVX2-NEXT: [[TMP10:%.*]] = insertelement <1 x i32> undef, i32 [[TMP9]], i64 0 +; AVX2-NEXT: br label [[ELSE]] +; AVX2: else: +; AVX2-NEXT: [[RES_PHI_SELECT:%.*]] = phi <1 x i32> [ [[TMP10]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; AVX2-NEXT: ret <1 x i32> [[RES_PHI_SELECT]] +; + %res = sdiv mof <1 x i32> %op1, %op2 + ret <1 x i32> %res; +} + +define <4 x i32> @udiv_scalarize(<4 x i32> %op1, <4 x i32> %op2) { +; ATOM-LABEL: @udiv_scalarize( +; ATOM-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[OP2:%.*]], zeroinitializer +; ATOM-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0 +; ATOM-NEXT: br i1 [[TMP2]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; ATOM: cond.div: +; ATOM-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> [[OP1:%.*]], i64 0 +; ATOM-NEXT: [[TMP4:%.*]] = extractelement <4 x i32> [[OP2]], i64 0 +; ATOM-NEXT: [[TMP5:%.*]] = udiv nof i32 [[TMP3]], [[TMP4]] +; ATOM-NEXT: [[TMP6:%.*]] = insertelement <4 x i32> undef, i32 [[TMP5]], i64 0 +; ATOM-NEXT: br label [[ELSE]] +; ATOM: else: +; ATOM-NEXT: [[RES_PHI_ELSE:%.*]] = phi <4 x i32> [ [[TMP6]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; ATOM-NEXT: [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1 +; ATOM-NEXT: br i1 [[TMP7]], label [[COND_DIV1:%.*]], label [[ELSE2:%.*]] +; ATOM: cond.div1: +; ATOM-NEXT: [[TMP8:%.*]] = extractelement <4 x i32> [[OP1]], i64 1 +; ATOM-NEXT: [[TMP9:%.*]] = extractelement <4 x i32> [[OP2]], i64 1 +; ATOM-NEXT: [[TMP10:%.*]] = udiv nof i32 [[TMP8]], [[TMP9]] +; ATOM-NEXT: [[TMP11:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE]], i32 [[TMP10]], i64 1 +; ATOM-NEXT: br label [[ELSE2]] +; ATOM: else2: +; ATOM-NEXT: [[RES_PHI_ELSE3:%.*]] = phi <4 x i32> [ [[TMP11]], [[COND_DIV1]] ], [ [[RES_PHI_ELSE]], [[ELSE]] ] +; ATOM-NEXT: [[TMP12:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2 +; ATOM-NEXT: br i1 [[TMP12]], label [[COND_DIV4:%.*]], label [[ELSE5:%.*]] +; ATOM: cond.div4: +; ATOM-NEXT: [[TMP13:%.*]] = extractelement <4 x i32> [[OP1]], i64 2 +; ATOM-NEXT: [[TMP14:%.*]] = extractelement <4 x i32> [[OP2]], i64 2 +; ATOM-NEXT: [[TMP15:%.*]] = udiv nof i32 [[TMP13]], [[TMP14]] +; ATOM-NEXT: [[TMP16:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE3]], i32 [[TMP15]], i64 2 +; ATOM-NEXT: br label [[ELSE5]] +; ATOM: else5: +; ATOM-NEXT: [[RES_PHI_ELSE6:%.*]] = phi <4 x i32> [ [[TMP16]], [[COND_DIV4]] ], [ [[RES_PHI_ELSE3]], [[ELSE2]] ] +; ATOM-NEXT: [[TMP17:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3 +; ATOM-NEXT: br i1 [[TMP17]], label [[COND_DIV7:%.*]], label [[ELSE8:%.*]] +; ATOM: cond.div7: +; ATOM-NEXT: [[TMP18:%.*]] = extractelement <4 x i32> [[OP1]], i64 3 +; ATOM-NEXT: [[TMP19:%.*]] = extractelement <4 x i32> [[OP2]], i64 3 +; ATOM-NEXT: [[TMP20:%.*]] = udiv nof i32 [[TMP18]], [[TMP19]] +; ATOM-NEXT: [[TMP21:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE6]], i32 [[TMP20]], i64 3 +; ATOM-NEXT: br label [[ELSE8]] +; ATOM: else8: +; ATOM-NEXT: [[RES_PHI_SELECT:%.*]] = phi <4 x i32> [ [[TMP21]], [[COND_DIV7]] ], [ [[RES_PHI_ELSE6]], [[ELSE5]] ] +; ATOM-NEXT: ret <4 x i32> [[RES_PHI_SELECT]] +; +; AVX2-LABEL: @udiv_scalarize( +; AVX2-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[OP2:%.*]], zeroinitializer +; AVX2-NEXT: [[TMP2:%.*]] = extractelement <4 x i1> [[TMP1]], i64 0 +; AVX2-NEXT: br i1 [[TMP2]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; AVX2: cond.div: +; AVX2-NEXT: [[TMP3:%.*]] = extractelement <4 x i32> [[OP1:%.*]], i64 0 +; AVX2-NEXT: [[TMP4:%.*]] = extractelement <4 x i32> [[OP2]], i64 0 +; AVX2-NEXT: [[TMP5:%.*]] = udiv nof i32 [[TMP3]], [[TMP4]] +; AVX2-NEXT: [[TMP6:%.*]] = insertelement <4 x i32> undef, i32 [[TMP5]], i64 0 +; AVX2-NEXT: br label [[ELSE]] +; AVX2: else: +; AVX2-NEXT: [[RES_PHI_ELSE:%.*]] = phi <4 x i32> [ [[TMP6]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; AVX2-NEXT: [[TMP7:%.*]] = extractelement <4 x i1> [[TMP1]], i64 1 +; AVX2-NEXT: br i1 [[TMP7]], label [[COND_DIV1:%.*]], label [[ELSE2:%.*]] +; AVX2: cond.div1: +; AVX2-NEXT: [[TMP8:%.*]] = extractelement <4 x i32> [[OP1]], i64 1 +; AVX2-NEXT: [[TMP9:%.*]] = extractelement <4 x i32> [[OP2]], i64 1 +; AVX2-NEXT: [[TMP10:%.*]] = udiv nof i32 [[TMP8]], [[TMP9]] +; AVX2-NEXT: [[TMP11:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE]], i32 [[TMP10]], i64 1 +; AVX2-NEXT: br label [[ELSE2]] +; AVX2: else2: +; AVX2-NEXT: [[RES_PHI_ELSE3:%.*]] = phi <4 x i32> [ [[TMP11]], [[COND_DIV1]] ], [ [[RES_PHI_ELSE]], [[ELSE]] ] +; AVX2-NEXT: [[TMP12:%.*]] = extractelement <4 x i1> [[TMP1]], i64 2 +; AVX2-NEXT: br i1 [[TMP12]], label [[COND_DIV4:%.*]], label [[ELSE5:%.*]] +; AVX2: cond.div4: +; AVX2-NEXT: [[TMP13:%.*]] = extractelement <4 x i32> [[OP1]], i64 2 +; AVX2-NEXT: [[TMP14:%.*]] = extractelement <4 x i32> [[OP2]], i64 2 +; AVX2-NEXT: [[TMP15:%.*]] = udiv nof i32 [[TMP13]], [[TMP14]] +; AVX2-NEXT: [[TMP16:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE3]], i32 [[TMP15]], i64 2 +; AVX2-NEXT: br label [[ELSE5]] +; AVX2: else5: +; AVX2-NEXT: [[RES_PHI_ELSE6:%.*]] = phi <4 x i32> [ [[TMP16]], [[COND_DIV4]] ], [ [[RES_PHI_ELSE3]], [[ELSE2]] ] +; AVX2-NEXT: [[TMP17:%.*]] = extractelement <4 x i1> [[TMP1]], i64 3 +; AVX2-NEXT: br i1 [[TMP17]], label [[COND_DIV7:%.*]], label [[ELSE8:%.*]] +; AVX2: cond.div7: +; AVX2-NEXT: [[TMP18:%.*]] = extractelement <4 x i32> [[OP1]], i64 3 +; AVX2-NEXT: [[TMP19:%.*]] = extractelement <4 x i32> [[OP2]], i64 3 +; AVX2-NEXT: [[TMP20:%.*]] = udiv nof i32 [[TMP18]], [[TMP19]] +; AVX2-NEXT: [[TMP21:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE6]], i32 [[TMP20]], i64 3 +; AVX2-NEXT: br label [[ELSE8]] +; AVX2: else8: +; AVX2-NEXT: [[RES_PHI_SELECT:%.*]] = phi <4 x i32> [ [[TMP21]], [[COND_DIV7]] ], [ [[RES_PHI_ELSE6]], [[ELSE5]] ] +; AVX2-NEXT: ret <4 x i32> [[RES_PHI_SELECT]] +; + %res = udiv mof <4 x i32> %op1, %op2 + ret <4 x i32> %res; +} + +define <4 x i32> @sdiv_scalarize(<4 x i32> %op1, <4 x i32> %op2) { +; ATOM-LABEL: @sdiv_scalarize( +; ATOM-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[OP2:%.*]], zeroinitializer +; ATOM-NEXT: [[TMP2:%.*]] = icmp ne <4 x i32> [[OP2]], +; ATOM-NEXT: [[TMP3:%.*]] = icmp ne <4 x i32> [[OP1:%.*]], +; ATOM-NEXT: [[TMP4:%.*]] = or <4 x i1> [[TMP2]], [[TMP3]] +; ATOM-NEXT: [[TMP5:%.*]] = and <4 x i1> [[TMP4]], [[TMP1]] +; ATOM-NEXT: [[TMP6:%.*]] = extractelement <4 x i1> [[TMP5]], i64 0 +; ATOM-NEXT: br i1 [[TMP6]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; ATOM: cond.div: +; ATOM-NEXT: [[TMP7:%.*]] = extractelement <4 x i32> [[OP1]], i64 0 +; ATOM-NEXT: [[TMP8:%.*]] = extractelement <4 x i32> [[OP2]], i64 0 +; ATOM-NEXT: [[TMP9:%.*]] = sdiv nof i32 [[TMP7]], [[TMP8]] +; ATOM-NEXT: [[TMP10:%.*]] = insertelement <4 x i32> undef, i32 [[TMP9]], i64 0 +; ATOM-NEXT: br label [[ELSE]] +; ATOM: else: +; ATOM-NEXT: [[RES_PHI_ELSE:%.*]] = phi <4 x i32> [ [[TMP10]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; ATOM-NEXT: [[TMP11:%.*]] = extractelement <4 x i1> [[TMP5]], i64 1 +; ATOM-NEXT: br i1 [[TMP11]], label [[COND_DIV1:%.*]], label [[ELSE2:%.*]] +; ATOM: cond.div1: +; ATOM-NEXT: [[TMP12:%.*]] = extractelement <4 x i32> [[OP1]], i64 1 +; ATOM-NEXT: [[TMP13:%.*]] = extractelement <4 x i32> [[OP2]], i64 1 +; ATOM-NEXT: [[TMP14:%.*]] = sdiv nof i32 [[TMP12]], [[TMP13]] +; ATOM-NEXT: [[TMP15:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE]], i32 [[TMP14]], i64 1 +; ATOM-NEXT: br label [[ELSE2]] +; ATOM: else2: +; ATOM-NEXT: [[RES_PHI_ELSE3:%.*]] = phi <4 x i32> [ [[TMP15]], [[COND_DIV1]] ], [ [[RES_PHI_ELSE]], [[ELSE]] ] +; ATOM-NEXT: [[TMP16:%.*]] = extractelement <4 x i1> [[TMP5]], i64 2 +; ATOM-NEXT: br i1 [[TMP16]], label [[COND_DIV4:%.*]], label [[ELSE5:%.*]] +; ATOM: cond.div4: +; ATOM-NEXT: [[TMP17:%.*]] = extractelement <4 x i32> [[OP1]], i64 2 +; ATOM-NEXT: [[TMP18:%.*]] = extractelement <4 x i32> [[OP2]], i64 2 +; ATOM-NEXT: [[TMP19:%.*]] = sdiv nof i32 [[TMP17]], [[TMP18]] +; ATOM-NEXT: [[TMP20:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE3]], i32 [[TMP19]], i64 2 +; ATOM-NEXT: br label [[ELSE5]] +; ATOM: else5: +; ATOM-NEXT: [[RES_PHI_ELSE6:%.*]] = phi <4 x i32> [ [[TMP20]], [[COND_DIV4]] ], [ [[RES_PHI_ELSE3]], [[ELSE2]] ] +; ATOM-NEXT: [[TMP21:%.*]] = extractelement <4 x i1> [[TMP5]], i64 3 +; ATOM-NEXT: br i1 [[TMP21]], label [[COND_DIV7:%.*]], label [[ELSE8:%.*]] +; ATOM: cond.div7: +; ATOM-NEXT: [[TMP22:%.*]] = extractelement <4 x i32> [[OP1]], i64 3 +; ATOM-NEXT: [[TMP23:%.*]] = extractelement <4 x i32> [[OP2]], i64 3 +; ATOM-NEXT: [[TMP24:%.*]] = sdiv nof i32 [[TMP22]], [[TMP23]] +; ATOM-NEXT: [[TMP25:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE6]], i32 [[TMP24]], i64 3 +; ATOM-NEXT: br label [[ELSE8]] +; ATOM: else8: +; ATOM-NEXT: [[RES_PHI_SELECT:%.*]] = phi <4 x i32> [ [[TMP25]], [[COND_DIV7]] ], [ [[RES_PHI_ELSE6]], [[ELSE5]] ] +; ATOM-NEXT: ret <4 x i32> [[RES_PHI_SELECT]] +; +; AVX2-LABEL: @sdiv_scalarize( +; AVX2-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[OP2:%.*]], zeroinitializer +; AVX2-NEXT: [[TMP2:%.*]] = icmp ne <4 x i32> [[OP2]], +; AVX2-NEXT: [[TMP3:%.*]] = icmp ne <4 x i32> [[OP1:%.*]], +; AVX2-NEXT: [[TMP4:%.*]] = or <4 x i1> [[TMP2]], [[TMP3]] +; AVX2-NEXT: [[TMP5:%.*]] = and <4 x i1> [[TMP4]], [[TMP1]] +; AVX2-NEXT: [[TMP6:%.*]] = extractelement <4 x i1> [[TMP5]], i64 0 +; AVX2-NEXT: br i1 [[TMP6]], label [[COND_DIV:%.*]], label [[ELSE:%.*]] +; AVX2: cond.div: +; AVX2-NEXT: [[TMP7:%.*]] = extractelement <4 x i32> [[OP1]], i64 0 +; AVX2-NEXT: [[TMP8:%.*]] = extractelement <4 x i32> [[OP2]], i64 0 +; AVX2-NEXT: [[TMP9:%.*]] = sdiv nof i32 [[TMP7]], [[TMP8]] +; AVX2-NEXT: [[TMP10:%.*]] = insertelement <4 x i32> undef, i32 [[TMP9]], i64 0 +; AVX2-NEXT: br label [[ELSE]] +; AVX2: else: +; AVX2-NEXT: [[RES_PHI_ELSE:%.*]] = phi <4 x i32> [ [[TMP10]], [[COND_DIV]] ], [ undef, [[TMP0:%.*]] ] +; AVX2-NEXT: [[TMP11:%.*]] = extractelement <4 x i1> [[TMP5]], i64 1 +; AVX2-NEXT: br i1 [[TMP11]], label [[COND_DIV1:%.*]], label [[ELSE2:%.*]] +; AVX2: cond.div1: +; AVX2-NEXT: [[TMP12:%.*]] = extractelement <4 x i32> [[OP1]], i64 1 +; AVX2-NEXT: [[TMP13:%.*]] = extractelement <4 x i32> [[OP2]], i64 1 +; AVX2-NEXT: [[TMP14:%.*]] = sdiv nof i32 [[TMP12]], [[TMP13]] +; AVX2-NEXT: [[TMP15:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE]], i32 [[TMP14]], i64 1 +; AVX2-NEXT: br label [[ELSE2]] +; AVX2: else2: +; AVX2-NEXT: [[RES_PHI_ELSE3:%.*]] = phi <4 x i32> [ [[TMP15]], [[COND_DIV1]] ], [ [[RES_PHI_ELSE]], [[ELSE]] ] +; AVX2-NEXT: [[TMP16:%.*]] = extractelement <4 x i1> [[TMP5]], i64 2 +; AVX2-NEXT: br i1 [[TMP16]], label [[COND_DIV4:%.*]], label [[ELSE5:%.*]] +; AVX2: cond.div4: +; AVX2-NEXT: [[TMP17:%.*]] = extractelement <4 x i32> [[OP1]], i64 2 +; AVX2-NEXT: [[TMP18:%.*]] = extractelement <4 x i32> [[OP2]], i64 2 +; AVX2-NEXT: [[TMP19:%.*]] = sdiv nof i32 [[TMP17]], [[TMP18]] +; AVX2-NEXT: [[TMP20:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE3]], i32 [[TMP19]], i64 2 +; AVX2-NEXT: br label [[ELSE5]] +; AVX2: else5: +; AVX2-NEXT: [[RES_PHI_ELSE6:%.*]] = phi <4 x i32> [ [[TMP20]], [[COND_DIV4]] ], [ [[RES_PHI_ELSE3]], [[ELSE2]] ] +; AVX2-NEXT: [[TMP21:%.*]] = extractelement <4 x i1> [[TMP5]], i64 3 +; AVX2-NEXT: br i1 [[TMP21]], label [[COND_DIV7:%.*]], label [[ELSE8:%.*]] +; AVX2: cond.div7: +; AVX2-NEXT: [[TMP22:%.*]] = extractelement <4 x i32> [[OP1]], i64 3 +; AVX2-NEXT: [[TMP23:%.*]] = extractelement <4 x i32> [[OP2]], i64 3 +; AVX2-NEXT: [[TMP24:%.*]] = sdiv nof i32 [[TMP22]], [[TMP23]] +; AVX2-NEXT: [[TMP25:%.*]] = insertelement <4 x i32> [[RES_PHI_ELSE6]], i32 [[TMP24]], i64 3 +; AVX2-NEXT: br label [[ELSE8]] +; AVX2: else8: +; AVX2-NEXT: [[RES_PHI_SELECT:%.*]] = phi <4 x i32> [ [[TMP25]], [[COND_DIV7]] ], [ [[RES_PHI_ELSE6]], [[ELSE5]] ] +; AVX2-NEXT: ret <4 x i32> [[RES_PHI_SELECT]] +; + %res = sdiv mof <4 x i32> %op1, %op2 + ret <4 x i32> %res; +} Index: test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll =================================================================== --- test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll +++ test/Transforms/SimplifyCFG/ConditionalTrappingConstantExpr.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: [[C:%.*]] = icmp sle i32 %a, %b ; CHECK-NEXT: br i1 [[C]], label %bb2, label %bb1 ; CHECK: bb1: -; CHECK-NEXT: [[D:%.*]] = icmp sgt i32 sdiv (i32 -32768, i32 ptrtoint (i32* @G to i32)), 0 +; CHECK-NEXT: [[D:%.*]] = icmp sgt i32 sdiv nof (i32 -32768, i32 ptrtoint (i32* @G to i32)), 0 ; CHECK-NEXT: [[DOT:%.*]] = select i1 [[D]], i32 927, i32 42 ; CHECK-NEXT: br label %bb2 ; CHECK: bb2: @@ -21,7 +21,7 @@ %c = icmp sle i32 %a, %b br i1 %c, label %bb2, label %bb1 bb1: - %d = icmp sgt i32 sdiv (i32 -32768, i32 ptrtoint (i32* @G to i32)), 0 + %d = icmp sgt i32 sdiv nof (i32 -32768, i32 ptrtoint (i32* @G to i32)), 0 br i1 %d, label %bb6, label %bb2 bb2: ret i32 42 @@ -33,7 +33,7 @@ ; CHECK-LABEL: @ackbar( ; CHECK-NEXT: br i1 %c, label %bb5, label %bb6 ; CHECK: bb5: -; CHECK-NEXT: [[DOT:%.*]] = select i1 icmp sgt (i32 sdiv (i32 32767, i32 ptrtoint (i32* @G to i32)), i32 0), i32 42, i32 927 +; CHECK-NEXT: [[DOT:%.*]] = select i1 icmp sgt (i32 sdiv nof (i32 32767, i32 ptrtoint (i32* @G to i32)), i32 0), i32 42, i32 927 ; CHECK-NEXT: br label %bb6 ; CHECK: bb6: ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ 42, %0 ], [ [[DOT]], %bb5 ] @@ -41,7 +41,7 @@ ; br i1 %c, label %bb5, label %bb6 bb5: - br i1 icmp sgt (i32 sdiv (i32 32767, i32 ptrtoint (i32* @G to i32)), i32 0), label %bb6, label %bb7 + br i1 icmp sgt (i32 sdiv nof (i32 32767, i32 ptrtoint (i32* @G to i32)), i32 0), label %bb6, label %bb7 bb6: ret i32 42 bb7: Index: test/Transforms/SimplifyCFG/div-rem-pairs.ll =================================================================== --- test/Transforms/SimplifyCFG/div-rem-pairs.ll +++ test/Transforms/SimplifyCFG/div-rem-pairs.ll @@ -11,7 +11,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[REM]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i32 %a, %b ; CHECK-NEXT: br label %end ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[DIV]], %if ], [ 3, %entry ] @@ -23,7 +23,7 @@ br i1 %cmp, label %if, label %end if: - %div = sdiv i32 %a, %b + %div = sdiv nof i32 %a, %b br label %end end: @@ -38,7 +38,7 @@ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[REM]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: -; CHECK-NEXT: [[DIV:%.*]] = udiv i64 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i64 %a, %b ; CHECK-NEXT: br label %end ; CHECK: end: ; CHECK-NEXT: [[RET:%.*]] = phi i64 [ [[DIV]], %if ], [ 3, %entry ] @@ -50,7 +50,7 @@ br i1 %cmp, label %if, label %end if: - %div = udiv i64 %a, %b + %div = udiv nof i64 %a, %b br label %end end: @@ -61,7 +61,7 @@ define i16 @hoist_srem(i16 %a, i16 %b) { ; CHECK-LABEL: @hoist_srem( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = sdiv i16 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = sdiv nof i16 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[DIV]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: @@ -72,7 +72,7 @@ ; CHECK-NEXT: ret i16 [[RET]] ; entry: - %div = sdiv i16 %a, %b + %div = sdiv nof i16 %a, %b %cmp = icmp eq i16 %div, 42 br i1 %cmp, label %if, label %end @@ -88,7 +88,7 @@ define i8 @hoist_urem(i8 %a, i8 %b) { ; CHECK-LABEL: @hoist_urem( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[DIV:%.*]] = udiv i8 %a, %b +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i8 %a, %b ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[DIV]], 42 ; CHECK-NEXT: br i1 [[CMP]], label %if, label %end ; CHECK: if: @@ -99,7 +99,7 @@ ; CHECK-NEXT: ret i8 [[RET]] ; entry: - %div = udiv i8 %a, %b + %div = udiv nof i8 %a, %b %cmp = icmp eq i8 %div, 42 br i1 %cmp, label %if, label %end Index: test/Transforms/SimplifyCFG/multiple-phis.ll =================================================================== --- test/Transforms/SimplifyCFG/multiple-phis.ll +++ test/Transforms/SimplifyCFG/multiple-phis.ll @@ -16,7 +16,7 @@ ; CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY]], label [[WHILE_END:%.*]] ; CHECK: while.body: ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[LOW_0]], [[HIGH_ADDR_0]] -; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[ADD]], 2 +; CHECK-NEXT: [[DIV:%.*]] = udiv nof i32 [[ADD]], 2 ; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[DIV]] to i64 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[R:%.*]], i64 [[IDXPROM]] ; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[ARRAYIDX]] @@ -39,7 +39,7 @@ while.body: ; preds = %while.cond %add = add i32 %low.0, %high.addr.0 - %div = udiv i32 %add, 2 + %div = udiv nof i32 %add, 2 %idxprom = zext i32 %div to i64 %arrayidx = getelementptr inbounds i32, i32* %r, i64 %idxprom %0 = load i32, i32* %arrayidx Index: test/Transforms/Util/PredicateInfo/pr33456.ll =================================================================== --- test/Transforms/Util/PredicateInfo/pr33456.ll +++ test/Transforms/Util/PredicateInfo/pr33456.ll @@ -20,7 +20,7 @@ ; CHECK-NEXT: br i1 [[TMP8]], label [[TMP9]], label [[TMP9]] ; CHECK: [[DOT0:%.*]] = phi i32 [ [[TMP4]], [[TMP7]] ], [ [[TMP4]], [[TMP7]] ], [ [[DOT1:%.*]], [[TMP13]] ], [ [[TMP4]], [[TMP3]] ] ; CHECK-NEXT: [[TMP10:%.*]] = load i32, i32* @b, align 4 -; CHECK-NEXT: [[TMP11:%.*]] = sdiv i32 [[TMP10]], [[DOT0]] +; CHECK-NEXT: [[TMP11:%.*]] = sdiv nof i32 [[TMP10]], [[DOT0]] ; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i32 [[TMP11]], 0 ; CHECK-NEXT: br i1 [[TMP12]], label [[TMP13]], label [[TMP13]] ; CHECK: [[DOT1]] = phi i32 [ [[DOT0]], [[TMP9]] ], [ [[DOT0]], [[TMP9]] ], [ undef, [[TMP0:%.*]] ] Index: tools/llc/llc.cpp =================================================================== --- tools/llc/llc.cpp +++ tools/llc/llc.cpp @@ -298,6 +298,7 @@ initializeScalarOpts(*Registry); initializeVectorization(*Registry); initializeScalarizeMaskedMemIntrinPass(*Registry); + initializeScalarizeMayOverflowDivPass(*Registry); initializeExpandReductionsPass(*Registry); // Initialize debugging passes. Index: tools/opt/opt.cpp =================================================================== --- tools/opt/opt.cpp +++ tools/opt/opt.cpp @@ -402,6 +402,7 @@ // supported. initializeExpandMemCmpPassPass(Registry); initializeScalarizeMaskedMemIntrinPass(Registry); + initializeScalarizeMayOverflowDivPass(Registry); initializeCodeGenPreparePass(Registry); initializeAtomicExpandPass(Registry); initializeRewriteSymbolsLegacyPassPass(Registry); Index: unittests/IR/ConstantsTest.cpp =================================================================== --- unittests/IR/ConstantsTest.cpp +++ unittests/IR/ConstantsTest.cpp @@ -242,8 +242,8 @@ CHECK(ConstantExpr::getFSub(P1, P1), "fsub float " P1STR ", " P1STR); CHECK(ConstantExpr::getMul(P0, P0), "mul i32 " P0STR ", " P0STR); CHECK(ConstantExpr::getFMul(P1, P1), "fmul float " P1STR ", " P1STR); - CHECK(ConstantExpr::getUDiv(P0, P0), "udiv i32 " P0STR ", " P0STR); - CHECK(ConstantExpr::getSDiv(P0, P0), "sdiv i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getUDiv(P0, P0), "udiv nof i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getSDiv(P0, P0), "sdiv nof i32 " P0STR ", " P0STR); CHECK(ConstantExpr::getFDiv(P1, P1), "fdiv float " P1STR ", " P1STR); CHECK(ConstantExpr::getURem(P0, P0), "urem i32 " P0STR ", " P0STR); CHECK(ConstantExpr::getSRem(P0, P0), "srem i32 " P0STR ", " P0STR); @@ -267,7 +267,8 @@ CHECK(ConstantExpr::getFPExtend(P1, DoubleTy), "fpext float " P1STR " to double"); - CHECK(ConstantExpr::getExactUDiv(P0, P0), "udiv exact i32 " P0STR ", " P0STR); + CHECK(ConstantExpr::getExactUDiv(P0, P0), + "udiv exact nof i32 " P0STR ", " P0STR); CHECK(ConstantExpr::getSelect(P3, P0, P4), "select i1 " P3STR ", i32 " P0STR ", i32 " P4STR);