diff --git a/llvm/include/llvm/Analysis/MemoryLocation.h b/llvm/include/llvm/Analysis/MemoryLocation.h --- a/llvm/include/llvm/Analysis/MemoryLocation.h +++ b/llvm/include/llvm/Analysis/MemoryLocation.h @@ -89,6 +89,11 @@ : 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. @@ -98,6 +103,11 @@ 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); diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -633,6 +633,10 @@ 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); diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -666,7 +666,7 @@ if (DerefBytes == 0 && (A->hasByValAttr() || A->hasStructRetAttr())) { Type *PT = cast(A->getType())->getElementType(); if (PT->isSized()) - DerefBytes = DL.getTypeStoreSize(PT); + DerefBytes = DL.getTypeStoreSize(PT).getKnownMinSize(); } if (DerefBytes == 0) { DerefBytes = A->getDereferenceableOrNullBytes(); @@ -707,14 +707,15 @@ } } else if (auto *AI = dyn_cast(this)) { if (!AI->isArrayAllocation()) { - DerefBytes = DL.getTypeStoreSize(AI->getAllocatedType()); + DerefBytes = + DL.getTypeStoreSize(AI->getAllocatedType()).getKnownMinSize(); CanBeNull = false; } } else if (auto *GV = dyn_cast(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; } } diff --git a/llvm/test/Analysis/MemorySSA/scalable-vec.ll b/llvm/test/Analysis/MemorySSA/scalable-vec.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/MemorySSA/scalable-vec.ll @@ -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' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s + +; CHECK-LABEL: define @f( +; CHECK: 1 = MemoryDef(liveOnEntry) +; CHECK: MemoryUse(1) MustAlias +define @f( %z) { + %a = alloca + store %z, * %a + %zz = load , * %a + ret %zz +} + +; CHECK-LABEL: define i32 @g( +; CHECK: 1 = MemoryDef(liveOnEntry) +; CHECK: MemoryUse(1) MayAlias +declare i32* @gg(* %a) +define i32 @g(i32 %z, i32 *%bb) { + %a = alloca + %aa = getelementptr , * %a, i32 0, i32 0 + store i32 %z, i32* %aa + %bbb = call i32* @gg(* %a) readnone + %zz = load i32, i32* %bbb + ret i32 %zz +}