diff options
author | Piotr Padlewski <piotr.padlewski@gmail.com> | 2017-04-24 19:37:17 +0000 |
---|---|---|
committer | Piotr Padlewski <piotr.padlewski@gmail.com> | 2017-04-24 19:37:17 +0000 |
commit | 610c966a4e90775860e9c3eb91efbd6b1e0dd28b (patch) | |
tree | c84ced328dd0f77856db909a5fb3f13a69e9828f /llvm/lib/IR/Value.cpp | |
parent | 9e536081fe7d66304913d8118a1123340f2b74e3 (diff) | |
download | bcm5719-llvm-610c966a4e90775860e9c3eb91efbd6b1e0dd28b.tar.gz bcm5719-llvm-610c966a4e90775860e9c3eb91efbd6b1e0dd28b.zip |
Handle invariant.group.barrier in BasicAA
Summary:
llvm.invariant.group.barrier returns pointer that mustalias
pointer it takes. It can't be marked with `returned` attribute,
because it would be remove easily. The other reason is that
only Alias Analysis can know about this, because if any other
pass would know it, then the result would be replaced with it's
argument, which would be invalid.
We can think about returned pointer as something that mustalias, but
it doesn't have to be bitwise the same as the argument.
Reviewers: dberlin, chandlerc, hfinkel, sanjoy
Subscribers: reames, nlewycky, rsmith, anna, amharc
Differential Revision: https://reviews.llvm.org/D31585
llvm-svn: 301227
Diffstat (limited to 'llvm/lib/IR/Value.cpp')
-rw-r--r-- | llvm/lib/IR/Value.cpp | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index b07c57685a2..d83bdf2acd4 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -432,6 +432,7 @@ namespace { enum PointerStripKind { PSK_ZeroIndices, PSK_ZeroIndicesAndAliases, + PSK_ZeroIndicesAndAliasesAndBarriers, PSK_InBoundsConstantIndices, PSK_InBounds }; @@ -450,6 +451,7 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) { if (auto *GEP = dyn_cast<GEPOperator>(V)) { switch (StripKind) { case PSK_ZeroIndicesAndAliases: + case PSK_ZeroIndicesAndAliasesAndBarriers: case PSK_ZeroIndices: if (!GEP->hasAllZeroIndices()) return V; @@ -472,12 +474,20 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) { return V; V = GA->getAliasee(); } else { - if (auto CS = ImmutableCallSite(V)) + if (auto CS = ImmutableCallSite(V)) { if (const Value *RV = CS.getReturnedArgOperand()) { V = RV; continue; } - + // The result of invariant.group.barrier must alias it's argument, + // but it can't be marked with returned attribute, that's why it needs + // special case. + if (StripKind == PSK_ZeroIndicesAndAliasesAndBarriers && + CS.getIntrinsicID() == Intrinsic::invariant_group_barrier) { + V = CS.getArgOperand(0); + continue; + } + } return V; } assert(V->getType()->isPointerTy() && "Unexpected operand type!"); @@ -499,6 +509,11 @@ const Value *Value::stripInBoundsConstantOffsets() const { return stripPointerCastsAndOffsets<PSK_InBoundsConstantIndices>(this); } +const Value *Value::stripPointerCastsAndBarriers() const { + return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliasesAndBarriers>( + this); +} + const Value * Value::stripAndAccumulateInBoundsConstantOffsets(const DataLayout &DL, APInt &Offset) const { |