This is an archive of the discontinued LLVM Phabricator instance.

Revert "[CaptureTracking] Ignore ephemeral values when determining pointer escapeness"
AbandonedPublic

Authored by fhahn on Jun 21 2023, 1:17 PM.

Details

Summary

This reverts commit 17fdaccccfad9b143e4aadbcdda7f645de127153.

Unfortunately the commit (D123162) introduced a mis-compile (see
llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll). The
issue is roughly:

  1. There's a call to a readonly function that takes a pointer argument and its result is only used by an assume, so the call is considered ephemeral and not capturing.
  2. Because the call doesn't capture the pointer, it's considered to not read the pointer, causing DSE to remove the store before the call.
  3. Now the called function gets inlined and there's now a load from the pointer, but the initializing store has been removed
  4. This leads to SROA replacing the load with undef, which will cause the function to get folded to unreachable by subsequent optimizations.

This is a mis-compile potentially impacting Clang builds with ThinLTO +
PGO.

I think as long as the call considered as ephemeral is not removed, we
need to be conservative. To address the correctness issue quickly, I
think we should revert the patch (as this patch does, it doens't revert
cleanly) and potentially consider what subset of ephemeral values we can
allow here or if we should clean up ephemeral calls sooner/avoid
inlining them.

Diff Detail

Event Timeline

fhahn created this revision.Jun 21 2023, 1:17 PM
fhahn requested review of this revision.Jun 21 2023, 1:17 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 21 2023, 1:17 PM
aeubanks accepted this revision.Jun 21 2023, 1:46 PM
This revision is now accepted and ready to land.Jun 21 2023, 1:46 PM
aeubanks added inline comments.Jun 21 2023, 2:27 PM
llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll
24–25

remove comment

Because the call doesn't capture the pointer, it's considered to not read the pointer

this part doesn't make sense, DSE must be conflating the two somehow (but only for ephemeral values?)

fhahn updated this revision to Diff 533412.Jun 21 2023, 2:55 PM

Remove FIXME, update assmue.ll checks.

Because the call doesn't capture the pointer, it's considered to not read the pointer

this part doesn't make sense, DSE must be conflating the two somehow (but only for ephemeral values?)

I think AA uses capture tracking to rule out aliasing for function calls if a local object hasn't been captured.

fhahn marked an inline comment as done.Jun 21 2023, 2:55 PM
fhahn added inline comments.
llvm/test/Transforms/PhaseOrdering/dse-ephemeral-value-captures.ll
24–25

Removed, thanks!

The problematic interaction is probably with this code: https://github.com/llvm/llvm-project/blob/88f07a311947f88de82ad2de9b2d6a26eba21343/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L880-L886 It assumes that non-nocapture/byval arguments have already been covered by the capture check.

nikic added a comment.Jun 22 2023, 1:15 AM

The problematic interaction is probably with this code: https://github.com/llvm/llvm-project/blob/88f07a311947f88de82ad2de9b2d6a26eba21343/llvm/lib/Analysis/BasicAliasAnalysis.cpp#L880-L886 It assumes that non-nocapture/byval arguments have already been covered by the capture check.

I tried dropping the check, and that doesn't seem to have significant compile-time impact: http://llvm-compile-time-tracker.com/compare.php?from=565c7525b9d642867837d5715c10afed2fa73970&to=1adcff6949aecc85f098f0a324389b7f48be0b7c&stat=instructions:u There are some changes to code size though.

I think this short-circuiting of non-noncapture arguments could also become a problem with certain extensions to CaptureTracking -- e.g. if for readnone/noreturn calls we did not require a void return but instead followed the return value. We'd also get wrong results in that case.

nikic added a comment.Oct 31 2023, 4:41 AM

Could you please rebase over https://github.com/llvm/llvm-project/commit/deb5bd1289404e8ca751127672d9380a6203b880? In https://github.com/llvm/llvm-project/issues/70547 a variant of this issue was found that was not fixed by D153511 (and that D153577 would not have fixed either).

As such, I think we probably do need to land this patch.

I think the way to recover the original motivating case would be to make CaptureTracking return whether the capture is a ProvenanceEscape or an AddressCapture, consider icmp an AddressCapture only, and only consider ProvenanceEscape for DSE/AA. I think the icmp semantics we want are that just a pointer icmp cannot leak provenance of the pointer, regardless of whether it will end up getting used in an assume or not.

I don't mind reverting this, it was mitigating an issue with libc++-sprinkled assumes which has since been reverted.

fhahn marked an inline comment as done.Oct 31 2023, 11:21 AM

Yep, we also found a case internally recently that was only fixed by this patch. Will update in a the next few days when I am back in the office