[PATCH] D23362: FIx UB in APInt::ashr

Jonathan Roelofs via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 10 12:46:01 PDT 2016


jroelofs updated this revision to Diff 67578.
jroelofs added a comment.

Use `SignExtend64()`


https://reviews.llvm.org/D23362

Files:
  lib/Support/APInt.cpp
  unittests/ADT/APIntTest.cpp

Index: unittests/ADT/APIntTest.cpp
===================================================================
--- unittests/ADT/APIntTest.cpp
+++ unittests/ADT/APIntTest.cpp
@@ -32,6 +32,11 @@
   EXPECT_FALSE(Shl[1]);
 }
 
+TEST(APIntTest, i64_ArithmeticRightShiftNegative) {
+  const APInt neg_one(64, static_cast<uint64_t>(-1), true);
+  EXPECT_EQ(neg_one, neg_one.ashr(7));
+}
+
 TEST(APIntTest, i128_NegativeCount) {
   APInt Minus3(128, static_cast<uint64_t>(-3), true);
   EXPECT_EQ(126u, Minus3.countLeadingOnes());
Index: lib/Support/APInt.cpp
===================================================================
--- lib/Support/APInt.cpp
+++ lib/Support/APInt.cpp
@@ -1042,11 +1042,7 @@
   if (isSingleWord()) {
     if (shiftAmt == BitWidth)
       return APInt(BitWidth, 0); // undefined
-    else {
-      unsigned SignBit = APINT_BITS_PER_WORD - BitWidth;
-      return APInt(BitWidth,
-        (((int64_t(VAL) << SignBit) >> SignBit) >> shiftAmt));
-    }
+    return APInt(BitWidth, SignExtend64(VAL, BitWidth) >> shiftAmt);
   }
 
   // If all the bits were shifted out, the result is, technically, undefined.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23362.67578.patch
Type: text/x-patch
Size: 1118 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160810/9aca223a/attachment.bin>


More information about the llvm-commits mailing list