Skip to content

Commit 835946b

Browse files
committed
[ConstantRange] Improve ConstantRange::binaryXor
1 parent 7c32d24 commit 835946b

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

llvm/lib/IR/ConstantRange.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1467,7 +1467,28 @@ ConstantRange ConstantRange::binaryXor(const ConstantRange &Other) const {
14671467
if (isSingleElement() && getSingleElement()->isAllOnes())
14681468
return Other.binaryNot();
14691469

1470-
return fromKnownBits(toKnownBits() ^ Other.toKnownBits(), /*IsSigned*/false);
1470+
KnownBits LHSKnown = toKnownBits();
1471+
KnownBits RHSKnown = Other.toKnownBits();
1472+
KnownBits Known = LHSKnown ^ RHSKnown;
1473+
ConstantRange CR = fromKnownBits(Known, /*IsSigned*/ false);
1474+
// Typically the following code doesn't improve the result if BW = 1.
1475+
if (getBitWidth() == 1)
1476+
return CR;
1477+
1478+
// If LHS is known to be the subset of RHS, treat LHS ^ RHS as RHS -nuw/nsw
1479+
// LHS. If RHS is known to be the subset of LHS, treat LHS ^ RHS as LHS
1480+
// -nuw/nsw RHS.
1481+
if (LHSKnown.getMaxValue().isSubsetOf(RHSKnown.getMinValue()))
1482+
CR = CR.intersectWith(
1483+
Other.subWithNoWrap(*this, OverflowingBinaryOperator::NoUnsignedWrap |
1484+
OverflowingBinaryOperator::NoSignedWrap),
1485+
PreferredRangeType::Unsigned);
1486+
else if (RHSKnown.getMaxValue().isSubsetOf(LHSKnown.getMinValue()))
1487+
CR = CR.intersectWith(
1488+
subWithNoWrap(Other, OverflowingBinaryOperator::NoUnsignedWrap |
1489+
OverflowingBinaryOperator::NoSignedWrap),
1490+
PreferredRangeType::Unsigned);
1491+
return CR;
14711492
}
14721493

14731494
ConstantRange

llvm/test/Transforms/SCCP/pr79696.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ define i1 @constant_range_xor(i64 %a) {
1212
; CHECK: then:
1313
; CHECK-NEXT: [[CTLZ:%.*]] = call i64 @llvm.ctlz.i64(i64 [[A]], i1 true)
1414
; CHECK-NEXT: [[CONV:%.*]] = xor i64 [[CTLZ]], 63
15-
; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i64 [[CONV]], 13
16-
; CHECK-NEXT: ret i1 [[CMP1]]
15+
; CHECK-NEXT: ret i1 false
1716
; CHECK: else:
1817
; CHECK-NEXT: ret i1 false
1918
;

0 commit comments

Comments
 (0)