This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] avoid crash from deleting an instruction that still has uses (PR43723)
ClosedPublic

Authored by spatel on Nov 7 2019, 4:15 PM.

Details

Summary

This whole thing seems fragile, but I've never looked at this code before this.

We gather a set of white-listed instructions in isAllocSiteRemovable() and then replace/erase them. But we don't know in general if the instructions in the set have uses amongst themselves, so order of deletion makes a difference.

There's already a special-case for the llvm.objectsize intrinsic, so add another for llvm.invariant.end.

Should fix:
https://bugs.llvm.org/show_bug.cgi?id=43723

Diff Detail

Event Timeline

spatel created this revision.Nov 7 2019, 4:15 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 7 2019, 4:15 PM

How confident are we that there aren't other uses of the return value of llvm.invariant.start?

How confident are we that there aren't other uses of the return value of llvm.invariant.start?

Personally, I'm not confident because I haven't looked at these before:
http://llvm.org/docs/LangRef.html#memory-use-markers

But based on my initial reading, only invariant.end is meant to use invariant.start? We could assert that the 'end' has a corresponding 'start' and that it is the only user?

spatel marked an inline comment as done.Nov 8 2019, 12:04 PM
spatel added inline comments.
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
2332–2336

For reference - these are the potential intrinsics that we can encounter in the code below. The 'default' case says we can't see anything outside of this set.

I'd be more comfortable if we actually verified the uses of the invariant.start.

(As far as I can tell, the other possible instructions/intrinsics are either explicitly handled, or have a void return value.)

spatel updated this revision to Diff 228515.Nov 8 2019, 1:36 PM

Patch updated:
Try harder to verify that a llvm.invariant.start is used as expected by llvm.invariant.end. If so, delete both at the same time. If not, don't try to delete the 'start'.

efriedma added inline comments.Nov 8 2019, 1:57 PM
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
2412

Is it not too late here? I would have thought we need to check in isAllocSiteRemovable.

spatel updated this revision to Diff 228520.Nov 8 2019, 2:34 PM
spatel marked 2 inline comments as done.

Patch updated:
Don't put an unexpected llvm.invariant.start in the kill list to begin with.

llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
2412

I'm not imagining how it would fail, but checking sooner definitely seems more efficient than nested loops. Will change.

efriedma accepted this revision.Nov 8 2019, 2:45 PM

LGTM

This revision is now accepted and ready to land.Nov 8 2019, 2:45 PM
This revision was automatically updated to reflect the committed changes.