aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/ValueTracking.cpp
diff options
context:
space:
mode:
authorNikolai Bozhenov <nikolai.bozhenov@intel.com>2017-10-18 09:28:09 +0000
committerNikolai Bozhenov <nikolai.bozhenov@intel.com>2017-10-18 09:28:09 +0000
commit74c047eabb17b75cac6d6e9537b8e6e51e750880 (patch)
treee981c5d8946f48aa35314c1fd94d740248c5d8cc /llvm/lib/Analysis/ValueTracking.cpp
parent480892b75fc15ee435b4b689a0021bb5f5fd7166 (diff)
downloadllvm-74c047eabb17b75cac6d6e9537b8e6e51e750880.zip
llvm-74c047eabb17b75cac6d6e9537b8e6e51e750880.tar.gz
llvm-74c047eabb17b75cac6d6e9537b8e6e51e750880.tar.bz2
Improve lookThroughCast function.
Summary: When we have the following case: %cond = cmp iN %x, CmpConst %tr = trunc iN %x to iK %narrowsel = select i1 %cond, iK %t, iK C We could possibly match only min/max pattern after looking through cast. So it is more profitable if widened C constant will be equal CmpConst. That is why just set widened C constant equal to CmpConst, because there is a further check in this function that trunc CmpConst == C. Also description for lookTroughCast function was added. Reviewers: spatel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D38536 Patch by: Artur Gainullin <artur.gainullin@intel.com> llvm-svn: 316070
Diffstat (limited to 'llvm/lib/Analysis/ValueTracking.cpp')
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp42
1 files changed, 41 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f70f2d1..55a7a35 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4320,6 +4320,20 @@ static SelectPatternResult matchSelectPattern(CmpInst::Predicate Pred,
return matchFastFloatClamp(Pred, CmpLHS, CmpRHS, TrueVal, FalseVal, LHS, RHS);
}
+/// Helps to match a select pattern in case of a type mismatch.
+///
+/// The function processes the case when type of true and false values of a
+/// select instruction differs from type of the cmp instruction operands because
+/// of a cast instructon. The function checks if it is legal to move the cast
+/// operation after "select". If yes, it returns the new second value of
+/// "select" (with the assumption that cast is moved):
+/// 1. As operand of cast instruction when both values of "select" are same cast
+/// instructions.
+/// 2. As restored constant (by applying reverse cast operation) when the first
+/// value of the "select" is a cast operation and the second value is a
+/// constant.
+/// NOTE: We return only the new second value because the first value could be
+/// accessed as operand of cast instruction.
static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2,
Instruction::CastOps *CastOp) {
auto *Cast1 = dyn_cast<CastInst>(V1);
@@ -4350,7 +4364,33 @@ static Value *lookThroughCast(CmpInst *CmpI, Value *V1, Value *V2,
CastedTo = ConstantExpr::getTrunc(C, SrcTy, true);
break;
case Instruction::Trunc:
- CastedTo = ConstantExpr::getIntegerCast(C, SrcTy, CmpI->isSigned());
+ Constant *CmpConst;
+ if (match(CmpI->getOperand(1), m_Constant(CmpConst))) {
+ // Here we have the following case:
+ //
+ // %cond = cmp iN %x, CmpConst
+ // %tr = trunc iN %x to iK
+ // %narrowsel = select i1 %cond, iK %t, iK C
+ //
+ // We can always move trunc after select operation:
+ //
+ // %cond = cmp iN %x, CmpConst
+ // %widesel = select i1 %cond, iN %x, iN CmpConst
+ // %tr = trunc iN %widesel to iK
+ //
+ // Note that C could be extended in any way because we don't care about
+ // upper bits after truncation. It can't be abs pattern, because it would
+ // look like:
+ //
+ // select i1 %cond, x, -x.
+ //
+ // So only min/max pattern could be matched. Such match requires widened C
+ // == CmpConst. That is why set widened C = CmpConst, condition trunc
+ // CmpConst == C is checked below.
+ CastedTo = CmpConst;
+ } else {
+ CastedTo = ConstantExpr::getIntegerCast(C, SrcTy, CmpI->isSigned());
+ }
break;
case Instruction::FPTrunc:
CastedTo = ConstantExpr::getFPExtend(C, SrcTy, true);