diff options
author | Nikolai Bozhenov <nikolai.bozhenov@intel.com> | 2017-10-18 09:28:09 +0000 |
---|---|---|
committer | Nikolai Bozhenov <nikolai.bozhenov@intel.com> | 2017-10-18 09:28:09 +0000 |
commit | 74c047eabb17b75cac6d6e9537b8e6e51e750880 (patch) | |
tree | e981c5d8946f48aa35314c1fd94d740248c5d8cc /llvm/lib/Analysis/ValueTracking.cpp | |
parent | 480892b75fc15ee435b4b689a0021bb5f5fd7166 (diff) | |
download | llvm-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.cpp | 42 |
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); |