summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-04-22 06:37:51 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-04-22 06:37:51 +0000
commitd0ce8f1485e0bf6ed850926216bd34cec4e57c08 (patch)
tree1cddf3ab87e566ab83eb2129b62a5b3f4d5acf4c /llvm/lib
parent68318e0414dbafb61f92a3f1f1b3882efb0cb38f (diff)
downloadbcm5719-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.cpp29
-rw-r--r--llvm/lib/Transforms/Scalar/GVN.cpp43
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) {
OpenPOWER on IntegriCloud