From ebec984e14af89331ccdd9861008f4cec4589df0 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 16 Mar 2020 11:13:20 -0700 Subject: [PATCH] [AliasAnalysis] Misc fixes for checking aliasing with scalable types. 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 | 10 ++++++++++ llvm/lib/Analysis/MemoryBuiltins.cpp | 4 ++++ llvm/lib/IR/Value.cpp | 7 ++++--- llvm/test/Analysis/MemorySSA/scalable-vec.ll | 25 +++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Analysis/MemorySSA/scalable-vec.ll diff --git a/llvm/include/llvm/Analysis/MemoryLocation.h b/llvm/include/llvm/Analysis/MemoryLocation.h index dd576e0..4460411 100644 --- a/llvm/include/llvm/Analysis/MemoryLocation.h +++ b/llvm/include/llvm/Analysis/MemoryLocation.h @@ -89,6 +89,11 @@ public: : 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 @@ public: 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 index 427e6fd..be0feeb 100644 --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -633,6 +633,10 @@ SizeOffsetType ObjectSizeOffsetVisitor::visitAllocaInst(AllocaInst &I) { 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 index 8cd5897..962e674 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -666,7 +666,7 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL, 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 @@ uint64_t Value::getPointerDereferenceableBytes(const DataLayout &DL, } } 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 index 0000000..2307287 --- /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 +} -- 1.8.3.1