diff --git a/llvm/include/llvm/IR/Instruction.h b/llvm/include/llvm/IR/Instruction.h --- a/llvm/include/llvm/IR/Instruction.h +++ b/llvm/include/llvm/IR/Instruction.h @@ -495,6 +495,10 @@ /// V and this instruction. void andIRFlags(const Value *V); + /// Logical 'and' of non poison generating flags, like fast-math flags, of + /// V and this instruction. + void andNonPoisonGeneratingIRFlags(const Value *V); + /// Merge 2 debug locations and apply it to the Instruction. If the /// instruction is a CallIns, we need to traverse the inline chain to find /// the common scope. This is not efficient for N-way merging as each time diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -316,6 +316,16 @@ DestGEP->setIsInBounds(SrcGEP->isInBounds() || DestGEP->isInBounds()); } +void Instruction::andNonPoisonGeneratingIRFlags(const Value *V) { + if (auto *FP = dyn_cast(V)) { + if (isa(this)) { + FastMathFlags FM = getFastMathFlags(); + FM &= FP->getFastMathFlags(); + copyFastMathFlags(FM); + } + } +} + void Instruction::andIRFlags(const Value *V) { if (auto *OB = dyn_cast(V)) { if (isa(this)) { @@ -328,17 +338,11 @@ if (isa(this)) setIsExact(isExact() && PE->isExact()); - if (auto *FP = dyn_cast(V)) { - if (isa(this)) { - FastMathFlags FM = getFastMathFlags(); - FM &= FP->getFastMathFlags(); - copyFastMathFlags(FM); - } - } - if (auto *SrcGEP = dyn_cast(V)) if (auto *DestGEP = dyn_cast(this)) DestGEP->setIsInBounds(SrcGEP->isInBounds() && DestGEP->isInBounds()); + + andNonPoisonGeneratingIRFlags(V); } const char *Instruction::getOpcodeName(unsigned OpCode) {