[llvm] [ADT] Fix a bug in PackedVector::setValue for signed types (PR #159239)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 16 22:12:01 PDT 2025


https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/159239

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.


>From b72c21f147ac1257a61e33d547b4f14eaca8b538 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Tue, 16 Sep 2025 17:37:18 -0700
Subject: [PATCH] [ADT] Fix a bug in PackedVector::setValue for signed types

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/include/llvm/ADT/PackedVector.h    | 2 ++
 llvm/unittests/ADT/PackedVectorTest.cpp | 8 ++++++++
 2 files changed, 10 insertions(+)

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) {



More information about the llvm-commits mailing list