[polly] [polly] Bound ISL operations during pre-vectorization (PR #143876)
Shikhar Jain via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 25 06:41:45 PDT 2025
https://github.com/ShikharjQUIC updated https://github.com/llvm/llvm-project/pull/143876
>From b6fce5961cc1860465ab1201d82d0f90c18ace94 Mon Sep 17 00:00:00 2001
From: ShikharJain <shikharj at qti.qualcomm.com>
Date: Fri, 23 May 2025 07:29:01 -0700
Subject: [PATCH] [polly] Bound ISL operations during pre-vectorization
Bound ISL operations during pre-vectorization to
prevent indefinite compilation. If the bound fails,
mark the SCoP invalid. Includes relevant unit test.
Fixes #132717.
---
polly/lib/Transform/ScheduleOptimizer.cpp | 23 ++++++++++-
.../prevectorization_islbound.ll | 41 +++++++++++++++++++
2 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 polly/test/ScheduleOptimizer/prevectorization_islbound.ll
diff --git a/polly/lib/Transform/ScheduleOptimizer.cpp b/polly/lib/Transform/ScheduleOptimizer.cpp
index 070700a64a168..8bd4f20636cdc 100644
--- a/polly/lib/Transform/ScheduleOptimizer.cpp
+++ b/polly/lib/Transform/ScheduleOptimizer.cpp
@@ -387,6 +387,8 @@ ScheduleTreeOptimizer::isolateFullPartialTiles(isl::schedule_node Node,
isl::union_set ScheduleRangeUSet = SchedRelUMap.range();
isl::set ScheduleRange{ScheduleRangeUSet};
isl::set IsolateDomain = getPartialTilePrefixes(ScheduleRange, VectorWidth);
+ if (IsolateDomain.is_null())
+ return isl::schedule_node();
auto AtomicOption = getDimOptions(IsolateDomain.ctx(), "atomic");
isl::union_set IsolateOption = getIsolateOptions(IsolateDomain, 1);
Node = Node.parent().parent();
@@ -430,6 +432,8 @@ isl::schedule_node ScheduleTreeOptimizer::prevectSchedBand(
Node =
isl::manage(isl_schedule_node_band_tile(Node.release(), Sizes.release()));
Node = isolateFullPartialTiles(Node, VectorWidth);
+ if (Node.is_null())
+ return isl::schedule_node();
Node = Node.child(0);
// Make sure the "trivially vectorizable loop" is not unrolled. Otherwise,
// we will have troubles to match it in the backend.
@@ -543,6 +547,8 @@ ScheduleTreeOptimizer::applyPrevectBandOpt(isl::schedule_node Node) {
break;
}
+ if (Node.is_null())
+ return isl::schedule_node();
return Node;
}
@@ -574,7 +580,12 @@ ScheduleTreeOptimizer::optimizeBand(__isl_take isl_schedule_node *NodeArg,
if (OAI->Prevect) {
// FIXME: Prevectorization requirements are different from those checked by
// isTileableBandNode.
- Node = applyPrevectBandOpt(Node);
+ {
+ IslMaxOperationsGuard MaxOpGuard(Node.ctx().get(), ScheduleComputeOut);
+ Node = applyPrevectBandOpt(Node);
+ if (MaxOpGuard.hasQuotaExceeded() || Node.is_null())
+ return (isl::schedule_node()).release();
+ }
}
return Node.release();
@@ -585,6 +596,8 @@ ScheduleTreeOptimizer::optimizeSchedule(isl::schedule Schedule,
const OptimizerAdditionalInfoTy *OAI) {
auto Root = Schedule.get_root();
Root = optimizeScheduleNode(Root, OAI);
+ if (Root.is_null())
+ return isl::schedule();
return Root.get_schedule();
}
@@ -593,6 +606,8 @@ isl::schedule_node ScheduleTreeOptimizer::optimizeScheduleNode(
Node = isl::manage(isl_schedule_node_map_descendant_bottom_up(
Node.release(), optimizeBand,
const_cast<void *>(static_cast<const void *>(OAI))));
+ if (Node.is_null())
+ return isl::schedule_node();
return Node;
}
@@ -908,6 +923,12 @@ static void runIslScheduleOptimizer(
DepsChanged};
if (OAI.PatternOpts || OAI.Postopts || OAI.Prevect) {
Schedule = ScheduleTreeOptimizer::optimizeSchedule(Schedule, &OAI);
+ if (Schedule.is_null()) {
+ POLLY_DEBUG(dbgs() << "Invalidating scop from further optimization as "
+ "max operations exceeded\n");
+ S.invalidate(COMPLEXITY, DebugLoc());
+ return;
+ }
Schedule = hoistExtensionNodes(Schedule);
POLLY_DEBUG(printSchedule(dbgs(), Schedule, "After post-optimizations"));
walkScheduleTreeForStatistics(Schedule, 2);
diff --git a/polly/test/ScheduleOptimizer/prevectorization_islbound.ll b/polly/test/ScheduleOptimizer/prevectorization_islbound.ll
new file mode 100644
index 0000000000000..bf6a763a616ef
--- /dev/null
+++ b/polly/test/ScheduleOptimizer/prevectorization_islbound.ll
@@ -0,0 +1,41 @@
+; RUN: opt %loadNPMPolly -S "-polly-vectorizer=stripmine" -polly-opt-isl -polly-debug -disable-output < %s 2>&1 | FileCheck %s
+; REQUIRES: asserts
+; ModuleID = '<stdin>'
+source_filename = "<stdin>"
+target datalayout = "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
+target triple = "i386-unknown-linux-gnu"
+
+define void @ham(ptr %arg, ptr %arg1, i32 %arg2, i32 %arg3, ptr %arg4, i32 %arg5, i32 %arg6) {
+bb:
+ %getelementptr = getelementptr [7 x float], ptr null, i32 0, i32 %arg3
+ br label %bb7
+
+bb7: ; preds = %bb11, %bb
+ %phi = phi i32 [ 0, %bb ], [ %add16, %bb11 ]
+ br label %bb8
+
+bb8: ; preds = %bb8, %bb7
+ %phi9 = phi i32 [ 0, %bb7 ], [ %add, %bb8 ]
+ %getelementptr10 = getelementptr [7 x float], ptr null, i32 0, i32 %phi9
+ store float 0.000000e+00, ptr %getelementptr10, align 4
+ %add = add i32 %phi9, 1
+ %icmp = icmp eq i32 %phi9, 0
+ br i1 %icmp, label %bb8, label %bb11
+
+bb11: ; preds = %bb8
+ %load = load float, ptr %getelementptr, align 4
+ store float %load, ptr %arg4, align 4
+ %getelementptr12 = getelementptr [7 x float], ptr null, i32 0, i32 %arg5
+ %load13 = load float, ptr %getelementptr12, align 4
+ store float %load13, ptr %arg, align 4
+ %getelementptr14 = getelementptr [7 x float], ptr null, i32 0, i32 %arg6
+ %load15 = load float, ptr %getelementptr14, align 4
+ store float %load15, ptr %arg1, align 4
+ %add16 = add i32 %phi, 1
+ %icmp17 = icmp ne i32 %phi, %arg2
+ br i1 %icmp17, label %bb7, label %bb18
+
+bb18: ; preds = %bb11
+ ret void
+}
+; CHECK:Invalidating scop from further optimization as max operations exceeded
More information about the llvm-commits
mailing list