diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -254,6 +254,16 @@ return DerefBytes; } +/// Return the maximal extent from \p V to the end of the underlying object, +/// assuming the result is used in an aliasing query. +static uint64_t getMaximalExtentFrom(const Value &V, + const LocationSize &LocSize, + const DataLayout &DL) { + // This is an over-approximation of the number of bytes until the end of + // the object. This approximation ignores the offset in \p V. + return V.getPointerMaxObjSizeBytes(DL); +} + /// Returns true if we can prove that the object specified by V has size Size. static bool isObjectSize(const Value *V, uint64_t Size, const DataLayout &DL, const TargetLibraryInfo &TLI, bool NullIsValidLoc) { @@ -1824,12 +1834,16 @@ // If the size of one access is larger than the entire object on the other // side, then we know such behavior is undefined and can assume no alias. bool NullIsValidLocation = NullPointerIsDefined(&F); - if ((isObjectSmallerThan( - O2, getMinimalExtentFrom(*V1, V1Size, DL, NullIsValidLocation), DL, - TLI, NullIsValidLocation)) || - (isObjectSmallerThan( - O1, getMinimalExtentFrom(*V2, V2Size, DL, NullIsValidLocation), DL, - TLI, NullIsValidLocation))) + uint64_t V1MinSize = + getMinimalExtentFrom(*V1, V1Size, DL, NullIsValidLocation); + uint64_t V2MinSize = + getMinimalExtentFrom(*V2, V2Size, DL, NullIsValidLocation); + uint64_t V1MaxSize = getMaximalExtentFrom(*V1, V1Size, DL); + uint64_t V2MaxSize = getMaximalExtentFrom(*V2, V2Size, DL); + + if (V1MaxSize < V2MinSize || V2MaxSize < V1MinSize || + isObjectSmallerThan(O2, V1MinSize, DL, TLI, NullIsValidLocation) || + isObjectSmallerThan(O1, V2MinSize, DL, TLI, NullIsValidLocation)) return NoAlias; // Check the cache before climbing up use-def chains. This also terminates diff --git a/llvm/test/Analysis/BasicAA/maxobjsize.ll b/llvm/test/Analysis/BasicAA/maxobjsize.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/BasicAA/maxobjsize.ll @@ -0,0 +1,29 @@ +; RUN: opt < %s -basic-aa -print-no-aliases -print-may-aliases -print-must-aliases -aa-eval -disable-output 2>&1 | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @no_alias_1(i8* dereferenceable(1) maxobjsize(4) %a, i8* dereferenceable(5) maxobjsize(8) %b) { +; CHECK: NoAlias: + ret void +} + +define void @no_alias_2(i8* dereferenceable(5) maxobjsize(8) %a, i8* dereferenceable(1) maxobjsize(4) %b) { +; CHECK: NoAlias: + ret void +} + +define void @may_alias_1(i8* dereferenceable(1) maxobjsize(4) %a, i8* dereferenceable(2) maxobjsize(8) %b) { +; CHECK: MayAlias: + ret void +} + +define void @may_alias_2(i8* dereferenceable(2) maxobjsize(8) %a, i8* dereferenceable(1) maxobjsize(4) %b) { +; CHECK: MayAlias: + ret void +} + +define void @may_alias_3(i8* dereferenceable(4) maxobjsize(4) %a, i8* dereferenceable(4) maxobjsize(4) %b) { +; CHECK: MayAlias: + ret void +} + diff --git a/llvm/test/CodeGen/SystemZ/int-cmp-59.ll b/llvm/test/CodeGen/SystemZ/int-cmp-59.ll --- a/llvm/test/CodeGen/SystemZ/int-cmp-59.ll +++ b/llvm/test/CodeGen/SystemZ/int-cmp-59.ll @@ -9,11 +9,10 @@ define i64 @main() { ; CHECK-LABEL: bb.0.entry: ; CHECK: %1:addr64bit = LARL @c -; CHECK: %2:gr64bit = LLGC %1, 0, $noreg :: (dereferenceable load 1 from @c, align 4) -; CHECK-NEXT: %4:gr64bit = IMPLICIT_DEF -; CHECK-NEXT: %3:gr64bit = RISBGN %4, killed %2, 63, 191, 0 -; CHECK-NEXT: %5:gr64bit = LCGR killed %3, implicit-def dead $cc -; CHECK-NEXT: CGHI killed %5, 1, implicit-def $cc +; CHECK: MVI killed %1, 0, 1 :: (store 1 into @c, align 4) +; CHECK: MVHI killed %0, 0, 8 :: (store 4 into %ir.0) +; CHECK: %2:gr64bit = LGHI 0 +; CHECK: $r2d = COPY %2 entry: %0 = load i32*, i32** @bPtr store i1 true, i1* @c diff --git a/llvm/test/Transforms/InstCombine/pr46680.ll b/llvm/test/Transforms/InstCombine/pr46680.ll --- a/llvm/test/Transforms/InstCombine/pr46680.ll +++ b/llvm/test/Transforms/InstCombine/pr46680.ll @@ -24,17 +24,11 @@ ; CHECK-NEXT: br label [[BB22:%.*]] ; CHECK: bb13: ; CHECK-NEXT: [[I14:%.*]] = load i16, i16* [[ARG]], align 2 -; CHECK-NEXT: [[I15:%.*]] = trunc i16 [[I14]] to i8 -; CHECK-NEXT: store i8 [[I15]], i8* @c, align 1 +; CHECK-NEXT: [[I19:%.*]] = trunc i16 [[I14]] to i8 +; CHECK-NEXT: store i8 [[I19]], i8* @c, align 1 ; CHECK-NEXT: br label [[BB22]] ; CHECK: bb22: -; CHECK-NEXT: [[STOREMERGE2_IN:%.*]] = load i16, i16* [[ARG]], align 2 -; CHECK-NEXT: [[STOREMERGE2:%.*]] = trunc i16 [[STOREMERGE2_IN]] to i8 -; CHECK-NEXT: store i8 [[STOREMERGE2]], i8* @c, align 1 -; CHECK-NEXT: [[STOREMERGE1_IN:%.*]] = load i16, i16* [[ARG]], align 2 -; CHECK-NEXT: [[STOREMERGE1:%.*]] = trunc i16 [[STOREMERGE1_IN]] to i8 -; CHECK-NEXT: store i8 [[STOREMERGE1]], i8* @c, align 1 -; CHECK-NEXT: [[STOREMERGE_IN:%.*]] = load i16, i16* [[ARG]], align 2 +; CHECK-NEXT: [[STOREMERGE_IN:%.*]] = phi i16 [ [[I5]], [[BB4]] ], [ [[I14]], [[BB13]] ] ; CHECK-NEXT: [[STOREMERGE:%.*]] = trunc i16 [[STOREMERGE_IN]] to i8 ; CHECK-NEXT: store i8 [[STOREMERGE]], i8* @c, align 1 ; CHECK-NEXT: br label [[BB23:%.*]] diff --git a/polly/test/Isl/Ast/alias_checks_with_empty_context.ll b/polly/test/Isl/Ast/alias_checks_with_empty_context.ll --- a/polly/test/Isl/Ast/alias_checks_with_empty_context.ll +++ b/polly/test/Isl/Ast/alias_checks_with_empty_context.ll @@ -56,7 +56,7 @@ br label %bb1 } -; CHECK: if (1 && (&MemRef_global_1[1] <= &MemRef_tmp3[0] || &MemRef_tmp3[1] <= &MemRef_global_1[0]) && (&MemRef_tmp[1] <= &MemRef_tmp3[0] || &MemRef_tmp3[1] <= &MemRef_tmp[0]) && (&MemRef_tmp[1] <= &MemRef_global_1[0] || &MemRef_global_1[1] <= &MemRef_tmp[0])) +; CHECK: if (1 && (&MemRef_global_1[1] <= &MemRef_tmp3[0] || &MemRef_tmp3[1] <= &MemRef_global_1[0])) ; CHECK: for (int c0 = 0; c0 <= 64; c0 += 1) { ; CHECK-NEXT: Stmt_bb7(c0);