-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[mlir][affine] Add Check for 'affine.for' Bound Map Results #127105
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
Conversation
@llvm/pr-subscribers-mlir Author: Ayokunle Amodu (ayokunle321) ChangesRelated to issue #120001. I learnt that we shouldn’t assert on IR that can be constructed and passes the verifier. In this case, it appears that the verifier is insufficiently strict and should be tightened. Since the maps used in the affine.for op below do not have results, the IR verification should fail however it does not. Minimal example: #map = affine_map<() -> ()> This gets past the verifier, but I added a check to see that it causes an error if an affine.for has a bound map with no result. Open to any comments or clarifications :) Full diff: https://github.com/llvm/llvm-project/pull/127105.diff 2 Files Affected:
diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
index 147f5dd7a24b6..06e26e887b050 100644
--- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
@@ -1903,6 +1903,12 @@ LogicalResult AffineForOp::verifyRegions() {
getUpperBoundMap().getNumDims())))
return failure();
+ if (getLowerBoundMap().getNumResults() < 1)
+ return emitOpError("expected lower bound map to have at least one result");
+
+ if (getUpperBoundMap().getNumResults() < 1)
+ return emitOpError("expected upper bound map to have at least one result");
+
unsigned opNumResults = getNumResults();
if (opNumResults == 0)
return success();
diff --git a/mlir/test/Dialect/Affine/invalid.mlir b/mlir/test/Dialect/Affine/invalid.mlir
index 44e484b9ba598..5a3243cb074c1 100644
--- a/mlir/test/Dialect/Affine/invalid.mlir
+++ b/mlir/test/Dialect/Affine/invalid.mlir
@@ -523,3 +523,25 @@ func.func @dynamic_dimension_index() {
}) : () -> ()
return
}
+
+// -----
+
+#map = affine_map<() -> ()>
+#map1 = affine_map<() -> (1)>
+func.func @no_lower_bound() {
+ // expected-error@+1 {{'affine.for' op expected lower bound map to have at least one result}}
+ affine.for %i = max #map() to min #map1() {
+ }
+ return
+}
+
+// -----
+
+#map = affine_map<() -> ()>
+#map1 = affine_map<() -> (1)>
+func.func @no_upper_bound() {
+ // expected-error@+1 {{'affine.for' op expected upper bound map to have at least one result}}
+ affine.for %i = max #map1() to min #map() {
+ }
+ return
+}
|
@llvm/pr-subscribers-mlir-affine Author: Ayokunle Amodu (ayokunle321) ChangesRelated to issue #120001. I learnt that we shouldn’t assert on IR that can be constructed and passes the verifier. In this case, it appears that the verifier is insufficiently strict and should be tightened. Since the maps used in the affine.for op below do not have results, the IR verification should fail however it does not. Minimal example: #map = affine_map<() -> ()> This gets past the verifier, but I added a check to see that it causes an error if an affine.for has a bound map with no result. Open to any comments or clarifications :) Full diff: https://github.com/llvm/llvm-project/pull/127105.diff 2 Files Affected:
diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
index 147f5dd7a24b6..06e26e887b050 100644
--- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
@@ -1903,6 +1903,12 @@ LogicalResult AffineForOp::verifyRegions() {
getUpperBoundMap().getNumDims())))
return failure();
+ if (getLowerBoundMap().getNumResults() < 1)
+ return emitOpError("expected lower bound map to have at least one result");
+
+ if (getUpperBoundMap().getNumResults() < 1)
+ return emitOpError("expected upper bound map to have at least one result");
+
unsigned opNumResults = getNumResults();
if (opNumResults == 0)
return success();
diff --git a/mlir/test/Dialect/Affine/invalid.mlir b/mlir/test/Dialect/Affine/invalid.mlir
index 44e484b9ba598..5a3243cb074c1 100644
--- a/mlir/test/Dialect/Affine/invalid.mlir
+++ b/mlir/test/Dialect/Affine/invalid.mlir
@@ -523,3 +523,25 @@ func.func @dynamic_dimension_index() {
}) : () -> ()
return
}
+
+// -----
+
+#map = affine_map<() -> ()>
+#map1 = affine_map<() -> (1)>
+func.func @no_lower_bound() {
+ // expected-error@+1 {{'affine.for' op expected lower bound map to have at least one result}}
+ affine.for %i = max #map() to min #map1() {
+ }
+ return
+}
+
+// -----
+
+#map = affine_map<() -> ()>
+#map1 = affine_map<() -> (1)>
+func.func @no_upper_bound() {
+ // expected-error@+1 {{'affine.for' op expected upper bound map to have at least one result}}
+ affine.for %i = max #map1() to min #map() {
+ }
+ return
+}
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes approved, but you don't need to comment what the code does
Please rebase, retest, and merge. |
Looks like this has exposed another issue/bug to fix. I can take that over if you prefer. |
@bondhugula sure you can take over. So I should not worry about rebasing and retesting? |
I'll debug the issue exposed, fix it and then we'll merge this. |
The failing test case is one where an invalid IR was being generated unchecked to start with. It's now exposed with this PR.
Created this issue for it: #127808 |
Fixed by #127809 |
001b1ff
to
b07e112
Compare
@bondhugula I did was able to successfully rebase on my local without conflicts: however GitHub's showing this: Any suggestions? |
@@ -2001,8 +2001,15 @@ static LogicalResult generateCopy( | |||
} | |||
|
|||
SmallVector<AffineMap, 4> lbMaps(rank), ubMaps(rank); | |||
for (unsigned i = 0; i < rank; ++i) | |||
for (unsigned i = 0; i < rank; ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate with #127809.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change has been merged. The first commit can be dropped during rebase.
#127809 has been merged into |
You can simply do |
0790e02
to
64b6566
Compare
64b6566
to
6cead0b
Compare
Fixes issue #120001.
I learnt that we shouldn’t assert on IR that can be constructed and passes the verifier. In this case, it appears that the verifier is insufficiently strict and should be tightened. Since the maps used in the
affine.for
op do not have results, I believe the IR verification should fail however it does not.Minimal example:
#map = affine_map<() -> ()>
module {
func.func @main() {
affine.for %arg0 = max #map() to min #map() {
}
return
}
}
This gets past the verifier, but I added a check to see that it causes an error if an affine.for has a bound map with no result.
@krzysz00 @matthias-springer @kazutakahirata @MaheshRavishankar Open to any comments or clarifications :)