[llvm] r193317 - fix PR17635: false positive with packed structures

Nuno Lopes nunoplopes at sapo.pt
Thu Oct 24 02:17:25 PDT 2013


Author: nlopes
Date: Thu Oct 24 04:17:24 2013
New Revision: 193317

URL: http://llvm.org/viewvc/llvm-project?rev=193317&view=rev
Log:
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

Added:
    llvm/trunk/test/Instrumentation/BoundsChecking/simple-32.ll
Modified:
    llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h
    llvm/trunk/lib/Analysis/MemoryBuiltins.cpp
    llvm/trunk/lib/Transforms/Instrumentation/BoundsChecking.cpp

Modified: llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h?rev=193317&r1=193316&r2=193317&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemoryBuiltins.h Thu Oct 24 04:17:24 2013
@@ -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) {

Modified: llvm/trunk/lib/Analysis/MemoryBuiltins.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryBuiltins.cpp?rev=193317&r1=193316&r2=193317&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemoryBuiltins.cpp (original)
+++ llvm/trunk/lib/Analysis/MemoryBuiltins.cpp Thu Oct 24 04:17:24 2013
@@ -588,8 +588,10 @@ SizeOffsetType ObjectSizeOffsetVisitor::
 
 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 ObjectSizeOffsetEvalu
 }
 
 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),

Modified: llvm/trunk/lib/Transforms/Instrumentation/BoundsChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/BoundsChecking.cpp?rev=193317&r1=193316&r2=193317&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/BoundsChecking.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/BoundsChecking.cpp Thu Oct 24 04:17:24 2013
@@ -172,7 +172,8 @@ bool BoundsChecking::runOnFunction(Funct
   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

Added: llvm/trunk/test/Instrumentation/BoundsChecking/simple-32.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/BoundsChecking/simple-32.ll?rev=193317&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/BoundsChecking/simple-32.ll (added)
+++ llvm/trunk/test/Instrumentation/BoundsChecking/simple-32.ll Thu Oct 24 04:17:24 2013
@@ -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
+}





More information about the llvm-commits mailing list