[APInt] Move operator~ out of line to make it better able to reused memory allocation from temporary objects

Summary:
This makes operator~ take the APInt by value so if it came from a temporary APInt the move constructor will get invoked and it will be able to reuse the memory allocation from the temporary.

This is similar to what was already done for 2s complement negation.

Reviewers: hans, davide, RKSimon

Reviewed By: davide

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D30614

llvm-svn: 296997
diff --git a/llvm/unittests/ADT/APIntTest.cpp b/llvm/unittests/ADT/APIntTest.cpp
index a818d26..aa1288e 100644
--- a/llvm/unittests/ADT/APIntTest.cpp
+++ b/llvm/unittests/ADT/APIntTest.cpp
@@ -761,6 +761,30 @@
   }
 }
 
+TEST(APIntTest, rvalue_invert) {
+  // Lamdba to return an APInt by value, but also provide the raw value of the
+  // allocated data.
+  auto getRValue = [](const char *HexString, uint64_t const *&RawData) {
+    APInt V(129, HexString, 16);
+    RawData = V.getRawData();
+    return V;
+  };
+
+  APInt One(129, 1);
+  APInt NegativeTwo(129, -2ULL, true);
+
+  const uint64_t *RawData = nullptr;
+
+  {
+    // ~1 = -2
+    APInt NegL = ~One;
+    EXPECT_EQ(NegL, NegativeTwo);
+
+    APInt NegR = ~getRValue("1", RawData);
+    EXPECT_EQ(NegR, NegativeTwo);
+    EXPECT_EQ(NegR.getRawData(), RawData);
+  }
+}
 
 // Tests different div/rem varaints using scheme (a * b + c) / a
 void testDiv(APInt a, APInt b, APInt c) {