Skip to content

Commit 9c6e441

Browse files
committed
[GR-46028] Properly handle stamps with only high bit set
PullRequest: graal/14525
2 parents 6e1a761 + fe94952 commit 9c6e441

File tree

2 files changed

+54
-28
lines changed

2 files changed

+54
-28
lines changed

compiler/src/jdk.internal.vm.compiler.test/src/org/graalvm/compiler/nodes/test/IntegerStampTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,4 +777,26 @@ public void testCanBeZero13() {
777777
IntegerStamp union = (IntegerStamp) stampWithZero.meet(stampWithoutZero);
778778
assertCanBeZero(union);
779779
}
780+
781+
/**
782+
* Check that a stamp that only allows the high bit to be set properly handles a range that
783+
* crosses 0 but doesn't include the min value.
784+
*/
785+
@Test
786+
public void testHighBitOnly() {
787+
for (int shift = 0, initialBits = 8; shift < 4; shift++) {
788+
int bits = initialBits << shift;
789+
long lo = CodeUtil.minValue(bits) + 1;
790+
long mustBeSet = 0L;
791+
long mayBeSet = 1L << ((bits) - 1);
792+
for (long hi = -1; hi < 1; hi++) {
793+
IntegerStamp s = IntegerStamp.create(bits, lo, hi, mustBeSet, mayBeSet, true);
794+
if (hi == 0) {
795+
Assert.assertTrue("Stamp = " + s, s.contains(0L));
796+
} else {
797+
Assert.assertTrue("Stamp = " + s, s.isEmpty());
798+
}
799+
}
800+
}
801+
}
780802
}

compiler/src/jdk.internal.vm.compiler/src/org/graalvm/compiler/core/common/type/IntegerStamp.java

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -390,39 +390,43 @@ private static long setOptionalBits(int bits, long bound, long mustBeSet, long m
390390
*/
391391
private static long computeLowerBound(int bits, long lowerBound, long mustBeSet, long mayBeSet, boolean canBeZero) {
392392
long newLowerBound = minValueForMasks(bits, mustBeSet, mayBeSet);
393+
final long optionalBits = mayBeSet & ~mustBeSet & CodeUtil.mask(bits - 1);
393394
if (newLowerBound < lowerBound) {
394-
// First find the largest value which is less the current bound
395-
final long optionalBits = mayBeSet & ~mustBeSet & CodeUtil.mask(bits - 1);
396-
for (int position = bits - 1; position >= 0; position--) {
397-
long bit = 1L << position;
398-
if ((bit & optionalBits) != 0) {
399-
if (newLowerBound + bit <= lowerBound) {
400-
newLowerBound += bit;
395+
if (optionalBits == 0) {
396+
newLowerBound = 0;
397+
} else {
398+
// First find the largest value which is less than or equal to the current bound
399+
for (int position = bits - 1; position >= 0; position--) {
400+
long bit = 1L << position;
401+
if ((bit & optionalBits) != 0) {
402+
if (newLowerBound + bit <= lowerBound) {
403+
newLowerBound += bit;
404+
}
401405
}
402406
}
403-
}
404-
GraalError.guarantee(newLowerBound <= lowerBound, "should have been sufficient");
405-
if (newLowerBound < lowerBound) {
406-
// Increment the first optional bit and then adjust the bits upward until it's
407-
// compatible with the masks
408-
boolean incremented = false;
409-
for (int position = 0; position < bits - 1; position++) {
410-
long bit = 1L << position;
411-
if (incremented) {
412-
// We have to propagate any carried bit that changed any bits which must
413-
// be set or cleared.
414-
if ((bit & mustBeSet) != 0 && (newLowerBound & bit) == 0) {
415-
// A mustBeSet bit has been cleared so set it
416-
newLowerBound |= bit;
417-
}
418-
if ((bit & mayBeSet) == 0 && (newLowerBound & bit) != 0) {
419-
// A bit has carried into the clear section so it needs to propagate
420-
// into an mayBeSet bit.
407+
GraalError.guarantee(newLowerBound <= lowerBound, "should have been sufficient");
408+
if (newLowerBound < lowerBound) {
409+
// Increment the first optional bit and then adjust the bits upward until it's
410+
// compatible with the masks
411+
boolean incremented = false;
412+
for (int position = 0; position < bits - 1; position++) {
413+
long bit = 1L << position;
414+
if (incremented) {
415+
// We have to propagate any carried bit that changed any bits which must
416+
// be set or cleared.
417+
if ((bit & mustBeSet) != 0 && (newLowerBound & bit) == 0) {
418+
// A mustBeSet bit has been cleared so set it
419+
newLowerBound |= bit;
420+
}
421+
if ((bit & mayBeSet) == 0 && (newLowerBound & bit) != 0) {
422+
// A bit has carried into the clear section so it needs to propagate
423+
// into an mayBeSet bit.
424+
newLowerBound += bit;
425+
}
426+
} else if ((bit & optionalBits) != 0) {
421427
newLowerBound += bit;
428+
incremented = true;
422429
}
423-
} else if ((bit & optionalBits) != 0) {
424-
newLowerBound += bit;
425-
incremented = true;
426430
}
427431
}
428432
}

0 commit comments

Comments
 (0)