summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/ExecutionEngine/MCJIT/test-data-align.ll15
-rw-r--r--tools/lli/lli.cpp14
2 files changed, 26 insertions, 3 deletions
diff --git a/test/ExecutionEngine/MCJIT/test-data-align.ll b/test/ExecutionEngine/MCJIT/test-data-align.ll
new file mode 100644
index 0000000000..0493cba87f
--- /dev/null
+++ b/test/ExecutionEngine/MCJIT/test-data-align.ll
@@ -0,0 +1,15 @@
+; RUN: %lli -mtriple=%mcjit_triple -use-mcjit -O0 %s
+
+; Check that a variable is always aligned as specified.
+
+@var = global i32 0, align 32
+define i32 @main() {
+ %addr = ptrtoint i32* @var to i64
+ %mask = and i64 %addr, 31
+ %tst = icmp eq i64 %mask, 0
+ br i1 %tst, label %good, label %bad
+good:
+ ret i32 0
+bad:
+ ret i32 1
+}
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index 0ee72387b8..532980a860 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -42,6 +42,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Memory.h"
+#include "llvm/Support/MathExtras.h"
#include <cerrno>
#ifdef __linux__
@@ -303,9 +304,16 @@ uint8_t *LLIMCJITMemoryManager::allocateDataSection(uintptr_t Size,
unsigned SectionID) {
if (!Alignment)
Alignment = 16;
- uint8_t *Addr = (uint8_t*)calloc((Size + Alignment - 1)/Alignment, Alignment);
- AllocatedDataMem.push_back(sys::MemoryBlock(Addr, Size));
- return Addr;
+ // Ensure that enough memory is requested to allow aligning.
+ size_t NumElementsAligned = 1 + (Size + Alignment - 1)/Alignment;
+ uint8_t *Addr = (uint8_t*)calloc(NumElementsAligned, Alignment);
+
+ // Honour the alignment requirement.
+ uint8_t *AlignedAddr = (uint8_t*)RoundUpToAlignment((uint64_t)Addr, Alignment);
+
+ // Store the original address from calloc so we can free it later.
+ AllocatedDataMem.push_back(sys::MemoryBlock(Addr, NumElementsAligned*Alignment));
+ return AlignedAddr;
}
uint8_t *LLIMCJITMemoryManager::allocateCodeSection(uintptr_t Size,