Skip to content

[mlir][intrange] Fix inference of zero-trip loop bound #96429

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 24, 2024

Conversation

ubfx
Copy link
Member

@ubfx ubfx commented Jun 23, 2024

When lower bound and exclusive upper bound of a loop are the same, and the zero-trip loop is not canonicalized away before the analysis, this leads to a meaningless range for the induction variable being inferred. This patch adds a check to make sure that the inferred range for the IV is meaningful before updating the analysis state.

Fix #94423

When lower bound and exclusive upper bound of a loop are the same, and
the zero-trip loop is not canonicalized away before the analysis, this
leads to a meaningless range for the induction variable being inferred.
This patch adds a check to make sure that the inferred range for the IV
is meaningful before updating the analysis state.

Fix llvm#94423
@llvmbot
Copy link
Member

llvmbot commented Jun 23, 2024

@llvm/pr-subscribers-mlir-arith

@llvm/pr-subscribers-mlir

Author: Felix Schneider (ubfx)

Changes

When lower bound and exclusive upper bound of a loop are the same, and the zero-trip loop is not canonicalized away before the analysis, this leads to a meaningless range for the induction variable being inferred. This patch adds a check to make sure that the inferred range for the IV is meaningful before updating the analysis state.

Fix #94423


Full diff: https://github.com/llvm/llvm-project/pull/96429.diff

2 Files Affected:

  • (modified) mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp (+8-3)
  • (modified) mlir/test/Dialect/Arith/int-range-interface.mlir (+18)
diff --git a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
index 9721620807a0f..244ce8b9c2ac6 100644
--- a/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
+++ b/mlir/lib/Analysis/DataFlow/IntegerRangeAnalysis.cpp
@@ -195,9 +195,14 @@ void IntegerRangeAnalysis::visitNonControlFlowArguments(
       max -= 1;
     }
 
-    IntegerValueRangeLattice *ivEntry = getLatticeElement(*iv);
-    auto ivRange = ConstantIntRanges::fromSigned(min, max);
-    propagateIfChanged(ivEntry, ivEntry->join(IntegerValueRange{ivRange}));
+    // If we infer the lower bound to be larger than the upper bound, the
+    // resulting range is meaningless and should not be used in further
+    // inferences.
+    if (max.sge(min)) {
+      IntegerValueRangeLattice *ivEntry = getLatticeElement(*iv);
+      auto ivRange = ConstantIntRanges::fromSigned(min, max);
+      propagateIfChanged(ivEntry, ivEntry->join(IntegerValueRange{ivRange}));
+    }
     return;
   }
 
diff --git a/mlir/test/Dialect/Arith/int-range-interface.mlir b/mlir/test/Dialect/Arith/int-range-interface.mlir
index e00b7692fe396..48fdb1cdced4d 100644
--- a/mlir/test/Dialect/Arith/int-range-interface.mlir
+++ b/mlir/test/Dialect/Arith/int-range-interface.mlir
@@ -918,3 +918,21 @@ func.func @test_cmpf_propagates(%a: f32, %b: f32) -> index {
   func.return %2 : index
 }
 
+// CHECK-LABEL: func @zero_trip_loop
+func.func @zero_trip_loop() {
+  %idx1 = arith.constant 1 : index
+  scf.for %arg0 = %idx1 to %idx1 step %idx1 {
+    %138 = index.floordivs %arg0, %arg0
+  }
+  return
+}
+
+// CHECK-LABEL: func @zero_trip_loop2
+func.func @zero_trip_loop2() {
+  %idx1 = arith.constant 1 : index
+  %idxm1 = arith.constant -1 : index
+  scf.for %arg0 = %idx1 to %idx1 step %idxm1 {
+    %138 = index.floordivs %arg0, %arg0
+  }
+  return
+}

Copy link
Contributor

@krzysz00 krzysz00 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved, thanks!

Also, I'm now thinking we might want to move to a signed and unsigned ConstantRsnge from LLVM ...

@ubfx
Copy link
Member Author

ubfx commented Jun 24, 2024

we might want to move to a signed and unsigned ConstantRsnge from LLVM

Thank you for the hint, I'll look it up

@ubfx ubfx merged commit b78883f into llvm:main Jun 24, 2024
10 checks passed
@ubfx ubfx deleted the intrange-fix-zero-trip branch June 24, 2024 06:05
AlexisPerry pushed a commit to llvm-project-tlp/llvm-project that referenced this pull request Jul 9, 2024
When lower bound and exclusive upper bound of a loop are the same, and
the zero-trip loop is not canonicalized away before the analysis, this
leads to a meaningless range for the induction variable being inferred.
This patch adds a check to make sure that the inferred range for the IV
is meaningful before updating the analysis state.

Fix llvm#94423
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[mlir] Crash when using --arith-unsigned-when-equivalent
3 participants