[llvm] bd12a32 - [BasicAA] Use GEP as context for computeKnownBits in aliasGEP.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 12 09:18:14 PST 2019


Author: Florian Hahn
Date: 2019-12-12T17:18:04Z
New Revision: bd12a322d7e0b2541880c00f5551e047e06be982

URL: https://github.com/llvm/llvm-project/commit/bd12a322d7e0b2541880c00f5551e047e06be982
DIFF: https://github.com/llvm/llvm-project/commit/bd12a322d7e0b2541880c00f5551e047e06be982.diff

LOG: [BasicAA] Use GEP as context for computeKnownBits in aliasGEP.

In order to use assumptions, computeKnownBits needs a context
instruction. We can use the GEP, if it is an instruction. We already
pass the assumption cache, but it cannot be used without a context
instruction.

Reviewers: anemet, asbirlea, hfinkel, spatel

Reviewed By: asbirlea

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

Added: 
    llvm/test/Analysis/BasicAA/assume-index-positive.ll

Modified: 
    llvm/lib/Analysis/BasicAliasAnalysis.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
index 227b12d1b67f..e852d663c6b4 100644
--- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1482,7 +1482,8 @@ AliasResult BasicAAResult::aliasGEP(
         // give up if we can't determine conditions that hold for every cycle:
         const Value *V = DecompGEP1.VarIndices[i].V;
 
-        KnownBits Known = computeKnownBits(V, DL, 0, &AC, nullptr, DT);
+        KnownBits Known =
+            computeKnownBits(V, DL, 0, &AC, dyn_cast<Instruction>(GEP1), DT);
         bool SignKnownZero = Known.isNonNegative();
         bool SignKnownOne = Known.isNegative();
 

diff  --git a/llvm/test/Analysis/BasicAA/assume-index-positive.ll b/llvm/test/Analysis/BasicAA/assume-index-positive.ll
new file mode 100644
index 000000000000..d89738a23b03
--- /dev/null
+++ b/llvm/test/Analysis/BasicAA/assume-index-positive.ll
@@ -0,0 +1,116 @@
+; RUN: opt -basicaa -aa-eval -print-all-alias-modref-info %s 2>&1 | FileCheck %s
+
+; %col.ptr.1 and %col.ptr.2 do not alias, if we know that %skip >= 0, because
+; the distance between %col.ptr.1 and %col.ptr.2 is %skip + 6 and we load 6
+; elements.
+define void @test1(double* %ptr, i32 %skip) {
+; CHECK-LABEL: Function: test1: 4 pointers, 1 call sites
+; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.1, double* %ptr
+; CHECK-NEXT:  NoAlias: double* %col.ptr.2, double* %ptr
+; CHECK-NEXT:  NoAlias: <6 x double>* %col.ptr.1, double* %col.ptr.2
+; CHECK-NEXT:  NoAlias: <6 x double>* %col.ptr.2.cast, double* %ptr
+; CHECK-NEXT:  NoAlias: <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
+; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.2.cast, double* %col.ptr.2
+; CHECK-NEXT:  NoModRef:  Ptr: double* %ptr <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.1 <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: double* %col.ptr.2   <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.2.cast    <->  call void @llvm.assume(i1 %gt)
+;
+  %gt = icmp sgt i32 %skip, -1
+  call void @llvm.assume(i1 %gt)
+  %stride = add nsw nuw i32 %skip, 6
+  %col.ptr.1 = bitcast double* %ptr to <6 x double>*
+  %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
+  %col.ptr.2= getelementptr double, double* %ptr, i32 %stride
+  %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
+  %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
+  %res.1 = fadd <6 x double> %lv.1, %lv.1
+  %res.2 = fadd <6 x double> %lv.2, %lv.2
+  store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8
+  store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8
+  ret void
+}
+
+; Same as @test1, but now we do not have an assume guaranteeing %skip >= 0.
+define void @test2(double* %ptr, i32 %skip) {
+; CHECK-LABEL: Function: test2: 4 pointers, 0 call sites
+; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.1, double* %ptr
+; CHECK-NEXT:  MayAlias:    double* %col.ptr.2, double* %ptr
+; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.1, double* %col.ptr.2
+; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.2.cast, double* %ptr
+; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
+; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.2.cast, double* %col.ptr.2
+;
+  %stride = add nsw nuw i32 %skip, 6
+  %col.ptr.1 = bitcast double* %ptr to <6 x double>*
+  %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
+  %col.ptr.2= getelementptr double, double* %ptr, i32 %stride
+  %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
+  %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
+  %res.1 = fadd <6 x double> %lv.1, %lv.1
+  %res.2 = fadd <6 x double> %lv.2, %lv.2
+  store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8
+  store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8
+  ret void
+}
+
+; Same as @test1, but the assume just guarantees %skip > -3, which is not
+; enough to derive NoAlias
+define void @test3(double* %ptr, i32 %skip) {
+; CHECK-LABEL: Function: test3: 4 pointers, 1 call sites
+; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.1, double* %ptr
+; CHECK-NEXT:  MayAlias:    double* %col.ptr.2, double* %ptr
+; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.1, double* %col.ptr.2
+; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.2.cast, double* %ptr
+; CHECK-NEXT:  MayAlias:    <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
+; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.2.cast, double* %col.ptr.2
+; CHECK-NEXT:  NoModRef:  Ptr: double* %ptr <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.1 <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: double* %col.ptr.2   <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.2.cast    <->  call void @llvm.assume(i1 %gt)
+;
+  %gt = icmp sgt i32 %skip, -3
+  call void @llvm.assume(i1 %gt)
+  %stride = add nsw nuw i32 %skip, 6
+  %col.ptr.1 = bitcast double* %ptr to <6 x double>*
+  %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
+  %col.ptr.2= getelementptr double, double* %ptr, i32 %stride
+  %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
+  %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
+  %res.1 = fadd <6 x double> %lv.1, %lv.1
+  %res.2 = fadd <6 x double> %lv.2, %lv.2
+  store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8
+  store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8
+  ret void
+}
+
+; Same as @test1, but the assume uses the sge predicate for %skip >= 0.
+define void @test4(double* %ptr, i32 %skip) {
+; CHECK-LABEL: Function: test4: 4 pointers, 1 call sites
+; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.1, double* %ptr
+; CHECK-NEXT:  NoAlias:     double* %col.ptr.2, double* %ptr
+; CHECK-NEXT:  NoAlias:     <6 x double>* %col.ptr.1, double* %col.ptr.2
+; CHECK-NEXT:  NoAlias:     <6 x double>* %col.ptr.2.cast, double* %ptr
+; CHECK-NEXT:  NoAlias:     <6 x double>* %col.ptr.1, <6 x double>* %col.ptr.2.cast
+; CHECK-NEXT:  MustAlias:   <6 x double>* %col.ptr.2.cast, double* %col.ptr.2
+; CHECK-NEXT:  NoModRef:  Ptr: double* %ptr <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.1 <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: double* %col.ptr.2   <->  call void @llvm.assume(i1 %gt)
+; CHECK-NEXT:  NoModRef:  Ptr: <6 x double>* %col.ptr.2.cast    <->  call void @llvm.assume(i1 %gt)
+;
+  %gt = icmp sge i32 %skip, 0
+  call void @llvm.assume(i1 %gt)
+  %stride = add nsw nuw i32 %skip, 6
+  %col.ptr.1 = bitcast double* %ptr to <6 x double>*
+  %lv.1 = load <6 x double>, <6 x double>* %col.ptr.1, align 8
+  %col.ptr.2= getelementptr double, double* %ptr, i32 %stride
+  %col.ptr.2.cast = bitcast double* %col.ptr.2 to <6 x double>*
+  %lv.2 = load <6 x double>, <6 x double>* %col.ptr.2.cast, align 8
+  %res.1 = fadd <6 x double> %lv.1, %lv.1
+  %res.2 = fadd <6 x double> %lv.2, %lv.2
+  store <6 x double> %res.1, <6 x double>* %col.ptr.1, align 8
+  store <6 x double> %res.2, <6 x double>* %col.ptr.2.cast, align 8
+  ret void
+}
+
+declare void @llvm.assume(i1 %cond)


        


More information about the llvm-commits mailing list