InstSimplify: Simplify trivial pointer expressions like b + (e - b)

consider:
long long *f(long long *b, long long *e) {
  return b + (e - b);
}

we would lower this to something like:
define i64* @f(i64* %b, i64* %e) {
  %1 = ptrtoint i64* %e to i64
  %2 = ptrtoint i64* %b to i64
  %3 = sub i64 %1, %2
  %4 = ashr exact i64 %3, 3
  %5 = getelementptr inbounds i64* %b, i64 %4
  ret i64* %5
}

This should fold away to just 'e'.

N.B.  This adds m_SpecificInt as a convenient way to match against a
particular 64-bit integer when using LLVM's match interface.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216439 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer
2014-08-26 05:55:16 +00:00
parent 2db57b44de
commit 594e4a1dd3
3 changed files with 96 additions and 5 deletions

View File

@@ -362,6 +362,29 @@ struct bind_const_intval_ty {
}
};
/// Match a specified integer value or vector of all elements of that value.
struct specific_intval {
uint64_t Val;
specific_intval(uint64_t V) : Val(V) {}
template<typename ITy>
bool match(ITy *V) {
ConstantInt *CI = dyn_cast<ConstantInt>(V);
if (!CI && V->getType()->isVectorTy())
if (const auto *C = dyn_cast<Constant>(V))
CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue());
if (CI && CI->getBitWidth() <= 64)
return CI->getZExtValue() == Val;
return false;
}
};
/// Match a specific integer value or vector with all elements equal to the
/// value.
inline specific_intval m_SpecificInt(uint64_t V) { return specific_intval(V); }
/// m_ConstantInt - Match a ConstantInt and bind to its value. This does not
/// match ConstantInts wider than 64-bits.
inline bind_const_intval_ty m_ConstantInt(uint64_t &V) { return V; }