This is an archive of the discontinued LLVM Phabricator instance.

Treat branch on poison as immediate UB (under an off by default flag)
ClosedPublic

Authored by reames on Oct 18 2021, 12:10 PM.

Details

Summary

The LangRef clearly states that branching on a poison value is immediate undefined behavior, but historically, we have not been consistent about implementing that interpretation in the optimizer. Historically, we used (in some cases) a more relaxed model which essentially looked for provable UB along both paths which was control dependent on the condition. However, we've never been 100% consistent here. For instance SCEV uses the strong model for increments which form AddRecs (and only addrecs).

At the moment, the last big blocker for finally making this switch is enabling the fix landed in D106041. Loop unswitching (in it's classic form) is incorrect as it creates many "branch on poisons" when unswitching conditions originally unreachable within the loop.

This change adds a flag to value tracking which allows to easily test the optimization potential of treating branch on poison as immediate UB. It's intended to help ease work on getting us finally through this transition and avoid multiple independent rediscovers of the same issues.

D111246 shows the test diff impact of enabling this.

Diff Detail

Event Timeline

reames created this revision.Oct 18 2021, 12:10 PM
reames requested review of this revision.Oct 18 2021, 12:10 PM
Herald added a project: Restricted Project. · View Herald TranscriptOct 18 2021, 12:10 PM
fhahn added a subscriber: fhahn.Oct 18 2021, 12:18 PM

Having a flag seems like a good first step to get things going!

Perhaps it would be worth to add the flag to one of the tests from D111246.

Perhaps it would be worth to add the flag to one of the tests from D111246.

Thought about it, but only the SCEV tests are really clear as to *why* the impact happens, and those tests are already complicated enough. Having to version one which happens to change doesn't really seem to add much value as there's a *bunch* of SCEV implementation details you have to dance around, and any one of them could change at any time. Just as an example, SCEV currently handrolls exactly this logic, but applies it only to expressions which happen to be addrecs. An unrelated change to say trip count logic could totally change whether an expression folded to an addrec or not.

This revision is now accepted and ready to land.Oct 23 2021, 1:49 PM
fhahn added a comment.Oct 24 2021, 6:39 AM

Perhaps it would be worth to add the flag to one of the tests from D111246.

Thought about it, but only the SCEV tests are really clear as to *why* the impact happens, and those tests are already complicated enough. Having to version one which happens to change doesn't really seem to add much value as there's a *bunch* of SCEV implementation details you have to dance around, and any one of them could change at any time. Just as an example, SCEV currently handrolls exactly this logic, but applies it only to expressions which happen to be addrecs. An unrelated change to say trip count logic could totally change whether an expression folded to an addrec or not.

Agreed, it's no ideal to have this flag for the more complicated tests.

But I think it would still be good to have at least minimal test coverage for the new flag & code. Perhaps you could add new test with a single function that uses the flag?

This revision was landed with ongoing or failed builds.Oct 24 2021, 2:42 PM
This revision was automatically updated to reflect the committed changes.