summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-02-23 17:17:57 +0000
committerDan Gohman <gohman@apple.com>2010-02-23 17:17:57 +0000
commitcd4c03e886755031ea06195d0878b9e81ec74f36 (patch)
tree307b5f5f5572216cddce27937a6cfe9d2a87dc65 /llvm/lib/Transforms
parent2f840382e21177d36f8367a83c9594b75fe5343b (diff)
downloadbcm5719-llvm-cd4c03e886755031ea06195d0878b9e81ec74f36.tar.gz
bcm5719-llvm-cd4c03e886755031ea06195d0878b9e81ec74f36.zip
Don't do (X != Y) ? X : Y -> X for floating-point values; it doesn't
handle NaN properly. Do (X une Y) ? X : Y -> X if one of X and Y is not zero. llvm-svn: 96955
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 7807d9a6334..2fc932594f7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -539,9 +539,18 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
!CFPf->getValueAPF().isZero()))
return ReplaceInstUsesWith(SI, FalseVal);
}
- // Transform (X != Y) ? X : Y -> X
- if (FCI->getPredicate() == FCmpInst::FCMP_ONE)
+ // Transform (X une Y) ? X : Y -> X
+ if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
+ // This is not safe in general for floating point:
+ // consider X== -0, Y== +0.
+ // It becomes safe if either operand is a nonzero constant.
+ ConstantFP *CFPt, *CFPf;
+ if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
+ !CFPt->getValueAPF().isZero()) ||
+ ((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
+ !CFPf->getValueAPF().isZero()))
return ReplaceInstUsesWith(SI, TrueVal);
+ }
// NOTE: if we wanted to, this is where to detect MIN/MAX
} else if (FCI->getOperand(0) == FalseVal && FCI->getOperand(1) == TrueVal){
@@ -557,9 +566,18 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
!CFPf->getValueAPF().isZero()))
return ReplaceInstUsesWith(SI, FalseVal);
}
- // Transform (X != Y) ? Y : X -> Y
- if (FCI->getPredicate() == FCmpInst::FCMP_ONE)
- return ReplaceInstUsesWith(SI, TrueVal);
+ // Transform (X une Y) ? Y : X -> Y
+ if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
+ // This is not safe in general for floating point:
+ // consider X== -0, Y== +0.
+ // It becomes safe if either operand is a nonzero constant.
+ ConstantFP *CFPt, *CFPf;
+ if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
+ !CFPt->getValueAPF().isZero()) ||
+ ((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
+ !CFPf->getValueAPF().isZero()))
+ return ReplaceInstUsesWith(SI, TrueVal);
+ }
// NOTE: if we wanted to, this is where to detect MIN/MAX
}
// NOTE: if we wanted to, this is where to detect ABS
OpenPOWER on IntegriCloud