1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

Define a maximum supported alignment value for load, store, and

alloca instructions (constrained by their internal encoding),
and add error checking for it. Fix an instcombine bug which
generated huge alignment values (null is infinitely aligned).
This fixes undefined behavior noticed by John Regehr.

llvm-svn: 109643
This commit is contained in:
Dan Gohman 2010-07-28 20:12:04 +00:00
parent 7ac201b2e3
commit 939744be5f
8 changed files with 46 additions and 1 deletions

View File

@ -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
//===----------------------------------------------------------------------===//

View File

@ -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;
}

View File

@ -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);

View File

@ -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!");
}
//===----------------------------------------------------------------------===//

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}