summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-04-29 18:40:34 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-04-29 18:40:34 +0000
commitd2a074b1f463806a2c0e6a56b950a73635350fe7 (patch)
treed43d6d9933360a03eda503b86fdc0552a2581f15 /llvm/lib/Analysis
parent10c4f451a8c0d96a83e31b309142f9f18e9a582d (diff)
downloadbcm5719-llvm-d2a074b1f463806a2c0e6a56b950a73635350fe7.tar.gz
bcm5719-llvm-d2a074b1f463806a2c0e6a56b950a73635350fe7.zip
[ValueTracking] matchSelectPattern needs to be more careful around FP
matchSelectPattern attempts to see through casts which mask min/max patterns from being more obvious. Under certain circumstances, it would misidentify a sequence of instructions as a min/max because it assumed that folding casts would preserve the result. This is not the case for floating point <-> integer casts. This fixes PR27575. llvm-svn: 268086
Diffstat (limited to 'llvm/lib/Analysis')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp50
1 files changed, 31 insertions, 19 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index c616e091290..feddbafa0d5 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3699,12 +3699,11 @@ static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2,
Instruction::CastOps *CastOp) {
CastInst *CI = dyn_cast<CastInst>(V1);
Constant *C = dyn_cast<Constant>(V2);
- CastInst *CI2 = dyn_cast<CastInst>(V2);
if (!CI)
return nullptr;
*CastOp = CI->getOpcode();
- if (CI2) {
+ if (auto *CI2 = dyn_cast<CastInst>(V2)) {
// If V1 and V2 are both the same cast from the same type, we can look
// through V1.
if (CI2->getOpcode() == CI->getOpcode() &&
@@ -3715,39 +3714,52 @@ static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2,
return nullptr;
}
- if (isa<SExtInst>(CI) && CmpI->isSigned()) {
- Constant *T = ConstantExpr::getTrunc(C, CI->getSrcTy());
- // This is only valid if the truncated value can be sign-extended
- // back to the original value.
- if (ConstantExpr::getSExt(T, C->getType()) == C)
- return T;
- return nullptr;
- }
if (isa<ZExtInst>(CI) && CmpI->isUnsigned())
return ConstantExpr::getTrunc(C, CI->getSrcTy());
if (isa<TruncInst>(CI))
return ConstantExpr::getIntegerCast(C, CI->getSrcTy(), CmpI->isSigned());
+ if (isa<FPTruncInst>(CI))
+ return ConstantExpr::getFPExtend(C, CI->getSrcTy(), true);
+
+ if (isa<FPExtInst>(CI))
+ return ConstantExpr::getFPTrunc(C, CI->getSrcTy(), true);
+
+ // Sophisticated constants can have values which we cannot easily reason
+ // about. Skip them for the fp<->int case.
+ if (isa<ConstantExpr>(C))
+ return nullptr;
+
+ Constant *CastedTo = nullptr;
+
+ // This is only valid if the truncated value can be sign-extended
+ // back to the original value.
+ if (isa<SExtInst>(CI) && CmpI->isSigned())
+ CastedTo = ConstantExpr::getTrunc(C, CI->getSrcTy(), true);
+
if (isa<FPToUIInst>(CI))
- return ConstantExpr::getUIToFP(C, CI->getSrcTy(), true);
+ CastedTo = ConstantExpr::getUIToFP(C, CI->getSrcTy(), true);
if (isa<FPToSIInst>(CI))
- return ConstantExpr::getSIToFP(C, CI->getSrcTy(), true);
+ CastedTo = ConstantExpr::getSIToFP(C, CI->getSrcTy(), true);
if (isa<UIToFPInst>(CI))
- return ConstantExpr::getFPToUI(C, CI->getSrcTy(), true);
+ CastedTo = ConstantExpr::getFPToUI(C, CI->getSrcTy(), true);
if (isa<SIToFPInst>(CI))
- return ConstantExpr::getFPToSI(C, CI->getSrcTy(), true);
+ CastedTo = ConstantExpr::getFPToSI(C, CI->getSrcTy(), true);
- if (isa<FPTruncInst>(CI))
- return ConstantExpr::getFPExtend(C, CI->getSrcTy(), true);
+ if (!CastedTo)
+ return nullptr;
- if (isa<FPExtInst>(CI))
- return ConstantExpr::getFPTrunc(C, CI->getSrcTy(), true);
+ Constant *CastedBack =
+ ConstantExpr::getCast(CI->getOpcode(), CastedTo, C->getType(), true);
+ // Make sure the cast doesn't lose any information.
+ if (CastedBack != C)
+ return nullptr;
- return nullptr;
+ return CastedTo;
}
SelectPatternResult llvm::matchSelectPattern(Value *V,
OpenPOWER on IntegriCloud