[llvm-commits] [llvm] r164595 - in /llvm/trunk: lib/Analysis/Lint.cpp test/Other/lint.ll

Duncan Sands baldrick at free.fr
Tue Sep 25 03:00:49 PDT 2012


Author: baldrick
Date: Tue Sep 25 05:00:49 2012
New Revision: 164595

URL: http://llvm.org/viewvc/llvm-project?rev=164595&view=rev
Log:
Change the way the lint sanity checking pass detects misaligned memory accesses.
Previously it was only be able to detect problems if the pointer was a numerical
value (eg inttoptr i32 1 to i32*), but not if it was an alloca or globa.  The
reason was the use of ComputeMaskedBits: imagine you have "alloca i8, align 2",
and ask ComputeMaskedBits what it knows about the bits of the alloca pointer.
It can tell you that the bottom bit is known zero (due to align 2) but it can't
tell you that bit 1 is known one.  That's because the address could be an even
multiple of 2 rather than an odd multiple, eg it might be a multiple of 4.  Thus
trying to use KnownOne is ineffective in the case of an alloca as it will never
have any bits set.  Instead look explicitly for constant offsets from allocas
and globals.

Modified:
    llvm/trunk/lib/Analysis/Lint.cpp
    llvm/trunk/test/Other/lint.ll

Modified: llvm/trunk/lib/Analysis/Lint.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Lint.cpp?rev=164595&r1=164594&r2=164595&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Lint.cpp (original)
+++ llvm/trunk/lib/Analysis/Lint.cpp Tue Sep 25 05:00:49 2012
@@ -412,14 +412,26 @@
   }
 
   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<AllocaInst>(Base)) {
+          BaseAlign = AI->getAlignment();
+          if (BaseAlign == 0 && AI->getAllocatedType()->isSized())
+            BaseAlign = TD->getABITypeAlignment(AI->getAllocatedType());
+        } else if (GlobalValue *GV = dyn_cast<GlobalVariable>(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);
+      }
     }
   }
 }

Modified: llvm/trunk/test/Other/lint.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/lint.ll?rev=164595&r1=164594&r2=164595&view=diff
==============================================================================
--- llvm/trunk/test/Other/lint.ll (original)
+++ llvm/trunk/test/Other/lint.ll Tue Sep 25 05:00:49 2012
@@ -11,6 +11,8 @@
 @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 @@
 ; 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





More information about the llvm-commits mailing list