summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorJakub Kuderski <jakub.kuderski@arm.com>2015-09-08 10:36:42 +0000
committerJakub Kuderski <jakub.kuderski@arm.com>2015-09-08 10:36:42 +0000
commitf50ab0ffce8fdb58a0859e070ecd660c0ed8f6cd (patch)
treefb67f13728783e97a7604f8e79f022bbf0efa161 /clang/lib/CodeGen
parent3f1153869faa1df53ad0a84f6cfebfeab78cfaff (diff)
downloadbcm5719-llvm-f50ab0ffce8fdb58a0859e070ecd660c0ed8f6cd.tar.gz
bcm5719-llvm-f50ab0ffce8fdb58a0859e070ecd660c0ed8f6cd.zip
findDominatingStoreToReturn in CGCall.cpp didn't check if a candidate store
instruction used the ReturnValue as pointer operand or value operand. This led to wrong code gen - in later stages (load-store elision code) the found store and its operand would be erased, causing ReturnValue to become a <badref>. The patch adds a check that makes sure that ReturnValue is a pointer operand of store instruction. Regression test is also added. This fixes PR24386. Differential Revision: http://reviews.llvm.org/D12400 llvm-svn: 247003
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp25
1 files changed, 14 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index e8760111f01..ef9095291cd 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2259,6 +2259,18 @@ static llvm::Value *emitAutoreleaseOfResult(CodeGenFunction &CGF,
/// Heuristically search for a dominating store to the return-value slot.
static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
+ // Check if a User is a store which pointerOperand is the ReturnValue.
+ // We are looking for stores to the ReturnValue, not for stores of the
+ // ReturnValue to some other location.
+ auto GetStoreIfValid = [&CGF](llvm::User *U) -> llvm::StoreInst * {
+ auto *SI = dyn_cast<llvm::StoreInst>(U);
+ if (!SI || SI->getPointerOperand() != CGF.ReturnValue.getPointer())
+ return nullptr;
+ // These aren't actually possible for non-coerced returns, and we
+ // only care about non-coerced returns on this code path.
+ assert(!SI->isAtomic() && !SI->isVolatile());
+ return SI;
+ };
// If there are multiple uses of the return-value slot, just check
// for something immediately preceding the IP. Sometimes this can
// happen with how we generate implicit-returns; it can also happen
@@ -2287,22 +2299,13 @@ static llvm::StoreInst *findDominatingStoreToReturnValue(CodeGenFunction &CGF) {
break;
}
- llvm::StoreInst *store = dyn_cast<llvm::StoreInst>(I);
- if (!store) return nullptr;
- if (store->getPointerOperand() != CGF.ReturnValue.getPointer())
- return nullptr;
- assert(!store->isAtomic() && !store->isVolatile()); // see below
- return store;
+ return GetStoreIfValid(I);
}
llvm::StoreInst *store =
- dyn_cast<llvm::StoreInst>(CGF.ReturnValue.getPointer()->user_back());
+ GetStoreIfValid(CGF.ReturnValue.getPointer()->user_back());
if (!store) return nullptr;
- // These aren't actually possible for non-coerced returns, and we
- // only care about non-coerced returns on this code path.
- assert(!store->isAtomic() && !store->isVolatile());
-
// Now do a first-and-dirty dominance check: just walk up the
// single-predecessors chain from the current insertion point.
llvm::BasicBlock *StoreBB = store->getParent();
OpenPOWER on IntegriCloud