Skip to content

Commit 2fac90d

Browse files
committed
Add test for insufficient alignment.
1 parent b10ca7a commit 2fac90d

File tree

1 file changed

+48
-16
lines changed

1 file changed

+48
-16
lines changed

mlir/unittests/Bytecode/BytecodeTest.cpp

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,10 @@
1818
#include "gmock/gmock.h"
1919
#include "gtest/gtest.h"
2020

21-
#include <algorithm>
22-
#include <cstdlib>
23-
#include <memory>
24-
2521
using namespace llvm;
2622
using namespace mlir;
2723

28-
using testing::ElementsAre;
24+
using ::testing::StartsWith;
2925

3026
StringLiteral IRWithResources = R"(
3127
module @TestDialectResources attributes {
@@ -34,7 +30,7 @@ module @TestDialectResources attributes {
3430
{-#
3531
dialect_resources: {
3632
builtin: {
37-
resource: "0x1000000001000000020000000300000004000000"
33+
resource: "0x2000000001000000020000000300000004000000"
3834
}
3935
}
4036
#-}
@@ -52,19 +48,19 @@ TEST(Bytecode, MultiModuleWithResource) {
5248
std::string buffer;
5349
llvm::raw_string_ostream ostream(buffer);
5450
ASSERT_TRUE(succeeded(writeBytecodeToFile(module.get(), ostream)));
55-
56-
// Make a sufficiently aligned copy of the buffer for reading it back.
5751
ostream.flush();
58-
constexpr std::size_t kAlignment = 16; // AsmResourceBlob alignment.
59-
auto deleter = [](char *ptr) { std::free(ptr); };
60-
std::unique_ptr<char, decltype(deleter)> aligned_buffer(
61-
static_cast<char *>(std::aligned_alloc(kAlignment, buffer.size())),
62-
deleter);
63-
std::copy(buffer.begin(), buffer.end(), aligned_buffer.get());
52+
53+
// Create copy of buffer which is aligned to requested resource alignment.
54+
constexpr size_t kAlignment = 0x20;
55+
size_t buffer_size = buffer.size();
56+
buffer.reserve(buffer_size + kAlignment - 1);
57+
size_t pad = ~(uintptr_t)buffer.data() + 1 & kAlignment - 1;
58+
buffer.insert(0, pad, ' ');
59+
StringRef aligned_buffer(buffer.data() + pad, buffer_size);
6460

6561
// Parse it back
66-
OwningOpRef<Operation *> roundTripModule = parseSourceString<Operation *>(
67-
{aligned_buffer.get(), buffer.size()}, parseConfig);
62+
OwningOpRef<Operation *> roundTripModule =
63+
parseSourceString<Operation *>(aligned_buffer, parseConfig);
6864
ASSERT_TRUE(roundTripModule);
6965

7066
// FIXME: Parsing external resources does not work on big-endian
@@ -92,3 +88,39 @@ TEST(Bytecode, MultiModuleWithResource) {
9288
checkResourceAttribute(*module);
9389
checkResourceAttribute(*roundTripModule);
9490
}
91+
92+
TEST(Bytecode, InsufficientAlignmentFailure) {
93+
MLIRContext context;
94+
Builder builder(&context);
95+
ParserConfig parseConfig(&context);
96+
OwningOpRef<Operation *> module =
97+
parseSourceString<Operation *>(IRWithResources, parseConfig);
98+
ASSERT_TRUE(module);
99+
100+
// Write the module to bytecode
101+
std::string buffer;
102+
llvm::raw_string_ostream ostream(buffer);
103+
ASSERT_TRUE(succeeded(writeBytecodeToFile(module.get(), ostream)));
104+
ostream.flush();
105+
106+
// Create copy of buffer which is insufficiently aligned.
107+
constexpr size_t kAlignment = 0x20;
108+
size_t buffer_size = buffer.size();
109+
buffer.reserve(buffer_size + kAlignment - 1);
110+
size_t pad = ~(uintptr_t)buffer.data() + kAlignment / 2 + 1 & kAlignment - 1;
111+
buffer.insert(0, pad, ' ');
112+
StringRef misaligned_buffer(buffer.data() + pad, buffer_size);
113+
114+
std::unique_ptr<Diagnostic> diagnostic;
115+
context.getDiagEngine().registerHandler([&](Diagnostic &diag) {
116+
diagnostic = std::make_unique<Diagnostic>(std::move(diag));
117+
});
118+
119+
// Try to parse it back and check for alignment error.
120+
OwningOpRef<Operation *> roundTripModule =
121+
parseSourceString<Operation *>(misaligned_buffer, parseConfig);
122+
EXPECT_FALSE(roundTripModule);
123+
ASSERT_TRUE(diagnostic);
124+
EXPECT_THAT(diagnostic->str(),
125+
StartsWith("expected bytecode buffer to be aligned to 32"));
126+
}

0 commit comments

Comments
 (0)