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
This commit is contained in:
Pete Cooper 2016-05-27 02:13:53 +00:00
parent 6fd1e53381
commit 604ae0b712
2 changed files with 28 additions and 1 deletions

View File

@ -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

View File

@ -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 }