[llvm] a19cf47 - [LAA] Precommit some extra tests for forked pointers
Graham Hunter via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 13 02:33:48 PDT 2022
Author: Graham Hunter
Date: 2022-07-13T10:32:35+01:00
New Revision: a19cf47da095190fbf33bac8edb91483053e6766
URL: https://github.com/llvm/llvm-project/commit/a19cf47da095190fbf33bac8edb91483053e6766
DIFF: https://github.com/llvm/llvm-project/commit/a19cf47da095190fbf33bac8edb91483053e6766.diff
LOG: [LAA] Precommit some extra tests for forked pointers
* Converted tests to use opaque pointers
* Added suggested test for inbounds GEP
* Added a test for forks on both the base and offset terms of a GEP
* Added a test for a select of a select
* Added a test for a GEP with >2 operands
* Added a test for vector GEPs
Added:
Modified:
llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
Removed:
################################################################################
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
index b63c2f0cc556d..72837b7fb3642 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
@@ -9,16 +9,16 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
; CHECK-NEXT: Run-time memory checks:
; CHECK-NEXT: Check 0:
; CHECK-NEXT: Comparing group ([[G1:.+]]):
-; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, float* %Dest, i64 %iv
-; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, float* %Dest, i64 %iv
+; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
; CHECK-NEXT: Against group ([[G2:.+]]):
-; CHECK-NEXT: %select = select i1 %cmp, float* %gep.1, float* %gep.2
+; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
; CHECK-NEXT: Check 1:
; CHECK-NEXT: Comparing group ([[G1]]):
-; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, float* %Dest, i64 %iv
-; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, float* %Dest, i64 %iv
+; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+; CHECK-NEXT: %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
; CHECK-NEXT: Against group ([[G3:.+]]):
-; CHECK-NEXT: %select = select i1 %cmp, float* %gep.1, float* %gep.2
+; CHECK-NEXT: %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
; CHECK-NEXT: Grouped accesses:
; CHECK-NEXT: Group [[G1]]
; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))
@@ -36,20 +36,20 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
; CHECK-EMPTY:
; CHECK-NEXT: Expressions re-written:
-define void @forked_ptrs_simple(float* nocapture readonly %Base1, float* nocapture readonly %Base2, float* %Dest) {
+define void @forked_ptrs_simple(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr %Dest) {
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
- %gep.Dest = getelementptr inbounds float, float* %Dest, i64 %iv
- %l.Dest = load float, float* %gep.Dest
+ %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+ %l.Dest = load float, ptr %gep.Dest
%cmp = fcmp une float %l.Dest, 0.0
- %gep.1 = getelementptr inbounds float, float* %Base1, i64 %iv
- %gep.2 = getelementptr inbounds float, float* %Base2, i64 %iv
- %select = select i1 %cmp, float* %gep.1, float* %gep.2
- %sink = load float, float* %select, align 4
- store float %sink, float* %gep.Dest, align 4
+ %gep.1 = getelementptr inbounds float, ptr %Base1, i64 %iv
+ %gep.2 = getelementptr inbounds float, ptr %Base2, i64 %iv
+ %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+ %sink = load float, ptr %select, align 4
+ store float %sink, ptr %gep.Dest, align 4
%iv.next = add nuw nsw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, 100
br i1 %exitcond.not, label %exit, label %loop
@@ -58,18 +58,17 @@ exit:
ret void
}
-
; CHECK-LABEL: function 'forked_ptrs_
diff erent_base_same_offset':
-; CHECK-NEXT: for.body:
-; CHECK-NEXT: Report: cannot identify array bounds
-; CHECK-NEXT: Dependences:
-; CHECK-NEXT: Run-time memory checks:
-; CHECK-NEXT: Grouped accesses:
+; CHECK-NEXT: for.body:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
; CHECK-EMPTY:
-; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
-; CHECK-NEXT: SCEV assumptions:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
; CHECK-EMPTY:
-; CHECK-NEXT: Expressions re-written:
+; CHECK-NEXT: Expressions re-written:
;;;; Derived from the following C code
;; void forked_ptrs_
diff erent_base_same_offset(float *A, float *B, float *C, int *D) {
@@ -82,7 +81,7 @@ exit:
;; }
;; }
-define dso_local void @forked_ptrs_
diff erent_base_same_offset(float* nocapture readonly %Base1, float* nocapture readonly %Base2, float* nocapture %Dest, i32* nocapture readonly %Preds) {
+define dso_local void @forked_ptrs_
diff erent_base_same_offset(ptr nocapture readonly nonnull %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
entry:
br label %for.body
@@ -91,14 +90,54 @@ for.cond.cleanup:
for.body:
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
- %arrayidx = getelementptr inbounds i32, i32* %Preds, i64 %indvars.iv
- %0 = load i32, i32* %arrayidx, align 4
+ %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
+ %cmp1.not = icmp eq i32 %0, 0
+ %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1
+ %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+ %.sink = load float, ptr %.sink.in, align 4
+ %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+ store float %.sink, ptr %1, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 100
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+; CHECK-LABEL: function 'forked_ptrs_
diff erent_base_same_offset_possible_poison':
+; CHECK-NEXT: for.body:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
+; CHECK-EMPTY:
+; CHECK-NEXT: Expressions re-written:
+
+define dso_local void @forked_ptrs_
diff erent_base_same_offset_possible_poison(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds, i1 %c) {
+entry:
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %latch ]
+ %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
%cmp1.not = icmp eq i32 %0, 0
- %spec.select = select i1 %cmp1.not, float* %Base2, float* %Base1
- %.sink.in = getelementptr inbounds float, float* %spec.select, i64 %indvars.iv
- %.sink = load float, float* %.sink.in, align 4
- %1 = getelementptr inbounds float, float* %Dest, i64 %indvars.iv
- store float %.sink, float* %1, align 4
+ %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1
+ %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %indvars.iv
+ %.sink = load float, ptr %.sink.in, align 4
+ %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+ br i1 %c, label %then, label %latch
+
+then:
+ store float %.sink, ptr %1, align 4
+ br label %latch
+
+latch:
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%exitcond.not = icmp eq i64 %indvars.iv.next, 100
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
@@ -128,7 +167,7 @@ for.body:
;; }
;; }
-define dso_local void @forked_ptrs_same_base_
diff erent_offset(float* nocapture readonly %Base, float* nocapture %Dest, i32* nocapture readonly %Preds) {
+define dso_local void @forked_ptrs_same_base_
diff erent_offset(ptr nocapture readonly %Base, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
entry:
br label %for.body
@@ -138,18 +177,18 @@ for.cond.cleanup: ; preds = %for.body
for.body: ; preds = %entry, %for.body
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
%i.014 = phi i32 [ 0, %entry ], [ %add, %for.body ]
- %arrayidx = getelementptr inbounds i32, i32* %Preds, i64 %indvars.iv
- %0 = load i32, i32* %arrayidx, align 4
+ %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
%cmp1.not = icmp eq i32 %0, 0
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%add = add nuw nsw i32 %i.014, 1
%1 = trunc i64 %indvars.iv to i32
%offset.0 = select i1 %cmp1.not, i32 %add, i32 %1
%idxprom213 = zext i32 %offset.0 to i64
- %arrayidx3 = getelementptr inbounds float, float* %Base, i64 %idxprom213
- %2 = load float, float* %arrayidx3, align 4
- %arrayidx5 = getelementptr inbounds float, float* %Dest, i64 %indvars.iv
- store float %2, float* %arrayidx5, align 4
+ %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %idxprom213
+ %2 = load float, ptr %arrayidx3, align 4
+ %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+ store float %2, ptr %arrayidx5, align 4
%exitcond.not = icmp eq i64 %indvars.iv.next, 100
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
}
@@ -181,8 +220,8 @@ for.cond.cleanup: ; preds = %for.body
for.body: ; preds = %entry, %for.body
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
%i.014 = phi i32 [ 0, %entry ], [ %add, %for.body ]
- %arrayidx = getelementptr inbounds i32, i32* %Preds, i64 %indvars.iv
- %0 = load i32, i32* %arrayidx, align 4
+ %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
%cmp1.not = icmp eq i32 %0, 0
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%add = add nuw nsw i32 %i.014, 1
@@ -190,10 +229,10 @@ for.body: ; preds = %entry, %for.body
%mul = mul i32 %1, 3
%offset.0 = select i1 %cmp1.not, i32 4, i32 %mul
%idxprom213 = sext i32 %offset.0 to i64
- %arrayidx3 = getelementptr inbounds float, float* %Base, i64 %idxprom213
- %2 = load float, float* %arrayidx3, align 4
- %arrayidx5 = getelementptr inbounds float, float* %Dest, i64 %indvars.iv
- store float %2, float* %arrayidx5, align 4
+ %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %idxprom213
+ %2 = load float, ptr %arrayidx3, align 4
+ %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+ store float %2, ptr %arrayidx5, align 4
%exitcond.not = icmp eq i64 %indvars.iv.next, 100
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
}
@@ -214,7 +253,7 @@ for.body: ; preds = %entry, %for.body
;;;; added using Preds as an index array in addition to the per-iteration
;;;; condition.
-define dso_local void @forked_ptrs_gather_and_contiguous_forks(float* nocapture readonly %Base1, float* nocapture readonly %Base2, float* nocapture %Dest, i32* nocapture readonly %Preds) {
+define dso_local void @forked_ptrs_gather_and_contiguous_forks(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
entry:
br label %for.body
@@ -223,17 +262,164 @@ for.cond.cleanup: ; preds = %for.body
for.body: ; preds = %entry, %for.body
%indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
- %arrayidx = getelementptr inbounds i32, i32* %Preds, i64 %indvars.iv
- %0 = load i32, i32* %arrayidx, align 4
+ %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
%cmp1.not = icmp eq i32 %0, 0
- %arrayidx9 = getelementptr inbounds float, float* %Base2, i64 %indvars.iv
+ %arrayidx9 = getelementptr inbounds float, ptr %Base2, i64 %indvars.iv
%idxprom4 = sext i32 %0 to i64
- %arrayidx5 = getelementptr inbounds float, float* %Base1, i64 %idxprom4
- %.sink.in = select i1 %cmp1.not, float* %arrayidx9, float* %arrayidx5
- %.sink = load float, float* %.sink.in, align 4
- %1 = getelementptr inbounds float, float* %Dest, i64 %indvars.iv
- store float %.sink, float* %1, align 4
+ %arrayidx5 = getelementptr inbounds float, ptr %Base1, i64 %idxprom4
+ %.sink.in = select i1 %cmp1.not, ptr %arrayidx9, ptr %arrayidx5
+ %.sink = load float, ptr %.sink.in, align 4
+ %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+ store float %.sink, ptr %1, align 4
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%exitcond.not = icmp eq i64 %indvars.iv.next, 100
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
}
+
+;; We don't currently handle a fork in both the base and the offset of a
+;; GEP instruction.
+
+; CHECK-LABEL: Loop access info in function 'forked_ptrs_two_forks_gep':
+; CHECK-NEXT: for.body:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
+; CHECK-EMPTY:
+; CHECK-NEXT: Expressions re-written:
+
+define dso_local void @forked_ptrs_two_forks_gep(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+entry:
+ br label %for.body
+
+for.cond.cleanup:
+ ret void
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds i32, i32* %Preds, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
+ %cmp1.not = icmp eq i32 %0, 0
+ %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %offset = select i1 %cmp1.not, i64 %indvars.iv.next, i64 %indvars.iv
+ %.sink.in = getelementptr inbounds float, ptr %spec.select, i64 %offset
+ %.sink = load float, ptr %.sink.in, align 4
+ %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+ store float %.sink, ptr %1, align 4
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 100
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+}
+
+;; We don't handle forks as children of a select
+
+; CHECK-LABEL: Loop access info in function 'forked_ptrs_two_select':
+; CHECK-NEXT: loop:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
+; CHECK-EMPTY:
+; CHECK-NEXT: Expressions re-written:
+
+define void @forked_ptrs_two_select(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture readonly %Base3, ptr %Dest) {
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %gep.Dest = getelementptr inbounds float, ptr %Dest, i64 %iv
+ %l.Dest = load float, ptr %gep.Dest
+ %cmp = fcmp une float %l.Dest, 0.0
+ %cmp1 = fcmp une float %l.Dest, 1.0
+ %gep.1 = getelementptr inbounds float, ptr %Base1, i64 %iv
+ %gep.2 = getelementptr inbounds float, ptr %Base2, i64 %iv
+ %gep.3 = getelementptr inbounds float, ptr %Base3, i64 %iv
+ %select = select i1 %cmp, ptr %gep.1, ptr %gep.2
+ %select1 = select i1 %cmp1, ptr %select, ptr %gep.3
+ %sink = load float, ptr %select1, align 4
+ store float %sink, ptr %gep.Dest, align 4
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond.not = icmp eq i64 %iv.next, 100
+ br i1 %exitcond.not, label %exit, label %loop
+
+exit:
+ ret void
+}
+
+;; We don't yet handle geps with more than 2 operands
+; CHECK-LABEL: Loop access info in function 'forked_ptrs_too_many_gep_ops':
+; CHECK-NEXT: for.body:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
+; CHECK-EMPTY:
+; CHECK-NEXT: Expressions re-written:
+
+define void @forked_ptrs_too_many_gep_ops(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
+ %cmp1.not = icmp eq i32 %0, 0
+ %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1
+ %.sink.in = getelementptr inbounds [1000 x float], ptr %spec.select, i64 0, i64 %indvars.iv
+ %.sink = load float, ptr %.sink.in, align 4
+ %1 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
+ store float %.sink, ptr %1, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 100
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+
+for.cond.cleanup:
+ ret void
+}
+
+;; We don't currently handle vector GEPs
+; CHECK-LABEL: Loop access info in function 'forked_ptrs_vector_gep':
+; CHECK-NEXT: for.body:
+; CHECK-NEXT: Report: cannot identify array bounds
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Grouped accesses:
+; CHECK-EMPTY:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
+; CHECK-EMPTY:
+; CHECK-NEXT: Expressions re-written:
+
+define void @forked_ptrs_vector_gep(ptr nocapture readonly %Base1, ptr nocapture readonly %Base2, ptr nocapture %Dest, ptr nocapture readonly %Preds) {
+entry:
+ br label %for.body
+
+for.body:
+ %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+ %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
+ %0 = load i32, ptr %arrayidx, align 4
+ %cmp1.not = icmp eq i32 %0, 0
+ %spec.select = select i1 %cmp1.not, ptr %Base2, ptr %Base1
+ %.sink.in = getelementptr inbounds <4 x float>, ptr %spec.select, i64 %indvars.iv
+ %.sink = load <4 x float>, ptr %.sink.in, align 4
+ %1 = getelementptr inbounds <4 x float>, ptr %Dest, i64 %indvars.iv
+ store <4 x float> %.sink, ptr %1, align 4
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 4
+ %exitcond.not = icmp eq i64 %indvars.iv.next, 100
+ br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
+
+for.cond.cleanup:
+ ret void
+}
More information about the llvm-commits
mailing list