mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-06-26 10:29:57 +00: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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@109643 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a0c5bf19bf
commit
138aa2a82b
|
@ -31,6 +31,10 @@ class APInt;
|
||||||
class LLVMContext;
|
class LLVMContext;
|
||||||
class DominatorTree;
|
class DominatorTree;
|
||||||
|
|
||||||
|
/// MaximumAlignment - This is the greatest alignment value supported by
|
||||||
|
/// load, store, and alloca instructions.
|
||||||
|
static const unsigned MaximumAlignment = 1u << 29;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// AllocaInst Class
|
// AllocaInst Class
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -1154,6 +1154,8 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) {
|
||||||
if (ParseUInt32(Alignment)) return true;
|
if (ParseUInt32(Alignment)) return true;
|
||||||
if (!isPowerOf2_32(Alignment))
|
if (!isPowerOf2_32(Alignment))
|
||||||
return Error(AlignLoc, "alignment is not a power of two");
|
return Error(AlignLoc, "alignment is not a power of two");
|
||||||
|
if (Alignment > MaximumAlignment)
|
||||||
|
return Error(AlignLoc, "huge alignments are not supported yet");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1176,6 +1178,7 @@ bool LLParser::ParseOptionalCommaAlign(unsigned &Alignment,
|
||||||
if (Lex.getKind() != lltok::kw_align)
|
if (Lex.getKind() != lltok::kw_align)
|
||||||
return Error(Lex.getLoc(), "expected metadata or 'align'");
|
return Error(Lex.getLoc(), "expected metadata or 'align'");
|
||||||
|
|
||||||
|
LocTy AlignLoc = Lex.getLoc();
|
||||||
if (ParseOptionalAlignment(Alignment)) return true;
|
if (ParseOptionalAlignment(Alignment)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,11 +104,15 @@ unsigned InstCombiner::GetOrEnforceKnownAlignment(Value *V,
|
||||||
ComputeMaskedBits(V, Mask, KnownZero, KnownOne);
|
ComputeMaskedBits(V, Mask, KnownZero, KnownOne);
|
||||||
unsigned TrailZ = KnownZero.countTrailingOnes();
|
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));
|
TrailZ = std::min(TrailZ, unsigned(sizeof(unsigned) * CHAR_BIT - 1));
|
||||||
|
|
||||||
unsigned Align = 1u << std::min(BitWidth - 1, TrailZ);
|
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)
|
if (PrefAlign > Align)
|
||||||
Align = EnforceKnownAlignment(V, Align, PrefAlign);
|
Align = EnforceKnownAlignment(V, Align, PrefAlign);
|
||||||
|
|
||||||
|
|
|
@ -891,6 +891,8 @@ AllocaInst::~AllocaInst() {
|
||||||
|
|
||||||
void AllocaInst::setAlignment(unsigned Align) {
|
void AllocaInst::setAlignment(unsigned Align) {
|
||||||
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
|
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);
|
setInstructionSubclassData(Log2_32(Align) + 1);
|
||||||
assert(getAlignment() == Align && "Alignment representation error!");
|
assert(getAlignment() == Align && "Alignment representation error!");
|
||||||
}
|
}
|
||||||
|
@ -1026,8 +1028,11 @@ LoadInst::LoadInst(Value *Ptr, const char *Name, bool isVolatile,
|
||||||
|
|
||||||
void LoadInst::setAlignment(unsigned Align) {
|
void LoadInst::setAlignment(unsigned Align) {
|
||||||
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
|
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
|
||||||
|
assert(Align <= MaximumAlignment &&
|
||||||
|
"Alignment is greater than MaximumAlignment!");
|
||||||
setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
|
setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
|
||||||
((Log2_32(Align)+1)<<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) {
|
void StoreInst::setAlignment(unsigned Align) {
|
||||||
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
|
assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
|
||||||
|
assert(Align <= MaximumAlignment &&
|
||||||
|
"Alignment is greater than MaximumAlignment!");
|
||||||
setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
|
setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
|
||||||
((Log2_32(Align)+1) << 1));
|
((Log2_32(Align)+1) << 1));
|
||||||
|
assert(getAlignment() == Align && "Alignment representation error!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
6
test/Assembler/align-inst-alloca.ll
Normal file
6
test/Assembler/align-inst-alloca.ll
Normal 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
|
||||||
|
}
|
6
test/Assembler/align-inst-load.ll
Normal file
6
test/Assembler/align-inst-load.ll
Normal 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
|
||||||
|
}
|
6
test/Assembler/align-inst-store.ll
Normal file
6
test/Assembler/align-inst-store.ll
Normal 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
|
||||||
|
}
|
8
test/Assembler/align-inst.ll
Normal file
8
test/Assembler/align-inst.ll
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user