diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp index 83bdf5286ad..6e765a7fdea 100644 --- a/lib/Analysis/Lint.cpp +++ b/lib/Analysis/Lint.cpp @@ -412,14 +412,26 @@ void Lint::visitMemoryReference(Instruction &I, } if (TD) { - if (Align == 0 && Ty) Align = TD->getABITypeAlignment(Ty); + if (Align == 0 && Ty && Ty->isSized()) + Align = TD->getABITypeAlignment(Ty); if (Align != 0) { - unsigned BitWidth = TD->getTypeSizeInBits(Ptr->getType()); - APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - ComputeMaskedBits(Ptr, KnownZero, KnownOne, TD); - Assert1(!(KnownOne & APInt::getLowBitsSet(BitWidth, Log2_32(Align))), - "Undefined behavior: Memory reference address is misaligned", &I); + int64_t Offset = 0; + if (Value *Base = GetPointerBaseWithConstantOffset(Ptr, Offset, *TD)) { + unsigned BaseAlign = 0; + if (AllocaInst *AI = dyn_cast(Base)) { + BaseAlign = AI->getAlignment(); + if (BaseAlign == 0 && AI->getAllocatedType()->isSized()) + BaseAlign = TD->getABITypeAlignment(AI->getAllocatedType()); + } else if (GlobalValue *GV = dyn_cast(Base)) { + BaseAlign = GV->getAlignment(); + if (BaseAlign == 0 && GV->getType()->getElementType()->isSized()) + BaseAlign = TD->getABITypeAlignment(GV->getType()->getElementType()); + } + Assert1((!BaseAlign || Align <= MinAlign(BaseAlign, Offset)), + "Undefined behavior: Memory reference address is misaligned", + &I); + } } } } diff --git a/test/Other/lint.ll b/test/Other/lint.ll index c84f56f8f69..f6787e973ed 100644 --- a/test/Other/lint.ll +++ b/test/Other/lint.ll @@ -11,6 +11,8 @@ declare void @one_arg(i32) @CG = constant i32 7 define i32 @foo() noreturn { + %buf = alloca i8 + %buf2 = alloca {i8, i8}, align 2 ; CHECK: Caller and callee calling convention differ call void @bar() ; CHECK: Null pointer dereference @@ -26,8 +28,10 @@ define i32 @foo() noreturn { ; CHECK: Address one pointer dereference store i32 0, i32* inttoptr (i64 1 to i32*) ; CHECK: Memory reference address is misaligned - %x = inttoptr i32 1 to i32* - load i32* %x, align 4 + store i8 0, i8* %buf, align 2 +; CHECK: Memory reference address is misaligned + %gep = getelementptr {i8, i8}* %buf2, i32 0, i32 1 + store i8 0, i8* %gep, align 2 ; CHECK: Division by zero %sd = sdiv i32 2, 0 ; CHECK: Division by zero