[polly] [Polly] Do not invalidate SCEV before codegen (PR #194677)
Michael Kruse via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 28 09:59:06 PDT 2026
https://github.com/Meinersbur created https://github.com/llvm/llvm-project/pull/194677
ScopInfo expects the state of the IR to reflect the state before codegen. Invalidating ScalarEvolution/SCEVs has the effect that values need to be reanalyzed, but this is not possible during codegen where the CFG and SSA is not yet in a consistent state. That is, we rely on ScalarEvolution to cache SCEVs from before the codegen phase. If ScalarEvolution did not already do this, Polly would need to more aggressively store SCEVs itself (in this case: `canSyntheziseInStmt`) instead of asking ScalarEvolution.
The SCEV invalidation was introduced in a61eda769890900903ee65278bf1ee07dfbd4ca5 which unfortunately does not explain the issue it intends to fix. The added test case passes even without the invalidation. In any case, SCEVs should represent the state before codegen.
Fixes #192298
>From 44e0fa47097c7c262d668c57d6c75176c6bd59eb Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Tue, 28 Apr 2026 18:30:20 +0200
Subject: [PATCH] Fix invalidated SCEV result
---
polly/lib/CodeGen/IslNodeBuilder.cpp | 5 ---
polly/test/ScopDetect/issue192298.ll | 61 ++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 5 deletions(-)
create mode 100644 polly/test/ScopDetect/issue192298.ll
diff --git a/polly/lib/CodeGen/IslNodeBuilder.cpp b/polly/lib/CodeGen/IslNodeBuilder.cpp
index b1c6dd37d8299..0f9ca1479eaef 100644
--- a/polly/lib/CodeGen/IslNodeBuilder.cpp
+++ b/polly/lib/CodeGen/IslNodeBuilder.cpp
@@ -1090,11 +1090,6 @@ Value *IslNodeBuilder::preloadUnconditionally(isl::set AccessRange,
if (LoadInst *PreloadInst = dyn_cast<LoadInst>(PreloadVal))
PreloadInst->setAlignment(cast<LoadInst>(AccInst)->getAlign());
- // TODO: This is only a hot fix for SCoP sequences that use the same load
- // instruction contained and hoisted by one of the SCoPs.
- if (SE.isSCEVable(Ty))
- SE.forgetValue(AccInst);
-
return PreloadVal;
}
diff --git a/polly/test/ScopDetect/issue192298.ll b/polly/test/ScopDetect/issue192298.ll
new file mode 100644
index 0000000000000..d9477ac60e2eb
--- /dev/null
+++ b/polly/test/ScopDetect/issue192298.ll
@@ -0,0 +1,61 @@
+; RUN: opt %loadNPMPolly -passes="polly-custom<detect>" -polly-invariant-load-hoisting=true -polly-print-detect -disable-output %s | FileCheck %s --check-prefix=DETECT
+; RUN: opt %loadNPMPolly -passes="polly-custom<detect;codegen>" -polly-invariant-load-hoisting=true -S %s | FileCheck %s --check-prefix=CODEGEN
+;
+; https://github.com/llvm/llvm-project/issues/192208
+; If not already cached, getSCEV(%phi) would try to re-derive the
+; SCEVAddRecExpr which will not work during the codegen phase where the SSA form
+; has not been restored yet.
+;
+; DETECT: Valid Region for Scop: bb3 => bb5
+; DETECT: Valid Region for Scop: bb10.peel => bb3
+;
+; CODEGEN: polly.start:
+; CODEGEN: polly.start6:
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+
+
+; Function Attrs: nofree norecurse nosync nounwind memory(argmem: readwrite)
+define noundef i32 @wombat(ptr writeonly captures(none) initializes((0, 1)) %arg, ptr readonly captures(none) %arg1, i1 %arg2) local_unnamed_addr #0 {
+bb:
+ br label %bb3
+
+bb3.loopexit: ; preds = %bb10, %bb10.peel
+ %add11.lcssa = phi i32 [ %add11.peel, %bb10.peel ], [ %add11, %bb10 ]
+ br label %bb3
+
+bb3: ; preds = %bb3.loopexit, %bb
+ %phi = phi i32 [ 0, %bb ], [ %add11.lcssa, %bb3.loopexit ]
+ %load = load i8, ptr %arg1, align 4
+ %icmp = icmp eq i8 %load, 0
+ br i1 %icmp, label %bb4, label %bb5
+
+bb4: ; preds = %bb3
+ store i32 0, ptr %arg, align 8
+ br label %bb5
+
+bb5: ; preds = %bb4, %bb3
+ store i8 0, ptr %arg, align 1
+ br i1 %arg2, label %bb9, label %bb10.peel
+
+bb10.peel: ; preds = %bb5
+ %zext = zext i8 %load to i32
+ %add = add nuw nsw i32 %phi, %zext
+ %add11.peel = add nuw nsw i32 %add, 1
+ %icmp12.peel = icmp samesign ugt i32 %add, 1
+ br i1 %icmp12.peel, label %bb10, label %bb3.loopexit
+
+bb9: ; preds = %bb5
+ ret i32 0
+
+bb10: ; preds = %bb10, %bb10.peel
+ %phi8 = phi i32 [ %add11, %bb10 ], [ %add11.peel, %bb10.peel ]
+ %add11 = add i32 %phi8, 1
+ %icmp12 = icmp ugt i32 %phi8, 1
+ br i1 %icmp12, label %bb10, label %bb3.loopexit, !llvm.loop !0
+}
+
+attributes #0 = { nofree norecurse nosync nounwind memory(argmem: readwrite) }
+
+!0 = distinct !{!0, !1}
+!1 = !{!"llvm.loop.peeled.count", i32 1}
More information about the llvm-commits
mailing list