diff --git a/llvm/include/llvm/ADT/DynamicAPInt.h b/llvm/include/llvm/ADT/DynamicAPInt.h index ca010f836de6f..07015b4a8dd80 100644 --- a/llvm/include/llvm/ADT/DynamicAPInt.h +++ b/llvm/include/llvm/ADT/DynamicAPInt.h @@ -16,6 +16,7 @@ #ifndef LLVM_ADT_DYNAMICAPINT_H #define LLVM_ADT_DYNAMICAPINT_H +#include "llvm/ADT/APInt.h" #include "llvm/ADT/SlowDynamicAPInt.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" @@ -116,6 +117,14 @@ class DynamicAPInt { : ValSmall(Val) { ValLarge.Val.BitWidth = 0; } + LLVM_ATTRIBUTE_ALWAYS_INLINE explicit DynamicAPInt(const APInt &Val) { + if (Val.getBitWidth() <= 64) { + ValSmall = Val.getSExtValue(); + ValLarge.Val.BitWidth = 0; + } else { + new (&ValLarge) detail::SlowDynamicAPInt(Val); + } + } LLVM_ATTRIBUTE_ALWAYS_INLINE DynamicAPInt() : DynamicAPInt(0) {} LLVM_ATTRIBUTE_ALWAYS_INLINE ~DynamicAPInt() { if (LLVM_UNLIKELY(isLarge())) diff --git a/llvm/unittests/ADT/DynamicAPIntTest.cpp b/llvm/unittests/ADT/DynamicAPIntTest.cpp index 932b750608b3e..fafd8fda08687 100644 --- a/llvm/unittests/ADT/DynamicAPIntTest.cpp +++ b/llvm/unittests/ADT/DynamicAPIntTest.cpp @@ -31,6 +31,16 @@ class TypeNames { }; TYPED_TEST_SUITE(IntTest, TypeList, TypeNames); +TYPED_TEST(IntTest, ValueInit) { + APInt Large(65, 0, true); + Large.setBit(64); + TypeParam DynLarge(1ll << 63); + EXPECT_EQ(TypeParam(Large), DynLarge + DynLarge); + APInt Small(64, -1, true); + TypeParam DynSmall(Small.getSExtValue()); + EXPECT_EQ(TypeParam(Small), DynSmall); +} + TYPED_TEST(IntTest, ops) { TypeParam Two(2), Five(5), Seven(7), Ten(10); EXPECT_EQ(Five + Five, Ten);