This is an archive of the discontinued LLVM Phabricator instance.

LLVM intrinsic for invariants
ClosedPublic

Authored by hfinkel on Dec 5 2012, 4:16 PM.

Details

Reviewers
chandlerc
hfinkel
Summary

Adds void @llvm.invariant(i1 %cond)

Diff Detail

Event Timeline

hfinkel updated this revision to Diff 11338.Jul 12 2014, 10:12 AM
hfinkel added a reviewer: chandlerc.
hfinkel removed a subscriber: chandlerc.

This adds the basic invariant intrinsic, noop lowering, and some basic properties:

  • llvm.invariant(undef) and llvm.invariant(true) are dead
  • llvm.invariant(false) is unreachable (this directly corresponds to the documented behavior of MSVC's __assume(0))

The intrinsic is tagged as writing arbitrarily, in order to maintain control dependencies. BasicAA has been updated, however, to return NoModRef for any particular location-based query so that we don't unnecessarily block code motion.

chandlerc added inline comments.Jul 17 2014, 11:16 AM
docs/LangRef.rst
9304 ↗(On Diff #11590)

I wonder if this would be more clear spelled "llvm.assume.invariant" or just "llvm.assume".

9321–9324 ↗(On Diff #11590)

I think we should provide some minimal guidance for FE authors here that essentially indicates that using this intrinsic is not without cost, and essentially shouldn't be used to either document basic mathematical invariants the compiler could deduce otherwise, or if the invariant holds little or no value to the optimizer.

lib/Transforms/Utils/Local.cpp
305 ↗(On Diff #11590)

If the condition is undef, aren't they unreachable?

test/Transforms/InstSimplify/invariant.ll
3–5 ↗(On Diff #11590)

Indent seems weird here. Use the more common 2-space indent?

hfinkel updated this revision to Diff 11629.Jul 17 2014, 8:36 PM

Updated docs and made invariant(undef) like invariant(false) (instead of like invariant(true)).

hfinkel updated this revision to Diff 11693.Jul 20 2014, 11:56 AM

Renamed to llvm.assume.

reames added a subscriber: reames.Jul 21 2014, 10:04 AM

With a couple of small changes mentioned inline, LGTM.

docs/LangRef.rst
9383 ↗(On Diff #11693)

Why? Suggestion:
Please note that ''llvm.assume'' is not free and may impact the effectiveness of the optimizer in hard to predict ways. ''llvm.assume'' should be used to represent high level facts which are not otherwise available to the optimizer and only after careful consideration of the benefit and costs. In particular, 'llvm.assume'' should not be used to...

I'm not sure I really like my wording around 'free' above, but this is a starting point.

include/llvm/IR/Intrinsics.td
282 ↗(On Diff #11693)

I understand why you're doing this, but it honestly feels like a bit of a hack. Is it possibly time to introduce a notion of control dependence that is not driven by memory access? This is essentially what you've written, but there might be a better way to factor it.

This doesn't need to be changed before submission, I'm just raising it for consideration and discussion.

lib/Analysis/BasicAliasAnalysis.cpp
799 ↗(On Diff #11693)

I've noticed we have multiple isXIntrinsic functions scatter around the code base. We might want to think about - in a separate change - creating an isIntrinsic(IntrinsicID) function on CallSite.

lib/Transforms/Utils/Local.cpp
1199 ↗(On Diff #11693)

Adding a comment on this case would be good. Particularly given that it required discussion to arrive at this being the right semantic.

test/CodeGen/Generic/assume.ll
1 ↗(On Diff #11693)

This test could be stronger. Could you add a FileCheck here?

hfinkel added inline comments.Jul 24 2014, 8:08 AM
docs/LangRef.rst
9383 ↗(On Diff #11693)

Good idea. Instead of "free", I'll say something like, "The optimizer might limit the transformations performed on values used by the intrinsic in order to preserve the instructions only used to form the intrinsic's input argument, and this might prove undesirable if the extra information provided by that intrinsic does cause sufficient overall improvement."

include/llvm/IR/Intrinsics.td
282 ↗(On Diff #11693)

Fixing this is another major infrastructure project. :(

lib/Analysis/BasicAliasAnalysis.cpp
799 ↗(On Diff #11693)

Good idea; I'll queue that for later refactoring.

lib/Transforms/Utils/Local.cpp
1199 ↗(On Diff #11693)

Will do.

test/CodeGen/Generic/assume.ll
1 ↗(On Diff #11693)

No, this is a "generic lowering" test. It runs on all targets to make sure that it does not crash (that the code generator does *something*). You'll find many such tests in that directory.

hfinkel accepted this revision.Jul 24 2014, 8:14 AM
hfinkel added a reviewer: hfinkel.

Philip accepted (with minor updates); I'll commit in the near future.

This revision is now accepted and ready to land.Jul 24 2014, 8:14 AM
hfinkel closed this revision.Jul 25 2014, 2:22 PM

r213973, thanks!