aboutsummaryrefslogtreecommitdiff
path: root/llvm/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/unittests')
-rw-r--r--llvm/unittests/ADT/BitTest.cpp38
-rw-r--r--llvm/unittests/ADT/STLForwardCompatTest.cpp22
-rw-r--r--llvm/unittests/ADT/StringSwitchTest.cpp8
-rw-r--r--llvm/unittests/Analysis/ValueTrackingTest.cpp10
-rw-r--r--llvm/unittests/CAS/CASTestConfig.cpp14
-rw-r--r--llvm/unittests/CAS/CASTestConfig.h11
-rw-r--r--llvm/unittests/CAS/CMakeLists.txt21
-rw-r--r--llvm/unittests/CAS/OnDiskCommonUtils.h76
-rw-r--r--llvm/unittests/CAS/OnDiskGraphDBTest.cpp310
-rw-r--r--llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp77
-rw-r--r--llvm/unittests/IR/IRBuilderTest.cpp1
11 files changed, 580 insertions, 8 deletions
diff --git a/llvm/unittests/ADT/BitTest.cpp b/llvm/unittests/ADT/BitTest.cpp
index eaed4e1..e8041bb 100644
--- a/llvm/unittests/ADT/BitTest.cpp
+++ b/llvm/unittests/ADT/BitTest.cpp
@@ -270,6 +270,44 @@ TEST(BitTest, BitWidthConstexpr) {
llvm::bit_width_constexpr(std::numeric_limits<uint64_t>::max()) == 64);
}
+TEST(BitTest, BitCeilConstexpr) {
+ static_assert(llvm::bit_ceil_constexpr(0u) == 1);
+ static_assert(llvm::bit_ceil_constexpr(1u) == 1);
+ static_assert(llvm::bit_ceil_constexpr(2u) == 2);
+ static_assert(llvm::bit_ceil_constexpr(3u) == 4);
+ static_assert(llvm::bit_ceil_constexpr(4u) == 4);
+ static_assert(llvm::bit_ceil_constexpr(5u) == 8);
+ static_assert(llvm::bit_ceil_constexpr(6u) == 8);
+ static_assert(llvm::bit_ceil_constexpr(7u) == 8);
+ static_assert(llvm::bit_ceil_constexpr(8u) == 8);
+
+ static_assert(llvm::bit_ceil_constexpr(255u) == 256);
+ static_assert(llvm::bit_ceil_constexpr(256u) == 256);
+ static_assert(llvm::bit_ceil_constexpr(257u) == 512);
+}
+
+TEST(BitTest, CountrZeroConstexpr) {
+ static_assert(llvm::countr_zero_constexpr(0u) == 32);
+ static_assert(llvm::countr_zero_constexpr(1u) == 0);
+ static_assert(llvm::countr_zero_constexpr(2u) == 1);
+ static_assert(llvm::countr_zero_constexpr(3u) == 0);
+ static_assert(llvm::countr_zero_constexpr(4u) == 2);
+ static_assert(llvm::countr_zero_constexpr(8u) == 3);
+ static_assert(llvm::countr_zero_constexpr(0x80000000u) == 31);
+
+ static_assert(llvm::countr_zero_constexpr(0ull) == 64);
+ static_assert(llvm::countr_zero_constexpr(1ull) == 0);
+ static_assert(llvm::countr_zero_constexpr(0x100000000ull) == 32);
+ static_assert(llvm::countr_zero_constexpr(0x8000000000000000ull) == 63);
+
+ static_assert(
+ llvm::countr_zero_constexpr(std::numeric_limits<uint16_t>::max()) == 0);
+ static_assert(
+ llvm::countr_zero_constexpr(std::numeric_limits<uint32_t>::max()) == 0);
+ static_assert(
+ llvm::countr_zero_constexpr(std::numeric_limits<uint64_t>::max()) == 0);
+}
+
TEST(BitTest, CountlZero) {
uint8_t Z8 = 0;
uint16_t Z16 = 0;
diff --git a/llvm/unittests/ADT/STLForwardCompatTest.cpp b/llvm/unittests/ADT/STLForwardCompatTest.cpp
index 4a8f53c..2a97e8d 100644
--- a/llvm/unittests/ADT/STLForwardCompatTest.cpp
+++ b/llvm/unittests/ADT/STLForwardCompatTest.cpp
@@ -184,4 +184,26 @@ TEST(TransformTest, ToUnderlying) {
static_assert(llvm::to_underlying(E3::B3) == 0);
}
+TEST(STLForwardCompatTest, IdentityCxx20) {
+ llvm::identity_cxx20 identity;
+
+ // Test with an lvalue.
+ int X = 42;
+ int &Y = identity(X);
+ EXPECT_EQ(&X, &Y);
+
+ // Test with a const lvalue.
+ const int CX = 10;
+ const int &CY = identity(CX);
+ EXPECT_EQ(&CX, &CY);
+
+ // Test with an rvalue.
+ EXPECT_EQ(identity(123), 123);
+
+ // Test perfect forwarding.
+ static_assert(std::is_same_v<int &, decltype(identity(X))>);
+ static_assert(std::is_same_v<const int &, decltype(identity(CX))>);
+ static_assert(std::is_same_v<int &&, decltype(identity(int(5)))>);
+}
+
} // namespace
diff --git a/llvm/unittests/ADT/StringSwitchTest.cpp b/llvm/unittests/ADT/StringSwitchTest.cpp
index 0fbf371..d88a0ff 100644
--- a/llvm/unittests/ADT/StringSwitchTest.cpp
+++ b/llvm/unittests/ADT/StringSwitchTest.cpp
@@ -159,7 +159,7 @@ TEST(StringSwitchTest, Cases) {
return llvm::StringSwitch<OSType>(S)
.Cases(StringLiteral::withInnerNUL("wind\0ws"), "win32", "winnt",
OSType::Windows)
- .Cases("linux", "unix", "*nix", "posix", OSType::Linux)
+ .Cases({"linux", "unix", "*nix", "posix"}, OSType::Linux)
.Cases({"macos", "osx"}, OSType::MacOS)
.Default(OSType::Unknown);
};
@@ -191,7 +191,7 @@ TEST(StringSwitchTest, CasesLower) {
return llvm::StringSwitch<OSType>(S)
.CasesLower(StringLiteral::withInnerNUL("wind\0ws"), "win32", "winnt",
OSType::Windows)
- .CasesLower("linux", "unix", "*nix", "posix", OSType::Linux)
+ .CasesLower({"linux", "unix", "*nix", "posix"}, OSType::Linux)
.CasesLower({"macos", "osx"}, OSType::MacOS)
.Default(OSType::Unknown);
};
@@ -230,13 +230,13 @@ TEST(StringSwitchTest, CasesCopies) {
// Check that evaluating multiple cases does not cause unnecessary copies.
unsigned NumCopies = 0;
- llvm::StringSwitch<Copyable, void>("baz").Cases("foo", "bar", "baz", "qux",
+ llvm::StringSwitch<Copyable, void>("baz").Cases({"foo", "bar", "baz", "qux"},
Copyable{NumCopies});
EXPECT_EQ(NumCopies, 1u);
NumCopies = 0;
llvm::StringSwitch<Copyable, void>("baz").CasesLower(
- "Foo", "Bar", "Baz", "Qux", Copyable{NumCopies});
+ {"Foo", "Bar", "Baz", "Qux"}, Copyable{NumCopies});
EXPECT_EQ(NumCopies, 1u);
}
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 559a0b7..bb0280ee 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1091,6 +1091,16 @@ TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison) {
}
}
+TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_splat) {
+ parseAssembly(
+ "define <4 x i32> @test(i32 noundef %x) {\n"
+ " %ins = insertelement <4 x i32> poison, i32 %x, i32 0\n"
+ " %A = shufflevector <4 x i32> %ins, <4 x i32> poison, <4 x i32> zeroinitializer\n"
+ " ret <4 x i32> %A\n"
+ "}");
+ EXPECT_TRUE(isGuaranteedNotToBeUndefOrPoison(A));
+}
+
TEST_F(ValueTrackingTest, isGuaranteedNotToBeUndefOrPoison_assume) {
parseAssembly("declare i1 @f_i1()\n"
"declare i32 @f_i32()\n"
diff --git a/llvm/unittests/CAS/CASTestConfig.cpp b/llvm/unittests/CAS/CASTestConfig.cpp
index 29e2db4..91d0970 100644
--- a/llvm/unittests/CAS/CASTestConfig.cpp
+++ b/llvm/unittests/CAS/CASTestConfig.cpp
@@ -19,3 +19,17 @@ static CASTestingEnv createInMemory(int I) {
INSTANTIATE_TEST_SUITE_P(InMemoryCAS, CASTest,
::testing::Values(createInMemory));
+
+#if LLVM_ENABLE_ONDISK_CAS
+namespace llvm::cas::ondisk {
+extern void setMaxMappingSize(uint64_t Size);
+} // namespace llvm::cas::ondisk
+
+void setMaxOnDiskCASMappingSize() {
+ static std::once_flag Flag;
+ std::call_once(
+ Flag, [] { llvm::cas::ondisk::setMaxMappingSize(100 * 1024 * 1024); });
+}
+#else
+void setMaxOnDiskCASMappingSize() {}
+#endif /* LLVM_ENABLE_ONDISK_CAS */
diff --git a/llvm/unittests/CAS/CASTestConfig.h b/llvm/unittests/CAS/CASTestConfig.h
index 8093a0b..c08968b 100644
--- a/llvm/unittests/CAS/CASTestConfig.h
+++ b/llvm/unittests/CAS/CASTestConfig.h
@@ -18,6 +18,17 @@ struct CASTestingEnv {
std::unique_ptr<llvm::cas::ActionCache> Cache;
};
+void setMaxOnDiskCASMappingSize();
+
+// Test fixture for on-disk data base tests.
+class OnDiskCASTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ // Use a smaller database size for testing to conserve disk space.
+ setMaxOnDiskCASMappingSize();
+ }
+};
+
class CASTest
: public testing::TestWithParam<std::function<CASTestingEnv(int)>> {
protected:
diff --git a/llvm/unittests/CAS/CMakeLists.txt b/llvm/unittests/CAS/CMakeLists.txt
index ee40e6c..da469f7 100644
--- a/llvm/unittests/CAS/CMakeLists.txt
+++ b/llvm/unittests/CAS/CMakeLists.txt
@@ -1,3 +1,19 @@
+set(ONDISK_CAS_TEST_SOURCES
+ OnDiskGraphDBTest.cpp
+ OnDiskDataAllocatorTest.cpp
+ OnDiskKeyValueDBTest.cpp
+ OnDiskTrieRawHashMapTest.cpp
+ ProgramTest.cpp
+ )
+
+set(LLVM_OPTIONAL_SOURCES
+ ${ONDISK_CAS_TEST_SOURCES}
+ )
+
+if (NOT LLVM_ENABLE_ONDISK_CAS)
+ unset(ONDISK_CAS_TEST_SOURCES)
+endif()
+
set(LLVM_LINK_COMPONENTS
Support
CAS
@@ -8,9 +24,8 @@ add_llvm_unittest(CASTests
ActionCacheTest.cpp
CASTestConfig.cpp
ObjectStoreTest.cpp
- OnDiskDataAllocatorTest.cpp
- OnDiskTrieRawHashMapTest.cpp
- ProgramTest.cpp
+
+ ${ONDISK_CAS_TEST_SOURCES}
)
target_link_libraries(CASTests PRIVATE LLVMTestingSupport)
diff --git a/llvm/unittests/CAS/OnDiskCommonUtils.h b/llvm/unittests/CAS/OnDiskCommonUtils.h
new file mode 100644
index 0000000..57c8c22
--- /dev/null
+++ b/llvm/unittests/CAS/OnDiskCommonUtils.h
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file Helper functions to test OnDiskCASDatabases.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CAS/BuiltinObjectHasher.h"
+#include "llvm/CAS/OnDiskGraphDB.h"
+#include "llvm/Support/BLAKE3.h"
+#include "llvm/Testing/Support/Error.h"
+
+namespace llvm::unittest::cas {
+
+using namespace llvm::cas;
+using namespace llvm::cas::ondisk;
+
+using HasherT = BLAKE3;
+using HashType = decltype(HasherT::hash(std::declval<ArrayRef<uint8_t> &>()));
+using ValueType = std::array<char, 20>;
+
+inline HashType digest(StringRef Data, ArrayRef<ArrayRef<uint8_t>> RefHashes) {
+ return BuiltinObjectHasher<HasherT>::hashObject(
+ RefHashes, arrayRefFromStringRef<char>(Data));
+}
+
+inline ObjectID digest(OnDiskGraphDB &DB, StringRef Data,
+ ArrayRef<ObjectID> Refs) {
+ SmallVector<ArrayRef<uint8_t>, 8> RefHashes;
+ for (ObjectID Ref : Refs)
+ RefHashes.push_back(DB.getDigest(Ref));
+ HashType Digest = digest(Data, RefHashes);
+ std::optional<ObjectID> ID;
+ EXPECT_THAT_ERROR(DB.getReference(Digest).moveInto(ID), Succeeded());
+ return *ID;
+}
+
+inline HashType digest(StringRef Data) {
+ return HasherT::hash(arrayRefFromStringRef(Data));
+}
+
+inline ValueType valueFromString(StringRef S) {
+ ValueType Val;
+ llvm::copy(S.substr(0, sizeof(Val)), Val.data());
+ return Val;
+}
+
+inline Expected<ObjectID> store(OnDiskGraphDB &DB, StringRef Data,
+ ArrayRef<ObjectID> Refs) {
+ ObjectID ID = digest(DB, Data, Refs);
+ if (Error E = DB.store(ID, Refs, arrayRefFromStringRef<char>(Data)))
+ return std::move(E);
+ return ID;
+}
+
+inline Error printTree(OnDiskGraphDB &DB, ObjectID ID, raw_ostream &OS,
+ unsigned Indent = 0) {
+ std::optional<ondisk::ObjectHandle> Obj;
+ if (Error E = DB.load(ID).moveInto(Obj))
+ return E;
+ if (!Obj)
+ return Error::success();
+ OS.indent(Indent) << toStringRef(DB.getObjectData(*Obj)) << '\n';
+ for (ObjectID Ref : DB.getObjectRefs(*Obj)) {
+ if (Error E = printTree(DB, Ref, OS, Indent + 2))
+ return E;
+ }
+ return Error::success();
+}
+
+} // namespace llvm::unittest::cas
diff --git a/llvm/unittests/CAS/OnDiskGraphDBTest.cpp b/llvm/unittests/CAS/OnDiskGraphDBTest.cpp
new file mode 100644
index 0000000..58f5dcc6
--- /dev/null
+++ b/llvm/unittests/CAS/OnDiskGraphDBTest.cpp
@@ -0,0 +1,310 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CASTestConfig.h"
+#include "OnDiskCommonUtils.h"
+#include "llvm/Testing/Support/Error.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::cas;
+using namespace llvm::cas::ondisk;
+using namespace llvm::unittest::cas;
+
+TEST_F(OnDiskCASTest, OnDiskGraphDBTest) {
+ unittest::TempDir Temp("ondiskcas", /*Unique=*/true);
+ std::unique_ptr<OnDiskGraphDB> DB;
+ ASSERT_THAT_ERROR(
+ OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType)).moveInto(DB),
+ Succeeded());
+
+ auto digest = [&DB](StringRef Data, ArrayRef<ObjectID> Refs) -> ObjectID {
+ return ::digest(*DB, Data, Refs);
+ };
+
+ auto store = [&](StringRef Data,
+ ArrayRef<ObjectID> Refs) -> Expected<ObjectID> {
+ return ::store(*DB, Data, Refs);
+ };
+
+ std::optional<ObjectID> ID1;
+ ASSERT_THAT_ERROR(store("hello", {}).moveInto(ID1), Succeeded());
+
+ std::optional<ondisk::ObjectHandle> Obj1;
+ ASSERT_THAT_ERROR(DB->load(*ID1).moveInto(Obj1), Succeeded());
+ ASSERT_TRUE(Obj1.has_value());
+ EXPECT_EQ(toStringRef(DB->getObjectData(*Obj1)), "hello");
+
+ ArrayRef<uint8_t> Digest1 = DB->getDigest(*ID1);
+ std::optional<ObjectID> ID2;
+ ASSERT_THAT_ERROR(DB->getReference(Digest1).moveInto(ID2), Succeeded());
+ EXPECT_EQ(ID1, ID2);
+
+ ObjectID ID3 = digest("world", {});
+ EXPECT_FALSE(DB->containsObject(ID3));
+ std::optional<ondisk::ObjectHandle> Obj2;
+ ASSERT_THAT_ERROR(DB->load(ID3).moveInto(Obj2), Succeeded());
+ EXPECT_FALSE(Obj2.has_value());
+
+ ASSERT_THAT_ERROR(DB->store(ID3, {}, arrayRefFromStringRef<char>("world")),
+ Succeeded());
+ EXPECT_TRUE(DB->containsObject(ID3));
+ ASSERT_THAT_ERROR(DB->load(ID3).moveInto(Obj2), Succeeded());
+ ASSERT_TRUE(Obj2.has_value());
+ EXPECT_EQ(toStringRef(DB->getObjectData(*Obj2)), "world");
+
+ size_t LargeDataSize = 256LL * 1024LL; // 256K.
+ // The precise size number is not important, we mainly check that the large
+ // object will be properly accounted for.
+ EXPECT_TRUE(DB->getStorageSize() > 10 &&
+ DB->getStorageSize() < LargeDataSize);
+
+ SmallString<16> Buffer;
+ Buffer.resize(LargeDataSize);
+ ASSERT_THAT_ERROR(store(Buffer, {}).moveInto(ID1), Succeeded());
+ size_t StorageSize = DB->getStorageSize();
+ EXPECT_TRUE(StorageSize > LargeDataSize);
+
+ // Close & re-open the DB and check that it reports the same storage size.
+ DB.reset();
+ ASSERT_THAT_ERROR(
+ OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType)).moveInto(DB),
+ Succeeded());
+ EXPECT_EQ(DB->getStorageSize(), StorageSize);
+}
+
+TEST_F(OnDiskCASTest, OnDiskGraphDBFaultInSingleNode) {
+ unittest::TempDir TempUpstream("ondiskcas-upstream", /*Unique=*/true);
+ std::unique_ptr<OnDiskGraphDB> UpstreamDB;
+ ASSERT_THAT_ERROR(
+ OnDiskGraphDB::open(TempUpstream.path(), "blake3", sizeof(HashType))
+ .moveInto(UpstreamDB),
+ Succeeded());
+ {
+ std::optional<ObjectID> ID1;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "hello", {}).moveInto(ID1),
+ Succeeded());
+ std::optional<ObjectID> ID2;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "another", {}).moveInto(ID2),
+ Succeeded());
+ std::optional<ObjectID> ID3;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "world", {*ID1, *ID2}).moveInto(ID3),
+ Succeeded());
+ }
+
+ unittest::TempDir Temp("ondiskcas", /*Unique=*/true);
+ std::unique_ptr<OnDiskGraphDB> DB;
+ ASSERT_THAT_ERROR(
+ OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType),
+ std::move(UpstreamDB),
+ OnDiskGraphDB::FaultInPolicy::SingleNode)
+ .moveInto(DB),
+ Succeeded());
+
+ ObjectID ID1 = digest(*DB, "hello", {});
+ ObjectID ID2 = digest(*DB, "another", {});
+ ObjectID ID3 = digest(*DB, "world", {ID1, ID2});
+ ObjectID ID4 = digest(*DB, "world", {});
+
+ EXPECT_TRUE(DB->containsObject(ID1));
+ EXPECT_TRUE(DB->containsObject(ID2));
+ EXPECT_TRUE(DB->containsObject(ID3));
+ EXPECT_FALSE(DB->containsObject(ID4));
+
+ EXPECT_TRUE(DB->getExistingReference(digest("hello", {})).has_value());
+ EXPECT_TRUE(DB->getExistingReference(DB->getDigest(ID3)).has_value());
+ EXPECT_FALSE(DB->getExistingReference(digest("world", {})).has_value());
+
+ {
+ std::optional<ondisk::ObjectHandle> Obj;
+ ASSERT_THAT_ERROR(DB->load(ID1).moveInto(Obj), Succeeded());
+ ASSERT_TRUE(Obj.has_value());
+ EXPECT_EQ(toStringRef(DB->getObjectData(*Obj)), "hello");
+ auto Refs = DB->getObjectRefs(*Obj);
+ EXPECT_TRUE(Refs.empty());
+ }
+ {
+ std::optional<ondisk::ObjectHandle> Obj;
+ ASSERT_THAT_ERROR(DB->load(ID3).moveInto(Obj), Succeeded());
+ ASSERT_TRUE(Obj.has_value());
+ EXPECT_EQ(toStringRef(DB->getObjectData(*Obj)), "world");
+ auto Refs = DB->getObjectRefs(*Obj);
+ ASSERT_EQ(std::distance(Refs.begin(), Refs.end()), 2);
+ EXPECT_EQ(Refs.begin()[0], ID1);
+ EXPECT_EQ(Refs.begin()[1], ID2);
+ }
+ {
+ std::optional<ondisk::ObjectHandle> Obj;
+ ASSERT_THAT_ERROR(DB->load(ID4).moveInto(Obj), Succeeded());
+ EXPECT_FALSE(Obj.has_value());
+ }
+
+ // Re-open the primary without chaining, to verify the data were copied from
+ // the upstream.
+ ASSERT_THAT_ERROR(
+ OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType),
+ /*UpstreamDB=*/nullptr,
+ OnDiskGraphDB::FaultInPolicy::SingleNode)
+ .moveInto(DB),
+ Succeeded());
+ ID1 = digest(*DB, "hello", {});
+ ID2 = digest(*DB, "another", {});
+ ID3 = digest(*DB, "world", {ID1, ID2});
+ EXPECT_TRUE(DB->containsObject(ID1));
+ EXPECT_FALSE(DB->containsObject(ID2));
+ EXPECT_TRUE(DB->containsObject(ID3));
+ {
+ std::optional<ondisk::ObjectHandle> Obj;
+ ASSERT_THAT_ERROR(DB->load(ID1).moveInto(Obj), Succeeded());
+ ASSERT_TRUE(Obj.has_value());
+ EXPECT_EQ(toStringRef(DB->getObjectData(*Obj)), "hello");
+ auto Refs = DB->getObjectRefs(*Obj);
+ EXPECT_TRUE(Refs.empty());
+ }
+}
+
+TEST_F(OnDiskCASTest, OnDiskGraphDBFaultInFullTree) {
+ unittest::TempDir TempUpstream("ondiskcas-upstream", /*Unique=*/true);
+ std::unique_ptr<OnDiskGraphDB> UpstreamDB;
+ ASSERT_THAT_ERROR(
+ OnDiskGraphDB::open(TempUpstream.path(), "blake3", sizeof(HashType))
+ .moveInto(UpstreamDB),
+ Succeeded());
+ HashType RootHash;
+ {
+ std::optional<ObjectID> ID11;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "11", {}).moveInto(ID11), Succeeded());
+ std::optional<ObjectID> ID121;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "121", {}).moveInto(ID121),
+ Succeeded());
+ std::optional<ObjectID> ID12;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "12", {*ID121}).moveInto(ID12),
+ Succeeded());
+ std::optional<ObjectID> ID1;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "1", {*ID11, *ID12}).moveInto(ID1),
+ Succeeded());
+ std::optional<ObjectID> ID21;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "21", {}).moveInto(ID21), Succeeded());
+ std::optional<ObjectID> ID22;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "22", {}).moveInto(ID22), Succeeded());
+ std::optional<ObjectID> ID2;
+ ASSERT_THAT_ERROR(
+ store(*UpstreamDB, "2", {*ID12, *ID21, *ID22}).moveInto(ID2),
+ Succeeded());
+ std::optional<ObjectID> IDRoot;
+ ASSERT_THAT_ERROR(store(*UpstreamDB, "root", {*ID1, *ID2}).moveInto(IDRoot),
+ Succeeded());
+ ArrayRef<uint8_t> Digest = UpstreamDB->getDigest(*IDRoot);
+ ASSERT_EQ(Digest.size(), RootHash.size());
+ llvm::copy(Digest, RootHash.data());
+ }
+
+ unittest::TempDir Temp("ondiskcas", /*Unique=*/true);
+ std::unique_ptr<OnDiskGraphDB> DB;
+ ASSERT_THAT_ERROR(OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType),
+ std::move(UpstreamDB),
+ OnDiskGraphDB::FaultInPolicy::FullTree)
+ .moveInto(DB),
+ Succeeded());
+
+ {
+ std::optional<ObjectID> IDRoot;
+ ASSERT_THAT_ERROR(DB->getReference(RootHash).moveInto(IDRoot), Succeeded());
+ std::optional<ondisk::ObjectHandle> Obj;
+ ASSERT_THAT_ERROR(DB->load(*IDRoot).moveInto(Obj), Succeeded());
+ ASSERT_TRUE(Obj.has_value());
+ EXPECT_EQ(toStringRef(DB->getObjectData(*Obj)), "root");
+ auto Refs = DB->getObjectRefs(*Obj);
+ ASSERT_EQ(std::distance(Refs.begin(), Refs.end()), 2);
+ }
+
+ // Re-open the primary without chaining, to verify the data were copied from
+ // the upstream.
+ ASSERT_THAT_ERROR(OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType),
+ /*UpstreamDB=*/nullptr,
+ OnDiskGraphDB::FaultInPolicy::FullTree)
+ .moveInto(DB),
+ Succeeded());
+
+ std::optional<ObjectID> IDRoot;
+ ASSERT_THAT_ERROR(DB->getReference(RootHash).moveInto(IDRoot), Succeeded());
+ std::string PrintedTree;
+ raw_string_ostream OS(PrintedTree);
+ ASSERT_THAT_ERROR(printTree(*DB, *IDRoot, OS), Succeeded());
+ StringRef Expected = R"(root
+ 1
+ 11
+ 12
+ 121
+ 2
+ 12
+ 121
+ 21
+ 22
+)";
+ EXPECT_EQ(PrintedTree, Expected);
+}
+
+TEST_F(OnDiskCASTest, OnDiskGraphDBFaultInPolicyConflict) {
+ auto tryFaultInPolicyConflict = [](OnDiskGraphDB::FaultInPolicy Policy1,
+ OnDiskGraphDB::FaultInPolicy Policy2) {
+ unittest::TempDir TempUpstream("ondiskcas-upstream", /*Unique=*/true);
+ std::unique_ptr<OnDiskGraphDB> UpstreamDB;
+ ASSERT_THAT_ERROR(
+ OnDiskGraphDB::open(TempUpstream.path(), "blake3", sizeof(HashType))
+ .moveInto(UpstreamDB),
+ Succeeded());
+
+ unittest::TempDir Temp("ondiskcas", /*Unique=*/true);
+ std::unique_ptr<OnDiskGraphDB> DB;
+ ASSERT_THAT_ERROR(OnDiskGraphDB::open(Temp.path(), "blake3",
+ sizeof(HashType),
+ std::move(UpstreamDB), Policy1)
+ .moveInto(DB),
+ Succeeded());
+ DB.reset();
+ ASSERT_THAT_ERROR(OnDiskGraphDB::open(Temp.path(), "blake3",
+ sizeof(HashType),
+ std::move(UpstreamDB), Policy2)
+ .moveInto(DB),
+ Failed());
+ };
+ // Open as 'single', then as 'full'.
+ tryFaultInPolicyConflict(OnDiskGraphDB::FaultInPolicy::SingleNode,
+ OnDiskGraphDB::FaultInPolicy::FullTree);
+ // Open as 'full', then as 'single'.
+ tryFaultInPolicyConflict(OnDiskGraphDB::FaultInPolicy::FullTree,
+ OnDiskGraphDB::FaultInPolicy::SingleNode);
+}
+
+#if defined(EXPENSIVE_CHECKS)
+TEST_F(OnDiskCASTest, OnDiskGraphDBSpaceLimit) {
+ setMaxOnDiskCASMappingSize();
+ unittest::TempDir Temp("ondiskcas", /*Unique=*/true);
+ std::unique_ptr<OnDiskGraphDB> DB;
+ ASSERT_THAT_ERROR(
+ OnDiskGraphDB::open(Temp.path(), "blake3", sizeof(HashType)).moveInto(DB),
+ Succeeded());
+
+ std::optional<ObjectID> ID;
+ std::string Data(500, '0');
+ auto storeSmallObject = [&]() {
+ SmallVector<ObjectID, 1> Refs;
+ if (ID)
+ Refs.push_back(*ID);
+ ASSERT_THAT_ERROR(store(*DB, Data, Refs).moveInto(ID), Succeeded());
+ };
+
+ // Insert enough small elements to overflow the data pool.
+ for (unsigned I = 0; I < 1024 * 256; ++I)
+ storeSmallObject();
+
+ EXPECT_GE(DB->getHardStorageLimitUtilization(), 99U);
+}
+#endif
diff --git a/llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp b/llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp
new file mode 100644
index 0000000..89c03b8
--- /dev/null
+++ b/llvm/unittests/CAS/OnDiskKeyValueDBTest.cpp
@@ -0,0 +1,77 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CAS/OnDiskKeyValueDB.h"
+#include "CASTestConfig.h"
+#include "OnDiskCommonUtils.h"
+#include "llvm/Testing/Support/Error.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::cas;
+using namespace llvm::cas::ondisk;
+using namespace llvm::unittest::cas;
+
+TEST_F(OnDiskCASTest, OnDiskKeyValueDBTest) {
+ unittest::TempDir Temp("ondiskkv", /*Unique=*/true);
+ std::unique_ptr<OnDiskKeyValueDB> DB;
+ ASSERT_THAT_ERROR(OnDiskKeyValueDB::open(Temp.path(), "blake3",
+ sizeof(HashType), "test",
+ sizeof(ValueType))
+ .moveInto(DB),
+ Succeeded());
+ {
+ std::optional<ArrayRef<char>> Val;
+ ASSERT_THAT_ERROR(DB->get(digest("hello")).moveInto(Val), Succeeded());
+ EXPECT_FALSE(Val.has_value());
+ }
+
+ ValueType ValW = valueFromString("world");
+ ArrayRef<char> Val;
+ ASSERT_THAT_ERROR(DB->put(digest("hello"), ValW).moveInto(Val), Succeeded());
+ EXPECT_EQ(Val, ArrayRef(ValW));
+ ASSERT_THAT_ERROR(
+ DB->put(digest("hello"), valueFromString("other")).moveInto(Val),
+ Succeeded());
+ EXPECT_EQ(Val, ArrayRef(ValW));
+
+ {
+ std::optional<ArrayRef<char>> Val;
+ ASSERT_THAT_ERROR(DB->get(digest("hello")).moveInto(Val), Succeeded());
+ EXPECT_TRUE(Val.has_value());
+ EXPECT_EQ(*Val, ArrayRef(ValW));
+ }
+
+ // Validate
+ {
+ auto ValidateFunc = [](FileOffset Offset, ArrayRef<char> Data) -> Error {
+ EXPECT_EQ(Data.size(), sizeof(ValueType));
+ return Error::success();
+ };
+ ASSERT_THAT_ERROR(DB->validate(ValidateFunc), Succeeded());
+ }
+
+ // Size
+ {
+ size_t InitSize = DB->getStorageSize();
+ unsigned InitPrecent = DB->getHardStorageLimitUtilization();
+
+ // Insert a lot of entries.
+ for (unsigned I = 0; I < 1024 * 100; ++I) {
+ std::string Index = Twine(I).str();
+ ArrayRef<char> Val;
+ ASSERT_THAT_ERROR(
+ DB->put(digest(Index), valueFromString(Index)).moveInto(Val),
+ Succeeded());
+ }
+
+ EXPECT_GT(DB->getStorageSize(), InitSize);
+ EXPECT_GT(DB->getHardStorageLimitUtilization(), InitPrecent);
+ }
+}
diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp
index 37826b2..4d5bbe9 100644
--- a/llvm/unittests/IR/IRBuilderTest.cpp
+++ b/llvm/unittests/IR/IRBuilderTest.cpp
@@ -201,7 +201,6 @@ TEST_F(IRBuilderTest, IntrinsicsWithScalableVectors) {
Args.clear();
Args.push_back(UndefValue::get(PtrToVecTy));
- Args.push_back(UndefValue::get(Builder.getInt32Ty()));
Args.push_back(UndefValue::get(PredTy));
Args.push_back(UndefValue::get(VecTy));