[AliasAnalysis] Misc fixes for checking aliasing with scalable types.
authorEli Friedman <efriedma@quicinc.com>
Mon, 16 Mar 2020 18:13:20 +0000 (11:13 -0700)
committerEli Friedman <efriedma@quicinc.com>
Wed, 18 Mar 2020 19:28:47 +0000 (12:28 -0700)
This is fixing up various places that use the implicit
TypeSize->uint64_t conversion.

The new overloads in MemoryLocation.h are already used in various places
that construct a MemoryLocation from a TypeSize, including MemorySSA.
(They were using the implicit conversion before.)

Differential Revision: https://reviews.llvm.org/D76249

llvm/include/llvm/Analysis/MemoryLocation.h
llvm/lib/Analysis/MemoryBuiltins.cpp
llvm/lib/IR/Value.cpp
llvm/test/Analysis/MemorySSA/scalable-vec.ll [new file with mode: 0644]

index dd576e0..4460411 100644 (file)
@@ -89,6 +89,11 @@ public:
       : Value(Raw > MaxValue ? Unknown : Raw) {}
 
   static LocationSize precise(uint64_t Value) { return LocationSize(Value); }
       : Value(Raw > MaxValue ? Unknown : Raw) {}
 
   static LocationSize precise(uint64_t Value) { return LocationSize(Value); }
+  static LocationSize precise(TypeSize Value) {
+    if (Value.isScalable())
+      return unknown();
+    return precise(Value.getFixedSize());
+  }
 
   static LocationSize upperBound(uint64_t Value) {
     // You can't go lower than 0, so give a precise result.
 
   static LocationSize upperBound(uint64_t Value) {
     // You can't go lower than 0, so give a precise result.
@@ -98,6 +103,11 @@ public:
       return unknown();
     return LocationSize(Value | ImpreciseBit, Direct);
   }
       return unknown();
     return LocationSize(Value | ImpreciseBit, Direct);
   }
+  static LocationSize upperBound(TypeSize Value) {
+    if (Value.isScalable())
+      return unknown();
+    return upperBound(Value.getFixedSize());
+  }
 
   constexpr static LocationSize unknown() {
     return LocationSize(Unknown, Direct);
 
   constexpr static LocationSize unknown() {
     return LocationSize(Unknown, Direct);
index 427e6fd..be0feeb 100644 (file)
@@ -633,6 +633,10 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) {
   if (!I.getAllocatedType()->isSized())
     return unknown();
 
   if (!I.getAllocatedType()->isSized())
     return unknown();
 
+  if (I.getAllocatedType()->isVectorTy() &&
+      I.getAllocatedType()->getVectorIsScalable())
+    return unknown();
+
   APInt Size(IntTyBits, DL.getTypeAllocSize(I.getAllocatedType()));
   if (!I.isArrayAllocation())
     return std::make_pair(align(Size, I.getAlignment()), Zero);
   APInt Size(IntTyBits, DL.getTypeAllocSize(I.getAllocatedType()));
   if (!I.isArrayAllocation())
     return std::make_pair(align(Size, I.getAlignment()), Zero);
index 8cd5897..962e674 100644 (file)
@@ -666,7 +666,7 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL,
     if (DerefBytes == 0 && (A->hasByValAttr() || A->hasStructRetAttr())) {
       Type *PT = cast<PointerType>(A->getType())->getElementType();
       if (PT->isSized())
     if (DerefBytes == 0 && (A->hasByValAttr() || A->hasStructRetAttr())) {
       Type *PT = cast<PointerType>(A->getType())->getElementType();
       if (PT->isSized())
-        DerefBytes = DL.getTypeStoreSize(PT);
+        DerefBytes = DL.getTypeStoreSize(PT).getKnownMinSize();
     }
     if (DerefBytes == 0) {
       DerefBytes = A->getDereferenceableOrNullBytes();
     }
     if (DerefBytes == 0) {
       DerefBytes = A->getDereferenceableOrNullBytes();
@@ -707,14 +707,15 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL,
     }
   } else if (auto *AI = dyn_cast<AllocaInst>(this)) {
     if (!AI->isArrayAllocation()) {
     }
   } else if (auto *AI = dyn_cast<AllocaInst>(this)) {
     if (!AI->isArrayAllocation()) {
-      DerefBytes = DL.getTypeStoreSize(AI->getAllocatedType());
+      DerefBytes =
+          DL.getTypeStoreSize(AI->getAllocatedType()).getKnownMinSize();
       CanBeNull = false;
     }
   } else if (auto *GV = dyn_cast<GlobalVariable>(this)) {
     if (GV->getValueType()->isSized() && !GV->hasExternalWeakLinkage()) {
       // TODO: Don't outright reject hasExternalWeakLinkage but set the
       // CanBeNull flag.
       CanBeNull = false;
     }
   } else if (auto *GV = dyn_cast<GlobalVariable>(this)) {
     if (GV->getValueType()->isSized() && !GV->hasExternalWeakLinkage()) {
       // TODO: Don't outright reject hasExternalWeakLinkage but set the
       // CanBeNull flag.
-      DerefBytes = DL.getTypeStoreSize(GV->getValueType());
+      DerefBytes = DL.getTypeStoreSize(GV->getValueType()).getFixedSize();
       CanBeNull = false;
     }
   }
       CanBeNull = false;
     }
   }
diff --git a/llvm/test/Analysis/MemorySSA/scalable-vec.ll b/llvm/test/Analysis/MemorySSA/scalable-vec.ll
new file mode 100644 (file)
index 0000000..2307287
--- /dev/null
@@ -0,0 +1,25 @@
+; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s
+; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s
+
+; CHECK-LABEL: define <vscale x 4 x i32> @f(
+; CHECK: 1 = MemoryDef(liveOnEntry)
+; CHECK: MemoryUse(1) MustAlias
+define <vscale x 4 x i32> @f(<vscale x 4 x i32> %z) {
+  %a = alloca <vscale x 4 x i32>
+  store <vscale x 4 x i32> %z, <vscale x 4 x i32>* %a
+  %zz = load <vscale x 4 x i32>, <vscale x 4 x i32>* %a
+  ret <vscale x 4 x i32> %zz
+}
+
+; CHECK-LABEL: define i32 @g(
+; CHECK: 1 = MemoryDef(liveOnEntry)
+; CHECK: MemoryUse(1) MayAlias
+declare i32* @gg(<vscale x 4 x i32>* %a)
+define i32 @g(i32 %z, i32 *%bb) {
+  %a = alloca <vscale x 4 x i32>
+  %aa = getelementptr <vscale x 4 x i32>, <vscale x 4 x i32>* %a, i32 0, i32 0
+  store i32 %z, i32* %aa
+  %bbb = call i32* @gg(<vscale x 4 x i32>* %a) readnone
+  %zz = load i32, i32* %bbb
+  ret i32 %zz
+}