diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-04-22 06:37:51 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-04-22 06:37:51 +0000 |
commit | d0ce8f1485e0bf6ed850926216bd34cec4e57c08 (patch) | |
tree | 1cddf3ab87e566ab83eb2129b62a5b3f4d5acf4c /llvm/lib | |
parent | 68318e0414dbafb61f92a3f1f1b3882efb0cb38f (diff) | |
download | bcm5719-llvm-d0ce8f1485e0bf6ed850926216bd34cec4e57c08.tar.gz bcm5719-llvm-d0ce8f1485e0bf6ed850926216bd34cec4e57c08.zip |
[GVN] Respect fast-math-flags on fcmps
We assumed that flags were only present on binary operators. This is
not true, they may also be present on calls and fcmps.
llvm-svn: 267113
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/IR/Instruction.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/GVN.cpp | 43 |
2 files changed, 40 insertions, 32 deletions
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp index dd28b5c506a..f90ebec06bd 100644 --- a/llvm/lib/IR/Instruction.cpp +++ b/llvm/lib/IR/Instruction.cpp @@ -217,32 +217,41 @@ void Instruction::copyFastMathFlags(const Instruction *I) { void Instruction::copyIRFlags(const Value *V) { // Copy the wrapping flags. if (auto *OB = dyn_cast<OverflowingBinaryOperator>(V)) { - setHasNoSignedWrap(OB->hasNoSignedWrap()); - setHasNoUnsignedWrap(OB->hasNoUnsignedWrap()); + if (isa<OverflowingBinaryOperator>(this)) { + setHasNoSignedWrap(OB->hasNoSignedWrap()); + setHasNoUnsignedWrap(OB->hasNoUnsignedWrap()); + } } // Copy the exact flag. if (auto *PE = dyn_cast<PossiblyExactOperator>(V)) - setIsExact(PE->isExact()); + if (isa<PossiblyExactOperator>(this)) + setIsExact(PE->isExact()); // Copy the fast-math flags. if (auto *FP = dyn_cast<FPMathOperator>(V)) - copyFastMathFlags(FP->getFastMathFlags()); + if (isa<FPMathOperator>(this)) + copyFastMathFlags(FP->getFastMathFlags()); } void Instruction::andIRFlags(const Value *V) { if (auto *OB = dyn_cast<OverflowingBinaryOperator>(V)) { - setHasNoSignedWrap(hasNoSignedWrap() & OB->hasNoSignedWrap()); - setHasNoUnsignedWrap(hasNoUnsignedWrap() & OB->hasNoUnsignedWrap()); + if (isa<OverflowingBinaryOperator>(this)) { + setHasNoSignedWrap(hasNoSignedWrap() & OB->hasNoSignedWrap()); + setHasNoUnsignedWrap(hasNoUnsignedWrap() & OB->hasNoUnsignedWrap()); + } } if (auto *PE = dyn_cast<PossiblyExactOperator>(V)) - setIsExact(isExact() & PE->isExact()); + if (isa<PossiblyExactOperator>(this)) + setIsExact(isExact() & PE->isExact()); if (auto *FP = dyn_cast<FPMathOperator>(V)) { - FastMathFlags FM = getFastMathFlags(); - FM &= FP->getFastMathFlags(); - copyFastMathFlags(FM); + if (isa<FPMathOperator>(this)) { + FastMathFlags FM = getFastMathFlags(); + FM &= FP->getFastMathFlags(); + copyFastMathFlags(FM); + } } } diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index 02e18abd332..2d4af732520 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -1725,30 +1725,29 @@ bool GVN::processAssumeIntrinsic(IntrinsicInst *IntrinsicI) { } static void patchReplacementInstruction(Instruction *I, Value *Repl) { + auto *ReplInst = dyn_cast<Instruction>(Repl); + if (!ReplInst) + return; + // Patch the replacement so that it is not more restrictive than the value // being replaced. - BinaryOperator *Op = dyn_cast<BinaryOperator>(I); - BinaryOperator *ReplOp = dyn_cast<BinaryOperator>(Repl); - if (Op && ReplOp) - ReplOp->andIRFlags(Op); - - if (Instruction *ReplInst = dyn_cast<Instruction>(Repl)) { - // FIXME: If both the original and replacement value are part of the - // same control-flow region (meaning that the execution of one - // guarantees the execution of the other), then we can combine the - // noalias scopes here and do better than the general conservative - // answer used in combineMetadata(). - - // In general, GVN unifies expressions over different control-flow - // regions, and so we need a conservative combination of the noalias - // scopes. - static const unsigned KnownIDs[] = { - LLVMContext::MD_tbaa, LLVMContext::MD_alias_scope, - LLVMContext::MD_noalias, LLVMContext::MD_range, - LLVMContext::MD_fpmath, LLVMContext::MD_invariant_load, - LLVMContext::MD_invariant_group}; - combineMetadata(ReplInst, I, KnownIDs); - } + ReplInst->andIRFlags(I); + + // FIXME: If both the original and replacement value are part of the + // same control-flow region (meaning that the execution of one + // guarantees the execution of the other), then we can combine the + // noalias scopes here and do better than the general conservative + // answer used in combineMetadata(). + + // In general, GVN unifies expressions over different control-flow + // regions, and so we need a conservative combination of the noalias + // scopes. + static const unsigned KnownIDs[] = { + LLVMContext::MD_tbaa, LLVMContext::MD_alias_scope, + LLVMContext::MD_noalias, LLVMContext::MD_range, + LLVMContext::MD_fpmath, LLVMContext::MD_invariant_load, + LLVMContext::MD_invariant_group}; + combineMetadata(ReplInst, I, KnownIDs); } static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl) { |