summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Doerfert <jdoerfert@anl.gov>2019-06-04 20:21:46 +0000
committerJohannes Doerfert <jdoerfert@anl.gov>2019-06-04 20:21:46 +0000
commit40107ce753ff172f76ceb67da2817868f952c003 (patch)
treef8be654cd5367b4e23558c908b8c3abf91e8bc20
parent29975a2a5d050d1c6a7220844efe8706d1376eb4 (diff)
downloadbcm5719-llvm-40107ce753ff172f76ceb67da2817868f952c003.tar.gz
bcm5719-llvm-40107ce753ff172f76ceb67da2817868f952c003.zip
Introduce Value::stripPointerCastsSameRepresentation
This patch allows current users of Value::stripPointerCasts() to force the result of the function to have the same representation as the value it was called on. This is useful in various cases, e.g., (non-)null checks. In this patch only a single call site was adjusted to fix an existing misuse that would cause nonnull where they may be wrong. Uses in attribute deduction and other areas, e.g., D60047, are to be expected. For a discussion on this topic, please see [0]. [0] http://lists.llvm.org/pipermail/llvm-dev/2018-December/128423.html Reviewers: hfinkel, arsenm, reames Subscribers: wdng, hiraditya, bollu, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D61607 llvm-svn: 362545
-rw-r--r--clang/test/CodeGenOpenCLCXX/addrspace-references.cl2
-rw-r--r--llvm/include/llvm/IR/Value.h13
-rw-r--r--llvm/lib/Analysis/LazyValueInfo.cpp2
-rw-r--r--llvm/lib/IR/Value.cpp13
4 files changed, 26 insertions, 4 deletions
diff --git a/clang/test/CodeGenOpenCLCXX/addrspace-references.cl b/clang/test/CodeGenOpenCLCXX/addrspace-references.cl
index b17e701426e..19aeebe5df6 100644
--- a/clang/test/CodeGenOpenCLCXX/addrspace-references.cl
+++ b/clang/test/CodeGenOpenCLCXX/addrspace-references.cl
@@ -9,6 +9,6 @@ void foo() {
// CHECK: [[REF:%.*]] = alloca i32
// CHECK: store i32 1, i32* [[REF]]
// CHECK: [[REG:%[0-9]+]] = addrspacecast i32* [[REF]] to i32 addrspace(4)*
- // CHECK: call spir_func i32 @_Z3barRU3AS4Kj(i32 addrspace(4)* nonnull dereferenceable(4) [[REG]])
+ // CHECK: call spir_func i32 @_Z3barRU3AS4Kj(i32 addrspace(4)* dereferenceable(4) [[REG]])
bar(1);
}
diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h
index d0de008db26..3f8caa668e5 100644
--- a/llvm/include/llvm/IR/Value.h
+++ b/llvm/include/llvm/IR/Value.h
@@ -493,7 +493,7 @@ public:
/// swifterror attribute.
bool isSwiftError() const;
- /// Strip off pointer casts, all-zero GEPs, and aliases.
+ /// Strip off pointer casts, all-zero GEPs, address space casts, and aliases.
///
/// Returns the original uncasted value. If this is called on a non-pointer
/// value, it returns 'this'.
@@ -503,6 +503,17 @@ public:
static_cast<const Value *>(this)->stripPointerCasts());
}
+ /// Strip off pointer casts, all-zero GEPs, address space casts, and aliases
+ /// but ensures the representation of the result stays the same.
+ ///
+ /// Returns the original uncasted value with the same representation. If this
+ /// is called on a non-pointer value, it returns 'this'.
+ const Value *stripPointerCastsSameRepresentation() const;
+ Value *stripPointerCastsSameRepresentation() {
+ return const_cast<Value *>(static_cast<const Value *>(this)
+ ->stripPointerCastsSameRepresentation());
+ }
+
/// Strip off pointer casts, all-zero GEPs, aliases and invariant group
/// info.
///
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 53e9f49a571..542ff709d47 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -1803,7 +1803,7 @@ LazyValueInfo::getPredicateAt(unsigned Pred, Value *V, Constant *C,
// through would still be correct.
const DataLayout &DL = CxtI->getModule()->getDataLayout();
if (V->getType()->isPointerTy() && C->isNullValue() &&
- isKnownNonZero(V->stripPointerCasts(), DL)) {
+ isKnownNonZero(V->stripPointerCastsSameRepresentation(), DL)) {
if (Pred == ICmpInst::ICMP_EQ)
return LazyValueInfo::False;
else if (Pred == ICmpInst::ICMP_NE)
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index cf32a66c901..9e0a43ce1e3 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -460,6 +460,7 @@ namespace {
enum PointerStripKind {
PSK_ZeroIndices,
PSK_ZeroIndicesAndAliases,
+ PSK_ZeroIndicesAndAliasesSameRepresentation,
PSK_ZeroIndicesAndAliasesAndInvariantGroups,
PSK_InBoundsConstantIndices,
PSK_InBounds
@@ -479,6 +480,7 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
if (auto *GEP = dyn_cast<GEPOperator>(V)) {
switch (StripKind) {
case PSK_ZeroIndicesAndAliases:
+ case PSK_ZeroIndicesAndAliasesSameRepresentation:
case PSK_ZeroIndicesAndAliasesAndInvariantGroups:
case PSK_ZeroIndices:
if (!GEP->hasAllZeroIndices())
@@ -494,8 +496,12 @@ static const Value *stripPointerCastsAndOffsets(const Value *V) {
break;
}
V = GEP->getPointerOperand();
- } else if (Operator::getOpcode(V) == Instruction::BitCast ||
+ } else if (Operator::getOpcode(V) == Instruction::BitCast) {
+ V = cast<Operator>(V)->getOperand(0);
+ } else if (StripKind != PSK_ZeroIndicesAndAliasesSameRepresentation &&
Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
+ // TODO: If we know an address space cast will not change the
+ // representation we could look through it here as well.
V = cast<Operator>(V)->getOperand(0);
} else if (auto *GA = dyn_cast<GlobalAlias>(V)) {
if (StripKind == PSK_ZeroIndices || GA->isInterposable())
@@ -530,6 +536,11 @@ const Value *Value::stripPointerCasts() const {
return stripPointerCastsAndOffsets<PSK_ZeroIndicesAndAliases>(this);
}
+const Value *Value::stripPointerCastsSameRepresentation() const {
+ return stripPointerCastsAndOffsets<
+ PSK_ZeroIndicesAndAliasesSameRepresentation>(this);
+}
+
const Value *Value::stripPointerCastsNoFollowAliases() const {
return stripPointerCastsAndOffsets<PSK_ZeroIndices>(this);
}
OpenPOWER on IntegriCloud