diff options
author | Andreas Jonson <andjo403@hotmail.com> | 2025-08-12 10:05:20 +0200 |
---|---|---|
committer | Andreas Jonson <andjo403@hotmail.com> | 2025-08-12 12:26:35 +0200 |
commit | ca7ffaaeeb54bc350b8e48f4f35b68902dc9868c (patch) | |
tree | bf90cdba2b020a420ae534e1c937a748959a2ef4 /llvm/lib/IR/ConstantRange.cpp | |
parent | 6a81dac65c1c5ee891d0ee8530bd73a63c5fa204 (diff) | |
download | llvm-ca7ffaaeeb54bc350b8e48f4f35b68902dc9868c.zip llvm-ca7ffaaeeb54bc350b8e48f4f35b68902dc9868c.tar.gz llvm-ca7ffaaeeb54bc350b8e48f4f35b68902dc9868c.tar.bz2 |
[ConstantRange] add nuw support to truncate (NFC) (#152990)
Diffstat (limited to 'llvm/lib/IR/ConstantRange.cpp')
-rw-r--r-- | llvm/lib/IR/ConstantRange.cpp | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/llvm/lib/IR/ConstantRange.cpp b/llvm/lib/IR/ConstantRange.cpp index 2fcdbcc6..b454c9a 100644 --- a/llvm/lib/IR/ConstantRange.cpp +++ b/llvm/lib/IR/ConstantRange.cpp @@ -872,7 +872,8 @@ ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const { return ConstantRange(Lower.sext(DstTySize), Upper.sext(DstTySize)); } -ConstantRange ConstantRange::truncate(uint32_t DstTySize) const { +ConstantRange ConstantRange::truncate(uint32_t DstTySize, + unsigned NoWrapKind) const { assert(getBitWidth() > DstTySize && "Not a value truncation"); if (isEmptySet()) return getEmpty(DstTySize); @@ -886,22 +887,36 @@ ConstantRange ConstantRange::truncate(uint32_t DstTySize) const { // We use the non-wrapped set code to analyze the [Lower, MaxValue) part, and // then we do the union with [MaxValue, Upper) if (isUpperWrapped()) { - // If Upper is greater than or equal to MaxValue(DstTy), it covers the whole - // truncated range. - if (Upper.getActiveBits() > DstTySize || Upper.countr_one() == DstTySize) + // If Upper is greater than MaxValue(DstTy), it covers the whole truncated + // range. + if (Upper.getActiveBits() > DstTySize) return getFull(DstTySize); - Union = ConstantRange(APInt::getMaxValue(DstTySize),Upper.trunc(DstTySize)); - UpperDiv.setAllBits(); - - // Union covers the MaxValue case, so return if the remaining range is just - // MaxValue(DstTy). - if (LowerDiv == UpperDiv) - return Union; + // For nuw the two parts are: [0, Upper) \/ [Lower, MaxValue(DstTy)] + if (NoWrapKind & TruncInst::NoUnsignedWrap) { + Union = ConstantRange(APInt::getZero(DstTySize), Upper.trunc(DstTySize)); + UpperDiv = APInt::getOneBitSet(getBitWidth(), DstTySize); + } else { + // If Upper is equal to MaxValue(DstTy), it covers the whole truncated + // range. + if (Upper.countr_one() == DstTySize) + return getFull(DstTySize); + Union = + ConstantRange(APInt::getMaxValue(DstTySize), Upper.trunc(DstTySize)); + UpperDiv.setAllBits(); + // Union covers the MaxValue case, so return if the remaining range is + // just MaxValue(DstTy). + if (LowerDiv == UpperDiv) + return Union; + } } // Chop off the most significant bits that are past the destination bitwidth. if (LowerDiv.getActiveBits() > DstTySize) { + // For trunc nuw if LowerDiv is greater than MaxValue(DstTy), the range is + // outside the whole truncated range. + if (NoWrapKind & TruncInst::NoUnsignedWrap) + return Union; // Mask to just the signficant bits and subtract from LowerDiv/UpperDiv. APInt Adjust = LowerDiv & APInt::getBitsSetFrom(getBitWidth(), DstTySize); LowerDiv -= Adjust; @@ -913,6 +928,10 @@ ConstantRange ConstantRange::truncate(uint32_t DstTySize) const { return ConstantRange(LowerDiv.trunc(DstTySize), UpperDiv.trunc(DstTySize)).unionWith(Union); + if (!LowerDiv.isZero() && NoWrapKind & TruncInst::NoUnsignedWrap) + return ConstantRange(LowerDiv.trunc(DstTySize), APInt::getZero(DstTySize)) + .unionWith(Union); + // The truncated value wraps around. Check if we can do better than fullset. if (UpperDivWidth == DstTySize + 1) { // Clear the MSB so that UpperDiv wraps around. |