make ConstantRange::signExtend() optimal
authorNuno Lopes <nunoplopes@sapo.pt>
Wed, 30 Oct 2013 15:36:50 +0000 (15:36 +0000)
committerNuno Lopes <nunoplopes@sapo.pt>
Wed, 30 Oct 2013 15:36:50 +0000 (15:36 +0000)
the case [x, INT_MIN) was not handled optimally

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193694 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/ConstantRange.cpp
unittests/Support/ConstantRangeTest.cpp

index 1085a45d0a2df9e2b63e52dcb23542a3854c2999..e3b43ed6df6178dd614eb921ca715b98a96172ad 100644 (file)
@@ -445,6 +445,11 @@ ConstantRange ConstantRange::signExtend(uint32_t DstTySize) const {
 
   unsigned SrcTySize = getBitWidth();
   assert(SrcTySize < DstTySize && "Not a value extension");
+
+  // special case: [X, INT_MIN) -- not really wrapping around
+  if (Upper == APInt::getHighBitsSet(SrcTySize, 1))
+    return ConstantRange(Lower.sext(DstTySize), Upper.zext(DstTySize));
+
   if (isFullSet() || isSignWrappedSet()) {
     return ConstantRange(APInt::getHighBitsSet(DstTySize,DstTySize-SrcTySize+1),
                          APInt::getLowBitsSet(DstTySize, SrcTySize-1) + 1);
index 4d6bbf6f8402b745453f81b3f357f12e3e8c9723..3e0a085ed1e7f853288a57fc097d23a45f0cbc70 100644 (file)
@@ -216,6 +216,9 @@ TEST_F(ConstantRangeTest, SExt) {
 
   EXPECT_EQ(ConstantRange(APInt(8, 120), APInt(8, 140)).signExtend(16),
             ConstantRange(APInt(16, -128), APInt(16, 128)));
+
+  EXPECT_EQ(ConstantRange(APInt(16, 0x0200), APInt(16, 0x8000)).signExtend(19),
+            ConstantRange(APInt(19, 0x0200), APInt(19, 0x8000)));
 }
 
 TEST_F(ConstantRangeTest, IntersectWith) {