[llvm] 3c74ed9 - [LAA] Fix ICE with scAddExpr in forked pointers
Graham Hunter via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 21 02:29:17 PDT 2022
Author: Graham Hunter
Date: 2022-09-21T10:27:06+01:00
New Revision: 3c74ed9ee3233d4272a7b213091a9fd1cb464d71
URL: https://github.com/llvm/llvm-project/commit/3c74ed9ee3233d4272a7b213091a9fd1cb464d71
DIFF: https://github.com/llvm/llvm-project/commit/3c74ed9ee3233d4272a7b213091a9fd1cb464d71.diff
LOG: [LAA] Fix ICE with scAddExpr in forked pointers
The IR from https://github.com/llvm/llvm-project/issues/57368 results
in an assert firing when trying to create a runtime check for the
forked pointer. One of the forks is fine since it's loop invariant,
but the other is a scAddExpr (containing a scAddRecExpr, so not
invariant) when RtCheck::insert expects a scAddRecExpr.
This is a simple fix to just avoid forks which aren't AddRec or
loop invariant. We can allow it as a forked pointer later with
more work.
Reviewed By: fhahn
Differential Revision: https://reviews.llvm.org/D133020
Added:
Modified:
llvm/lib/Analysis/LoopAccessAnalysis.cpp
llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index dc56d8d019b21..f06e412352859 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -954,9 +954,18 @@ findForkedPointer(PredicatedScalarEvolution &PSE,
SmallVector<std::pair<const SCEV *, bool>> Scevs;
findForkedSCEVs(SE, L, Ptr, Scevs, MaxForkedSCEVDepth);
- // For now, we will only accept a forked pointer with two possible SCEVs.
- if (Scevs.size() == 2)
+ // For now, we will only accept a forked pointer with two possible SCEVs
+ // that are either SCEVAddRecExprs or loop invariant.
+ if (Scevs.size() == 2 &&
+ (isa<SCEVAddRecExpr>(Scevs[0].first) ||
+ SE->isLoopInvariant(Scevs[0].first, L)) &&
+ (isa<SCEVAddRecExpr>(Scevs[1].first) ||
+ SE->isLoopInvariant(Scevs[1].first, L))) {
+ LLVM_DEBUG(dbgs() << "LAA: Found forked pointer: " << *Ptr << "\n");
+ LLVM_DEBUG(dbgs() << "\t(1) " << *(Scevs[0].first) << "\n");
+ LLVM_DEBUG(dbgs() << "\t(2) " << *(Scevs[1].first) << "\n");
return Scevs;
+ }
return {
std::make_pair(replaceSymbolicStrideSCEV(PSE, StridesMap, Ptr), false)};
diff --git a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
index efde509d75cf8..3f5c8e4c1c72f 100644
--- a/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
+++ b/llvm/test/Analysis/LoopAccessAnalysis/forked-pointers.ll
@@ -569,13 +569,13 @@ for.body: ; preds = %entry, %for.body
; CHECK-NEXT: Against group ([[G2:.+]]):
; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, ptr %Preds, i64 %indvars.iv
; CHECK-NEXT: Check 1:
-; CHECK-NEXT: Comparing group ([[G1:.+]]):
+; CHECK-NEXT: Comparing group ([[G1]]):
; CHECK-NEXT: %arrayidx5 = getelementptr inbounds float, ptr %Dest, i64 %indvars.iv
; CHECK-NEXT: Against group ([[G3:.+]]):
; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
; CHECK-NEXT: %arrayidx3 = getelementptr inbounds float, ptr %Base, i64 %offset
; CHECK-NEXT: Grouped accesses:
-; CHECK-NEXT: Group [[G1:.+]]:
+; CHECK-NEXT: Group [[G1]]:
; CHECK-NEXT: (Low: %Dest High: (400 + %Dest))
; CHECK-NEXT: Member: {%Dest,+,4}<nuw><%for.body>
; CHECK-NEXT: Group [[G2]]:
@@ -880,3 +880,59 @@ for.body:
for.cond.cleanup:
ret void
}
+
+; CHECK-LABEL: Loop access info in function 'sc_add_expr_ice':
+; CHECK-NEXT: for.body:
+; CHECK-NEXT: Memory dependences are safe with run-time checks
+; CHECK-NEXT: Dependences:
+; CHECK-NEXT: Run-time memory checks:
+; CHECK-NEXT: Check 0:
+; CHECK-NEXT: Comparing group ([[G1:.+]]):
+; CHECK-NEXT: ptr %Base1
+; CHECK-NEXT: Against group ([[G2:.+]]):
+; CHECK-NEXT: %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel
+; CHECK-NEXT: Grouped accesses:
+; CHECK-NEXT: Group [[G1]]:
+; CHECK-NEXT: (Low: %Base1 High: (8 + %Base1))
+; CHECK-NEXT: Member: %Base1
+; CHECK-NEXT: Group [[G2]]:
+; CHECK-NEXT: (Low: %Base2 High: ((8 * %N) + %Base2))
+; CHECK-NEXT: Member: {%Base2,+,8}<%for.body>
+; CHECK-EMPTY:
+; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
+; CHECK-NEXT: SCEV assumptions:
+; CHECK-NEXT: {0,+,1}<%for.body> Added Flags: <nusw>
+; CHECK-EMPTY:
+; CHECK-NEXT: Expressions re-written:
+; CHECK-NEXT: [PSE] %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel:
+; CHECK-NEXT: ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw>
+; CHECK-NEXT: --> {%Base2,+,8}<%for.body>
+
+;;; The following test caused an ICE with the initial forked pointers work.
+;;; One fork is loop invariant (%Base2 + 0), the other is an scAddExpr that
+;;; contains an scAddRecExpr inside it:
+;;; ((8 * (zext i32 {0,+,1}<%for.body> to i64))<nuw><nsw> + %Base2)<nuw>
+;;;
+;;; RtCheck::insert was expecting either loop invariant or SAR, so asserted
+;;; on a plain scAddExpr. For now we restrict to loop invariant or SAR
+;;; forks only, but we should be able to do better.
+
+define void @sc_add_expr_ice(ptr %Base1, ptr %Base2, i64 %N) {
+entry:
+ br label %for.body
+
+for.body:
+ %iv = phi i64 [ %iv.next, %for.body ], [ 0, %entry ]
+ %iv.trunc = trunc i64 %iv to i32
+ store double 0.000000e+00, ptr %Base1, align 8
+ %iv.zext = zext i32 %iv.trunc to i64
+ %sel = select i1 true, i64 %iv.zext, i64 0
+ %fptr = getelementptr inbounds double, ptr %Base2, i64 %sel
+ %dummy.load = load double, ptr %fptr, align 8
+ %iv.next = add nuw nsw i64 %iv, 1
+ %exitcond = icmp eq i64 %iv.next, %N
+ br i1 %exitcond, label %exit, label %for.body
+
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list