summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPete Cooper <peter_cooper@apple.com>2016-05-27 02:13:53 +0000
committerPete Cooper <peter_cooper@apple.com>2016-05-27 02:13:53 +0000
commit1929b5539aa2e183555baab043c2a2f9601ce6de (patch)
treef20cd78e69b8bfedcb7ae179a179315a6c8362ed
parentb822424f476d86ead8f28cde6f62cdaa759e3aa4 (diff)
downloadbcm5719-llvm-1929b5539aa2e183555baab043c2a2f9601ce6de.tar.gz
bcm5719-llvm-1929b5539aa2e183555baab043c2a2f9601ce6de.zip
Form objc_storeStrong in the presence of bitcasts.
objc_storeStrong can be formed from a sequence such as %0 = tail call i8* @objc_retain(i8* %p) nounwind %tmp = load i8*, i8** @x, align 8 store i8* %0, i8** @x, align 8 tail call void @objc_release(i8* %tmp) nounwind The code was already looking through bitcasts for most of the values involved, but had missed one case where the pointer operand for the store was a bitcast. Ultimately the pointer for the load and store have to be the same value, after stripping casts. llvm-svn: 270955
-rw-r--r--llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp3
-rw-r--r--llvm/test/Transforms/ObjCARC/contract-storestrong.ll26
2 files changed, 28 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index ef70d4c4392..11e2d03e17d 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -201,6 +201,7 @@ static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
// Get the location associated with Load.
MemoryLocation Loc = MemoryLocation::get(Load);
+ auto *LocPtr = Loc.Ptr->stripPointerCasts();
// Walk down to find the store and the release, which may be in either order.
for (auto I = std::next(BasicBlock::iterator(Load)),
@@ -261,7 +262,7 @@ static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
// Then make sure that the pointer we are storing to is Ptr. If so, we
// found our Store!
- if (Store->getPointerOperand() == Loc.Ptr)
+ if (Store->getPointerOperand()->stripPointerCasts() == LocPtr)
continue;
// Otherwise, we have an unknown store to some other ptr that clobbers
diff --git a/llvm/test/Transforms/ObjCARC/contract-storestrong.ll b/llvm/test/Transforms/ObjCARC/contract-storestrong.ll
index aadc3a26539..2b83bdb9bfb 100644
--- a/llvm/test/Transforms/ObjCARC/contract-storestrong.ll
+++ b/llvm/test/Transforms/ObjCARC/contract-storestrong.ll
@@ -217,6 +217,32 @@ entry:
ret i1 %t
}
+; Make sure that we form the store strong even if there are bitcasts on
+; the pointers.
+; CHECK-LABEL: define void @test12(
+; CHECK: entry:
+; CHECK-NEXT: %p16 = bitcast i8** @x to i16**
+; CHECK-NEXT: %tmp16 = load i16*, i16** %p16, align 8
+; CHECK-NEXT: %tmp8 = bitcast i16* %tmp16 to i8*
+; CHECK-NEXT: %p32 = bitcast i8** @x to i32**
+; CHECK-NEXT: %v32 = bitcast i8* %p to i32*
+; CHECK-NEXT: %0 = bitcast i16** %p16 to i8**
+; CHECK-NEXT: tail call void @objc_storeStrong(i8** %0, i8* %p)
+; CHECK-NEXT: ret void
+; CHECK-NEXT: }
+define void @test12(i8* %p) {
+entry:
+ %retain = tail call i8* @objc_retain(i8* %p) nounwind
+ %p16 = bitcast i8** @x to i16**
+ %tmp16 = load i16*, i16** %p16, align 8
+ %tmp8 = bitcast i16* %tmp16 to i8*
+ %p32 = bitcast i8** @x to i32**
+ %v32 = bitcast i8* %retain to i32*
+ store i32* %v32, i32** %p32, align 8
+ tail call void @objc_release(i8* %tmp8) nounwind
+ ret void
+}
+
!0 = !{}
; CHECK: attributes [[NUW]] = { nounwind }
OpenPOWER on IntegriCloud