aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Instructions.h4
-rw-r--r--lib/AsmParser/LLParser.cpp3
-rw-r--r--lib/Transforms/InstCombine/InstCombineCalls.cpp6
-rw-r--r--lib/VMCore/Instructions.cpp8
-rw-r--r--test/Assembler/align-inst-alloca.ll6
-rw-r--r--test/Assembler/align-inst-load.ll6
-rw-r--r--test/Assembler/align-inst-store.ll6
-rw-r--r--test/Assembler/align-inst.ll8
8 files changed, 46 insertions, 1 deletions
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 273c9951c6..118a42d515 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -31,6 +31,10 @@ class APInt;
class LLVMContext;
class DominatorTree;
+/// MaximumAlignment - This is the greatest alignment value supported by
+/// load, store, and alloca instructions.
+static const unsigned MaximumAlignment = 1u << 29;
+
//===----------------------------------------------------------------------===//
// AllocaInst Class
//===----------------------------------------------------------------------===//
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index 61b1ae5e97..e581a69458 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -1154,6 +1154,8 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) {
if (ParseUInt32(Alignment)) return true;
if (!isPowerOf2_32(Alignment))
return Error(AlignLoc, "alignment is not a power of two");
+ if (Alignment > MaximumAlignment)
+ return Error(AlignLoc, "huge alignments are not supported yet");
return false;
}
@@ -1176,6 +1178,7 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
if (Lex.getKind() != lltok::kw_align)
return Error(Lex.getLoc(), "expected metadata or 'align'");
+ LocTy AlignLoc = Lex.getLoc();
if (ParseOptionalAlignment(Alignment)) return true;
}
diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 0d5e30205a..fdb2dd693d 100644
--- a/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -104,11 +104,15 @@ unsigned InstCombiner::GetOrEnforceKnownAlignment(Value *V,
ComputeMaskedBits(V, Mask, KnownZero, KnownOne);
unsigned TrailZ = KnownZero.countTrailingOnes();
- // LLVM doesn't support alignments larger than this currently.
+ // Avoid trouble with rediculously large TrailZ values, such as
+ // those computed from a null pointer.
TrailZ = std::min(TrailZ, unsigned(sizeof(unsigned) * CHAR_BIT - 1));
unsigned Align = 1u << std::min(BitWidth - 1, TrailZ);
+ // LLVM doesn't support alignments larger than this currently.
+ Align = std::min(Align, MaximumAlignment);
+
if (PrefAlign > Align)
Align = EnforceKnownAlignment(V, Align, PrefAlign);
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 57b7f3f3d6..e03cc82758 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -891,6 +891,8 @@ AllocaInst::~AllocaInst() {
void AllocaInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+ assert(Align <= MaximumAlignment &&
+ "Alignment is greater than MaximumAlignment!");
setInstructionSubclassData(Log2_32(Align) + 1);
assert(getAlignment() == Align && "Alignment representation error!");
}
@@ -1026,8 +1028,11 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile,
void LoadInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+ assert(Align <= MaximumAlignment &&
+ "Alignment is greater than MaximumAlignment!");
setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
((Log2_32(Align)+1)<<1));
+ assert(getAlignment() == Align && "Alignment representation error!");
}
//===----------------------------------------------------------------------===//
@@ -1122,8 +1127,11 @@ StoreInst::StoreInst(Value *val, Value *addr, bool isVolatile,
void StoreInst::setAlignment(unsigned Align) {
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+ assert(Align <= MaximumAlignment &&
+ "Alignment is greater than MaximumAlignment!");
setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
((Log2_32(Align)+1) << 1));
+ assert(getAlignment() == Align && "Alignment representation error!");
}
//===----------------------------------------------------------------------===//
diff --git a/test/Assembler/align-inst-alloca.ll b/test/Assembler/align-inst-alloca.ll
new file mode 100644
index 0000000000..0343bebf18
--- /dev/null
+++ b/test/Assembler/align-inst-alloca.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as %s -o /dev/null 2>/dev/null
+
+define void @foo() {
+ %p = alloca i1, align 1073741824
+ ret void
+}
diff --git a/test/Assembler/align-inst-load.ll b/test/Assembler/align-inst-load.ll
new file mode 100644
index 0000000000..3586be2d6e
--- /dev/null
+++ b/test/Assembler/align-inst-load.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as %s -o /dev/null 2>/dev/null
+
+define void @foo() {
+ load i1* %p, align 1073741824
+ ret void
+}
diff --git a/test/Assembler/align-inst-store.ll b/test/Assembler/align-inst-store.ll
new file mode 100644
index 0000000000..8c3b7124b4
--- /dev/null
+++ b/test/Assembler/align-inst-store.ll
@@ -0,0 +1,6 @@
+; RUN: not llvm-as %s -o /dev/null 2>/dev/null
+
+define void @foo() {
+ store i1 false, i1* %p, align 1073741824
+ ret void
+}
diff --git a/test/Assembler/align-inst.ll b/test/Assembler/align-inst.ll
new file mode 100644
index 0000000000..7bf0b6493b
--- /dev/null
+++ b/test/Assembler/align-inst.ll
@@ -0,0 +1,8 @@
+; RUN: llvm-as %s -o /dev/null
+
+define void @foo() {
+ %p = alloca i1, align 536870912
+ load i1* %p, align 536870912
+ store i1 false, i1* %p, align 536870912
+ ret void
+}