diff options
-rw-r--r-- | llvm/include/llvm/IR/InstrTypes.h | 6 | ||||
-rw-r--r-- | llvm/lib/IR/Instructions.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 2 |
3 files changed, 24 insertions, 3 deletions
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h index 7ef245cbc46..83c5e5cc13f 100644 --- a/llvm/include/llvm/IR/InstrTypes.h +++ b/llvm/include/llvm/IR/InstrTypes.h @@ -360,7 +360,11 @@ public: /// Convenience method to copy supported wrapping, exact, and fast-math flags /// from V to this instruction. - void copyFlags(const Value *V); + void copyIRFlags(const Value *V); + + /// Logical 'and' of any supported wrapping, exact, and fast-math flags of + /// V and this instruction. + void andIRFlags(const Value *V); // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index b113d51d416..be32dee0638 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -2030,7 +2030,7 @@ bool BinaryOperator::isExact() const { return cast<PossiblyExactOperator>(this)->isExact(); } -void BinaryOperator::copyFlags(const Value *V) { +void BinaryOperator::copyIRFlags(const Value *V) { // Copy the wrapping flags. if (auto *OB = dyn_cast<OverflowingBinaryOperator>(V)) { setHasNoSignedWrap(OB->hasNoSignedWrap()); @@ -2046,6 +2046,23 @@ void BinaryOperator::copyFlags(const Value *V) { copyFastMathFlags(FP->getFastMathFlags()); } +void BinaryOperator::andIRFlags(const Value *V) { + if (auto *OB = dyn_cast<OverflowingBinaryOperator>(V)) { + setHasNoSignedWrap(hasNoSignedWrap() & OB->hasNoSignedWrap()); + setHasNoUnsignedWrap(hasNoUnsignedWrap() & OB->hasNoUnsignedWrap()); + } + + if (auto *PE = dyn_cast<PossiblyExactOperator>(V)) + setIsExact(isExact() & PE->isExact()); + + if (auto *FP = dyn_cast<FPMathOperator>(V)) { + FastMathFlags FM = getFastMathFlags(); + FM &= FP->getFastMathFlags(); + copyFastMathFlags(FM); + } +} + + //===----------------------------------------------------------------------===// // FPMathOperator Class //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index ba330128788..f2d928ca0bb 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -3249,7 +3249,7 @@ void InnerLoopVectorizer::vectorizeBlockInLoop(BasicBlock *BB, PhiVector *PV) { Value *V = Builder.CreateBinOp(BinOp->getOpcode(), A[Part], B[Part]); if (BinaryOperator *VecOp = dyn_cast<BinaryOperator>(V)) - VecOp->copyFlags(BinOp); + VecOp->copyIRFlags(BinOp); Entry[Part] = V; } |