[objc-arc-opts] In the presense of an alloca unconditionally remove RR pairs if and...
authorMichael Gottesman <mgottesman@apple.com>
Mon, 13 May 2013 23:49:42 +0000 (23:49 +0000)
committerMichael Gottesman <mgottesman@apple.com>
Mon, 13 May 2013 23:49:42 +0000 (23:49 +0000)
commitacfb3584c58159ec20a8379c864c9d644f8d967e
tree304995d93e7f1dd7a3b21a8bbd85741543e1c98d
parent9b5e6c0943dcfced64980240e25427cdc06c9bad
[objc-arc-opts] In the presense of an alloca unconditionally remove RR pairs if and only if we are both KnownSafeBU/KnownSafeTD rather than just either or.

In the presense of a block being initialized, the frontend will emit the
objc_retain on the original pointer and the release on the pointer loaded from
the alloca. The optimizer will through the provenance analysis realize that the
two are related (albiet different), but since we only require KnownSafe in one
direction, will match the inner retain on the original pointer with the guard
release on the original pointer. This is fixed by ensuring that in the presense
of allocas we only unconditionally remove pointers if both our retain and our
release are KnownSafe (i.e. we are KnownSafe in both directions) since we must
deal with the possibility that the frontend will emit what (to the optimizer)
appears to be unbalanced retain/releases.

An example of the miscompile is:

  %A = alloca
  retain(%x)
  retain(%x) <--- Inner Retain
  store %x, %A
  %y = load %A
  ... DO STUFF ...
  release(%y)
  call void @use(%x)
  release(%x) <--- Guarding Release

getting optimized to:

  %A = alloca
  retain(%x)
  store %x, %A
  %y = load %A
  ... DO STUFF ...
  release(%y)
  call void @use(%x)

rdar://13750319

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181743 91177308-0d34-0410-b5e6-96231b3b80d8
lib/Transforms/ObjCARC/ObjCARCOpts.cpp
test/Transforms/ObjCARC/allocas.ll [new file with mode: 0644]