fix PR17635: false positive with packed structures

LLVM optimizers may widen accesses to packed structures that overflow the structure itself, but should be in bounds up to the alignment of the object

llvm-svn: 193317
This commit is contained in:
Nuno Lopes 2013-10-24 09:17:24 +00:00
parent c5cae0f20c
commit 340b0463e6
4 changed files with 38 additions and 5 deletions

View File

@ -228,6 +228,7 @@ class ObjectSizeOffsetEvaluator
Value *Zero;
CacheMapTy CacheMap;
PtrSetTy SeenVals;
bool RoundToAlign;
SizeOffsetEvalType unknown() {
return std::make_pair((Value*)0, (Value*)0);
@ -236,7 +237,7 @@ class ObjectSizeOffsetEvaluator
public:
ObjectSizeOffsetEvaluator(const DataLayout *DL, const TargetLibraryInfo *TLI,
LLVMContext &Context);
LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetEvalType compute(Value *V);
bool knownSize(SizeOffsetEvalType SizeOffset) {

View File

@ -588,8 +588,10 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitInstruction(Instruction &I) {
ObjectSizeOffsetEvaluator::ObjectSizeOffsetEvaluator(const DataLayout *DL,
const TargetLibraryInfo *TLI,
LLVMContext &Context)
: DL(DL), TLI(TLI), Context(Context), Builder(Context, TargetFolder(DL)) {
LLVMContext &Context,
bool RoundToAlign)
: DL(DL), TLI(TLI), Context(Context), Builder(Context, TargetFolder(DL)),
RoundToAlign(RoundToAlign) {
IntTy = DL->getIntPtrType(Context);
Zero = ConstantInt::get(IntTy, 0);
}
@ -614,7 +616,7 @@ SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute(Value *V) {
}
SizeOffsetEvalType ObjectSizeOffsetEvaluator::compute_(Value *V) {
ObjectSizeOffsetVisitor Visitor(DL, TLI, Context);
ObjectSizeOffsetVisitor Visitor(DL, TLI, Context, RoundToAlign);
SizeOffsetType Const = Visitor.compute(V);
if (Visitor.bothKnown(Const))
return std::make_pair(ConstantInt::get(Context, Const.first),

View File

@ -172,7 +172,8 @@ bool BoundsChecking::runOnFunction(Function &F) {
TrapBB = 0;
BuilderTy TheBuilder(F.getContext(), TargetFolder(TD));
Builder = &TheBuilder;
ObjectSizeOffsetEvaluator TheObjSizeEval(TD, TLI, F.getContext());
ObjectSizeOffsetEvaluator TheObjSizeEval(TD, TLI, F.getContext(),
/*RoundToAlign=*/true);
ObjSizeEval = &TheObjSizeEval;
// check HANDLE_MEMORY_INST in include/llvm/Instruction.def for memory

View File

@ -0,0 +1,29 @@
; RUN: opt < %s -bounds-checking -S | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
%struct.s2_packed = type <{ i64, i32, i32, i32, i16, i8 }>
; CHECK-LABEL: @f
; CHECK-NOT: trap
define i16 @f() {
entry:
%packed1 = alloca %struct.s2_packed, align 8
%gep = getelementptr inbounds %struct.s2_packed* %packed1, i32 0, i32 4
%ptr = bitcast i16* %gep to i32*
%val = load i32* %ptr, align 4
%valt = trunc i32 %val to i16
ret i16 %valt
}
; CHECK-LABEL: @f
; CHECK: call void @llvm.trap()
define i16 @f2() {
entry:
%packed1 = alloca %struct.s2_packed, align 8
%gep = getelementptr inbounds %struct.s2_packed* %packed1, i32 0, i32 4
%ptr = bitcast i16* %gep to i48*
%val = load i48* %ptr, align 4
%valt = trunc i48 %val to i16
ret i16 %valt
}