Page MenuHomePhabricator

[ConstantRange] Add `ushl_sat()`/`sshl_sat()` methods.
ClosedPublic

Authored by lebedev.ri on Thu, Nov 7, 12:16 PM.

Details

Summary

To be used in ConstantRange::shlWithNoOverflow(),
may in future be useful for when saturating shift/mul ops are added.

Unlike ConstantRange::shl(), these are precise.

Diff Detail

Event Timeline

lebedev.ri created this revision.Thu, Nov 7, 12:16 PM
nikic added a comment.Thu, Nov 7, 12:48 PM

Unlike ConstantRange::shl(), these are precise.

At least when modelling the APInt semantics. If we treat too large shifts as poison, then we could produce empty sets in more cases. But this seems like a reasonable starting point...

llvm/lib/IR/ConstantRange.cpp
1359

Wondering if a formulation along the lines of

APInt Min = getSignedMin(), Max = getSignedMax();
APInt ShiftMin = getUnsignedMin(), ShiftMax = getUnsignedMax();
APInt NewL = Min.sshl_sat(Min.isNonNegative() ? ShiftMin : ShiftMax);
APInt NewU = Max.sshl_sat(Max.isNonNegative() ? ShiftMax : ShiftMin) + 1;

might be cleaner?

lebedev.ri updated this revision to Diff 228295.Thu, Nov 7, 1:15 PM
lebedev.ri marked 2 inline comments as done.

Cleanup sshl_sat() with ternaries as suggested.

Unlike ConstantRange::shl(), these are precise.

At least when modelling the APInt semantics. If we treat too large shifts as poison, then we could produce empty sets in more cases.

Yeah, i think this might be a good thing to do, but later, more globally.

But this seems like a reasonable starting point...

This comment was removed by lebedev.ri.
llvm/lib/IR/ConstantRange.cpp
1359

A bit, yes.

nikic accepted this revision.Thu, Nov 7, 2:22 PM

LGTM

llvm/lib/IR/ConstantRange.cpp
1352

Mild preference for using Min.isNonNegative() and Max.isNegative() here, because it makes the relationship to the shifted value clear. Also fine as-is though.

This revision is now accepted and ready to land.Thu, Nov 7, 2:22 PM
This revision was automatically updated to reflect the committed changes.