-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[ADT] Fix a bug in PackedVector::setValue for signed types #159239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ADT] Fix a bug in PackedVector::setValue for signed types #159239
Conversation
Without this patch, we forget to update the sign bit. When we assign: Vec[0] = -1; the sign bit is correctly set to 1. Overwriting the same element: Vec[0] = 1; does not update the sign bit, leaving the 4-bit as 0b1001, which reads -2 according to PackedVector's encoding. (It does not use two's complement.) This patch fixes the bug by clearing the sign bit when we are assigning a non-negative value.
@llvm/pr-subscribers-llvm-adt Author: Kazu Hirata (kazutakahirata) ChangesWithout this patch, we forget to update the sign bit. When we assign: Vec[0] = -1; the sign bit is correctly set to 1. Overwriting the same element: Vec[0] = 1; does not update the sign bit, leaving the 4-bit as 0b1001, which reads This patch fixes the bug by clearing the sign bit when we are Full diff: https://github.com/llvm/llvm-project/pull/159239.diff 2 Files Affected:
diff --git a/llvm/include/llvm/ADT/PackedVector.h b/llvm/include/llvm/ADT/PackedVector.h
index 1146cc4bd6d23..4e31d3f098d44 100644
--- a/llvm/include/llvm/ADT/PackedVector.h
+++ b/llvm/include/llvm/ADT/PackedVector.h
@@ -58,6 +58,8 @@ class PackedVectorBase<T, BitNum, BitVectorTy, true> {
if (val < 0) {
val = ~val;
Bits.set((Idx * BitNum) + BitNum - 1);
+ } else {
+ Bits.reset((Idx * BitNum) + BitNum - 1);
}
assert((val >> (BitNum-1)) == 0 && "value is too big");
for (unsigned i = 0; i != BitNum-1; ++i)
diff --git a/llvm/unittests/ADT/PackedVectorTest.cpp b/llvm/unittests/ADT/PackedVectorTest.cpp
index 30fc7c0b6d07f..df2cbf0e7f0f8 100644
--- a/llvm/unittests/ADT/PackedVectorTest.cpp
+++ b/llvm/unittests/ADT/PackedVectorTest.cpp
@@ -71,6 +71,14 @@ TEST(PackedVectorTest, RawBitsSize) {
EXPECT_EQ(12u, Vec.raw_bits().size());
}
+TEST(PackedVectorTest, SignedValueOverwrite) {
+ PackedVector<signed, 4> Vec(1);
+ Vec[0] = -1;
+ EXPECT_EQ(-1, Vec[0]);
+ Vec[0] = 1;
+ EXPECT_EQ(1, Vec[0]);
+}
+
#ifdef EXPECT_DEBUG_DEATH
TEST(PackedVectorTest, UnsignedValues) {
|
val = ~val; | ||
Bits.set((Idx * BitNum) + BitNum - 1); | ||
} else { | ||
Bits.reset((Idx * BitNum) + BitNum - 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd expect signed types to be disallowed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The author seems to mean to support signed types as far as I can tell from PackedVectorBase
.
template <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned>
class PackedVectorBase;
template <typename T, unsigned BitNum, typename BitVectorTy>
class PackedVectorBase<T, BitNum, BitVectorTy, false> {
:
:
};
template <typename T, unsigned BitNum, typename BitVectorTy>
class PackedVectorBase<T, BitNum, BitVectorTy, true> {
:
:
};
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd think that in order to support signed types, we have to take care of sign extension and that merely manipulating the MSB is not enough? I haven't looked at the logic carefully, but this sounds fishy...
That is, if the sign bit is set, we flip the whole value with |
Friendly ping. Thanks! |
Without this patch, we forget to update the sign bit. When we assign: Vec[0] = -1; the sign bit is correctly set to 1. Overwriting the same element: Vec[0] = 1; does not update the sign bit, leaving the 4-bit as 0b1001, which reads -2 according to PackedVector's encoding. (It does not use two's complement.) This patch fixes the bug by clearing the sign bit when we are assigning a non-negative value.
Without this patch, we forget to update the sign bit. When we assign:
Vec[0] = -1;
the sign bit is correctly set to 1. Overwriting the same element:
Vec[0] = 1;
does not update the sign bit, leaving the 4-bit as 0b1001, which reads
-2 according to PackedVector's encoding. (It does not use two's
complement.)
This patch fixes the bug by clearing the sign bit when we are
assigning a non-negative value.