diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index c54b7e6dfb5..91224ad94ac 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -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) { diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp index a2fb544c657..1db0f634c94 100644 --- a/lib/Analysis/MemoryBuiltins.cpp +++ b/lib/Analysis/MemoryBuiltins.cpp @@ -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), diff --git a/lib/Transforms/Instrumentation/BoundsChecking.cpp b/lib/Transforms/Instrumentation/BoundsChecking.cpp index 4a9e9503675..7a9f0f69fbd 100644 --- a/lib/Transforms/Instrumentation/BoundsChecking.cpp +++ b/lib/Transforms/Instrumentation/BoundsChecking.cpp @@ -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 diff --git a/test/Instrumentation/BoundsChecking/simple-32.ll b/test/Instrumentation/BoundsChecking/simple-32.ll new file mode 100644 index 00000000000..38b210f7e23 --- /dev/null +++ b/test/Instrumentation/BoundsChecking/simple-32.ll @@ -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 +}