[llvm-branch-commits] [llvm] 9070c25 - [LAA] Require AddRecs to be in the innermost loop for diff-checks.
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Aug 29 23:09:59 PDT 2022
Author: Florian Hahn
Date: 2022-08-30T08:08:28+02:00
New Revision: 9070c258c143d6666274da3c70971bd266cabb82
URL: https://github.com/llvm/llvm-project/commit/9070c258c143d6666274da3c70971bd266cabb82
DIFF: https://github.com/llvm/llvm-project/commit/9070c258c143d6666274da3c70971bd266cabb82.diff
LOG: [LAA] Require AddRecs to be in the innermost loop for diff-checks.
The simpler diff-checks require pointers with add-recs from the same
innermost loop, but this property wasn't check completely. Add the
missing check to ensure both addrecs are in the innermost loop.
Fixes #57315.
(cherry picked from commit 9405af1c850139f6ddd6d35ff395756fe2aef31f)
Added:
Modified:
llvm/include/llvm/Analysis/LoopAccessAnalysis.h
llvm/lib/Analysis/LoopAccessAnalysis.cpp
llvm/test/Transforms/LoopVectorize/runtime-checks-difference.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
index 8f71ce9e96c05..af8e8d22269e4 100644
--- a/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -253,6 +253,8 @@ class MemoryDepChecker {
return {};
}
+ const Loop *getInnermostLoop() const { return InnermostLoop; }
+
private:
/// A wrapper around ScalarEvolution, used to add runtime SCEV checks, and
/// applies dynamic knowledge to simplify SCEV expressions and convert them
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index aa35f253bc5f0..8311b480ab099 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -280,7 +280,8 @@ void RuntimePointerChecking::tryToCreateDiffCheck(
auto *SrcAR = dyn_cast<SCEVAddRecExpr>(Src->Expr);
auto *SinkAR = dyn_cast<SCEVAddRecExpr>(Sink->Expr);
- if (!SrcAR || !SinkAR) {
+ if (!SrcAR || !SinkAR || SrcAR->getLoop() != DC.getInnermostLoop() ||
+ SinkAR->getLoop() != DC.getInnermostLoop()) {
CanUseDiffCheck = false;
return;
}
diff --git a/llvm/test/Transforms/LoopVectorize/runtime-checks-
diff erence.ll b/llvm/test/Transforms/LoopVectorize/runtime-checks-
diff erence.ll
index c8595aee2fe9d..bdafe9f4daaae 100644
--- a/llvm/test/Transforms/LoopVectorize/runtime-checks-
diff erence.ll
+++ b/llvm/test/Transforms/LoopVectorize/runtime-checks-
diff erence.ll
@@ -172,18 +172,29 @@ exit:
ret void
}
-; FIXME: Full no-overlap checks are required instead of
diff erence checks, as
+; Full no-overlap checks are required instead of
diff erence checks, as
; one of the add-recs used is invariant in the inner loop.
; Test case for PR57315.
define void @nested_loop_outer_iv_addrec_invariant_in_inner1(ptr %a, ptr %b, i64 %n) {
; CHECK-LABEL: @nested_loop_outer_iv_addrec_invariant_in_inner1(
-; CHECK: entry:
-; CHECK-NEXT: [[B:%.*]] = ptrtoint ptr %b to i64
-; CHECK-NEXT: [[A:%.*]] = ptrtoint ptr %a to i64
+; CHECK: entry:
+; CHECK-NEXT: [[N_SHL_2:%.]] = shl i64 %n, 2
+; CHECK-NEXT: [[B_GEP_UPPER:%.*]] = getelementptr i8, ptr %b, i64 [[N_SHL_2]]
+; CHECK-NEXT: br label %outer
+
+; CHECK: outer.header:
+; CHECK: [[OUTER_IV_SHL_2:%.]] = shl i64 %outer.iv, 2
+; CHECK-NEXT: [[A_GEP_UPPER:%.*]] = getelementptr i8, ptr %a, i64 [[OUTER_IV_SHL_2]]
+; CHECK-NEXT: [[OUTER_IV_4:%.]] = add i64 [[OUTER_IV_SHL_2]], 4
+; CHECK-NEXT: [[A_GEP_UPPER_4:%.*]] = getelementptr i8, ptr %a, i64 [[OUTER_IV_4]]
+; CHECK: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
+
; CHECK: vector.memcheck:
-; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[A]], [[B]]
-; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP1]], 16
-; CHECK-NEXT: br i1 [[DIFF_CHECK]], label %scalar.ph, label %vector.ph
+; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr [[A_GEP_UPPER]], [[B_GEP_UPPER]]
+; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr %b, [[A_GEP_UPPER_4]]
+; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
+; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label %scalar.ph, label %vector.ph
;
entry:
br label %outer.header
@@ -216,13 +227,24 @@ exit:
; sink and source swapped.
define void @nested_loop_outer_iv_addrec_invariant_in_inner2(ptr %a, ptr %b, i64 %n) {
; CHECK-LABEL: @nested_loop_outer_iv_addrec_invariant_in_inner2(
-; CHECK: entry:
-; CHECK-NEXT: [[A:%.*]] = ptrtoint ptr %a to i64
-; CHECK-NEXT: [[B:%.*]] = ptrtoint ptr %b to i64
+; CHECK: entry:
+; CHECK-NEXT: [[N_SHL_2:%.]] = shl i64 %n, 2
+; CHECK-NEXT: [[B_GEP_UPPER:%.*]] = getelementptr i8, ptr %b, i64 [[N_SHL_2]]
+; CHECK-NEXT: br label %outer
+
+; CHECK: outer.header:
+; CHECK: [[OUTER_IV_SHL_2:%.]] = shl i64 %outer.iv, 2
+; CHECK-NEXT: [[A_GEP_UPPER:%.*]] = getelementptr i8, ptr %a, i64 [[OUTER_IV_SHL_2]]
+; CHECK-NEXT: [[OUTER_IV_4:%.]] = add i64 [[OUTER_IV_SHL_2]], 4
+; CHECK-NEXT: [[A_GEP_UPPER_4:%.*]] = getelementptr i8, ptr %a, i64 [[OUTER_IV_4]]
+; CHECK: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N:%.*]], 4
+; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %scalar.ph, label %vector.memcheck
+
; CHECK: vector.memcheck:
-; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[B]], [[A]]
-; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP1]], 16
-; CHECK-NEXT: br i1 [[DIFF_CHECK]], label %scalar.ph, label %vector.ph
+; CHECK-NEXT: [[BOUND0:%.*]] = icmp ult ptr %b, [[A_GEP_UPPER_4]]
+; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult ptr [[A_GEP_UPPER]], [[B_GEP_UPPER]]
+; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
+; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label %scalar.ph, label %vector.ph
;
entry:
br label %outer.header
More information about the llvm-branch-commits
mailing list