diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2020-01-22 01:04:47 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2020-01-22 01:32:46 +0300 |
commit | a6492e22711e45f1e60416371f7b5c29be5f508e (patch) | |
tree | e90efdd8bc1f9a4173cf70d88a41b853eebeda60 /llvm/lib/IR/Value.cpp | |
parent | f42994f228d20e787fe1dfab69ab5c59ca9e0868 (diff) | |
download | llvm-a6492e22711e45f1e60416371f7b5c29be5f508e.zip llvm-a6492e22711e45f1e60416371f7b5c29be5f508e.tar.gz llvm-a6492e22711e45f1e60416371f7b5c29be5f508e.tar.bz2 |
[IR] Value::getPointerAlignment(): handle pointer constants
Summary:
New `@test13` in `Attributor/align.ll` is the main motivation - `null` pointer
really does not limit our alignment knowledge, in fact it is fully aligned
since it has no bits set.
Here we don't special-case `null` pointer because it is somewhat controversial
to add one more place where we enforce that `null` pointer is zero,
but instead we do the more general thing of trying to perform constant-fold
of pointer constant to an integer, and perform alignment inferrment on that.
Reviewers: jdoerfert, gchatelet, courbet, sstefan1
Reviewed By: jdoerfert
Subscribers: hiraditya, arphaman, jfb, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D73131
Diffstat (limited to 'llvm/lib/IR/Value.cpp')
-rw-r--r-- | llvm/lib/IR/Value.cpp | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index cf9d08f..8e2d49f 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -729,6 +729,17 @@ MaybeAlign Value::getPointerAlignment(const DataLayout &DL) const { ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0)); return MaybeAlign(CI->getLimitedValue()); } + } else if (auto *CstPtr = dyn_cast<Constant>(this)) { + if (auto *CstInt = dyn_cast_or_null<ConstantInt>(ConstantExpr::getPtrToInt( + const_cast<Constant *>(CstPtr), DL.getIntPtrType(getType()), + /*OnlyIfReduced=*/true))) { + size_t TrailingZeros = CstInt->getValue().countTrailingZeros(); + // While the actual alignment may be large, elsewhere we have + // an arbitrary upper alignmet limit, so let's clamp to it. + return Align(TrailingZeros < Value::MaxAlignmentExponent + ? uint64_t(1) << TrailingZeros + : Value::MaximumAlignment); + } } return llvm::None; } |