This is an archive of the discontinued LLVM Phabricator instance.

[ConstantRange] Use APInt::or/APInt::and for single elements.
ClosedPublic

Authored by fhahn on Mar 19 2020, 12:29 PM.

Details

Summary

Currently ConstantRange::binaryAnd/binaryOr results are too pessimistic
for single element constant ranges.

If both operands are single element ranges, we can use APInt's AND and
OR implementations directly.

Note that some other binary operations on constant ranges can cover the
single element cases naturally, but for OR and AND this unfortunately is
not the case.

Diff Detail

Event Timeline

fhahn created this revision.Mar 19 2020, 12:29 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 19 2020, 12:29 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
spatel accepted this revision.Mar 19 2020, 1:13 PM

LGTM as well.

This revision is now accepted and ready to land.Mar 19 2020, 1:13 PM
nikic added a comment.Mar 19 2020, 1:15 PM

I'd like to see a unit test that exhaustively tests this for all binary operators (or the ones where it holds). I don't think single element ranges are handled accurately for all the ops (e.g. probably not for urem/srem?)

fhahn added a comment.Mar 19 2020, 1:45 PM

I'd like to see a unit test that exhaustively tests this for all binary operators (or the ones where it holds). I don't think single element ranges are handled accurately for all the ops (e.g. probably not for urem/srem?)

Yes, ideally we would handle all single element ranges in ConstantRange::binaryOp directly, by delegating to APInt, rather than doing it separately for each one I think. Maybe we should add an APInt::binaryOp? Or just dispatch in ConstantRange::binaryOp?

nikic added a comment.Mar 19 2020, 4:21 PM

I'd like to see a unit test that exhaustively tests this for all binary operators (or the ones where it holds). I don't think single element ranges are handled accurately for all the ops (e.g. probably not for urem/srem?)

Yes, ideally we would handle all single element ranges in ConstantRange::binaryOp directly, by delegating to APInt, rather than doing it separately for each one I think. Maybe we should add an APInt::binaryOp?

I don't think that's possible due to layering. APInt is in Support, so it can't depend on IR.

Or just dispatch in ConstantRange::binaryOp?

We probably don't want to make binaryOp() more powerful than the individual methods, so I think your current approach is already fine.

fhahn added a comment.Apr 1 2020, 1:34 AM

I'd like to see a unit test that exhaustively tests this for all binary operators (or the ones where it holds). I don't think single element ranges are handled accurately for all the ops (e.g. probably not for urem/srem?)

Yes, ideally we would handle all single element ranges in ConstantRange::binaryOp directly, by delegating to APInt, rather than doing it separately for each one I think. Maybe we should add an APInt::binaryOp?

I don't think that's possible due to layering. APInt is in Support, so it can't depend on IR.

Or just dispatch in ConstantRange::binaryOp?

We probably don't want to make binaryOp() more powerful than the individual methods, so I think your current approach is already fine.

Agreed! I'll go ahead and commit this as is for now. Happy to iterate on this post-commit as well

This revision was automatically updated to reflect the committed changes.