This is an archive of the discontinued LLVM Phabricator instance.

[CFLGraph] Change isMallocOrCallocLikeFn to isNoAliasCall now that allocation functions must be marked noalias
Needs ReviewPublic

Authored by Bryce-MW on Jan 11 2022, 8:55 PM.

Details

Reviewers
reames
Summary

Allocation functions must now be marked noalias and any function marked noalias does not introduce aliases. The if condition below like 461 will now always be true because Fn->returnDoesNotAlias() returns the same result as isNoAliasCall(&Call). Since we return early if isNoAliasCall returns true, it will always be false at the point of the condition. I'm happy to restore that condition for safety if wanted.

Diff Detail

Event Timeline

Bryce-MW created this revision.Jan 11 2022, 8:55 PM
Bryce-MW requested review of this revision.Jan 11 2022, 8:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 11 2022, 8:55 PM

Hmm, I expected that Herald would add other reviewers automatically. I'm not sure if I can ask it to do that manually

Bryce-MW updated this revision to Diff 399208.Jan 11 2022, 10:22 PM
  • Rebase to fix failing test on Windows
nikic added a subscriber: nikic.Jan 12 2022, 1:01 AM

I'm not familiar with CFL, but I don't think this was the intention of the code. I think this part tries to reason about inaccessiblememonly/inaccessibleorargmemonly in a clumsy way.

reames requested changes to this revision.Jan 12 2022, 7:53 AM

I agree with @nikic on the intent of the code. This can probably be replaced with a check for inaccessiblememonly instead.

The change as implemented is incorrect. There is no requirement that an noalias call not have other side effects. Example:
define nolias i8* helper(i64 %size, i8* %unrelated) {

%res = call i8* malloc(i64 %size)
store i8 0, i8* %unrelated
ret %res

}

Thanks for looking at this!

This revision now requires changes to proceed.Jan 12 2022, 7:53 AM

Thanks for catching that. I'm glad we have review. For a normal function, it tries interprocedural analysis, if that fails, it looks at the readonly and noalias attributes. I think that allocation functions can go through the same process but just also check Call.onlyAccessesInaccessibleMemory(). This would mean that allocation functions could undergo interprocedural analysis first which would be a functionality change from before.

Bryce-MW updated this revision to Diff 399412.Jan 12 2022, 12:03 PM
  • Use onlyAccessesInaccessibleMemory instead

I went and took a slightly deeper look at this code, and unfortunately, I think we have a couple of interacting issues here we will need to fix if we want to remove the isMallocOrCallocLike check.

Issue 1 - The inter-procedural inference code does not appear to restrict results based on call site attributes. It appears to only look at function attributes. This means that a call site which is annotated inaccessiblememonly to a call which isn't would get the conservative answer, not the precise one.

Issue 2 - The inter-procedural inference code (getAliasSummary) does not appear to incorporate function attributes into the result at all. (I may be misreading this code, it's horribly "generic" and really hard to figure out what it is actually doing.)

Issue 3 - The cumulative result of the previous two is that letting noalias only trigger if inter-procedural doesn't is a regression.

I think what I'd suggest is that rather than removing this code, we focus on simple generalizing it.

I believe the property isMallocOrCallLike is actually checking for here is: a noalias function whose only side effect is inaccessiblememonly. We can generalize the check - with added test coverage - and at least remove the overly specific call.

nikic added a comment.Jan 17 2022, 9:22 AM

It may be worth considering dropping the CFL code entirely. It's not used in a default pipeline, and I rather doubt that this is ever going to change.