[llvm] 9405af1 - [LAA] Require AddRecs to be in the innermost loop for diff-checks.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 26 12:40:21 PDT 2022
Author: Florian Hahn
Date: 2022-08-26T20:39:52+01:00
New Revision: 9405af1c850139f6ddd6d35ff395756fe2aef31f
URL: https://github.com/llvm/llvm-project/commit/9405af1c850139f6ddd6d35ff395756fe2aef31f
DIFF: https://github.com/llvm/llvm-project/commit/9405af1c850139f6ddd6d35ff395756fe2aef31f.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.
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 5a01a8e4b0558..4ae55b80294e7 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 180f3fe9befc4..b6e05298bb78a 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -281,7 +281,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-commits
mailing list