This is an archive of the discontinued LLVM Phabricator instance.

[WIP][ConstantRange] Add support for multiply and left shift with nowrap flags
Needs ReviewPublic

Authored by reames on Jul 15 2022, 9:19 AM.

Details

Reviewers
nikic
fhahn
Summary

This patch adds support for multiply and left shift variants which use NoWrap flags to restrict the range returned. It directly follows the pattern already taken for add/sub, and extends it to mul/shl.

This is a WIP for two major reasons, both of which I'd appreciate some input on.

  1. I don't understand the bits in add/sub about being required to return empty ranges on definite overflow. I can see that from a precision perspective, but since both the 2s complement and saturating variants are valid implementations of the no-wrap behavior, it seems like intersecting them should always be valid. Am I right here? Or is my code subtly wrong?
  2. Suggestions on how to test this? I glanced at the ConstantRangeTest file, and am looking for specific guidance on which exhaustive test harness to use. This file has gotten quite complicated.

Once complete, I plan to use this in SCEV to help refine the ranges returned for multiplies.

Diff Detail

Event Timeline

reames created this revision.Jul 15 2022, 9:19 AM
reames requested review of this revision.Jul 15 2022, 9:19 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 15 2022, 9:19 AM

I don't understand the bits in add/sub about being required to return empty ranges on definite overflow. I can see that from a precision perspective, but since both the 2s complement and saturating variants are valid implementations of the no-wrap behavior, it seems like intersecting them should always be valid. Am I right here? Or is my code subtly wrong?

There is no requirement to return an empty range. I believe the existing code is only pedantic about this so that tests can prove both correctness and optimality.

Suggestions on how to test this? I glanced at the ConstantRangeTest file, and am looking for specific guidance on which exhaustive test harness to use. This file has gotten quite complicated.

The generic testing framework is TestBinaryOpExhaustive. For the second callback, return an Optional<APInt> only if no overflow occurs. For the third callback, you probably want PreferSmallestUnsigned or PreferSmallestSigned depending on the PreferredRangeType. The fourth one depends on whether your implementation provides optimal results, at least for some subsets.