-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[mlir][emitc] mark emitc.load
with CExpression
#130802
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-emitc @llvm/pr-subscribers-mlir Author: Kirill Chibisov (kchibisov) ChangesFollow the Even though -- It was brought #91475 (comment) and while there was some opposition due to Full diff: https://github.com/llvm/llvm-project/pull/130802.diff 3 Files Affected:
diff --git a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
index a518e7425956c..af2eed81e0d5b 100644
--- a/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
+++ b/mlir/include/mlir/Dialect/EmitC/IR/EmitC.td
@@ -927,7 +927,7 @@ def EmitC_LogicalOrOp : EmitC_BinaryOp<"logical_or", [CExpression]> {
let assemblyFormat = "operands attr-dict `:` type(operands)";
}
-def EmitC_LoadOp : EmitC_Op<"load", [
+def EmitC_LoadOp : EmitC_Op<"load", [CExpression,
TypesMatchWith<"result type matches value type of 'operand'",
"operand", "result",
"::llvm::cast<LValueType>($_self).getValueType()">
diff --git a/mlir/lib/Target/Cpp/TranslateToCpp.cpp b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
index b00820ffc542b..a3761ead4adde 100644
--- a/mlir/lib/Target/Cpp/TranslateToCpp.cpp
+++ b/mlir/lib/Target/Cpp/TranslateToCpp.cpp
@@ -100,6 +100,7 @@ static FailureOr<int> getOperatorPrecedence(Operation *operation) {
})
.Case<emitc::ConditionalOp>([&](auto op) { return 2; })
.Case<emitc::DivOp>([&](auto op) { return 13; })
+ .Case<emitc::LoadOp>([&](auto op) { return 16; })
.Case<emitc::LogicalAndOp>([&](auto op) { return 4; })
.Case<emitc::LogicalNotOp>([&](auto op) { return 15; })
.Case<emitc::LogicalOrOp>([&](auto op) { return 3; })
diff --git a/mlir/test/Dialect/EmitC/transforms.mlir b/mlir/test/Dialect/EmitC/transforms.mlir
index d204dec70d449..0678b4e5515c0 100644
--- a/mlir/test/Dialect/EmitC/transforms.mlir
+++ b/mlir/test/Dialect/EmitC/transforms.mlir
@@ -129,3 +129,26 @@ func.func @single_result_requirement() -> (i32, i32) {
%0:2 = emitc.call_opaque "foo" () : () -> (i32, i32)
return %0#0, %0#1 : i32, i32
}
+
+// CHECK-LABEL: func.func @expression_with_load(
+// CHECK-SAME: %[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32) -> i1 {
+// CHECK: %[[VAL_2:.*]] = "emitc.variable"() <{value = #emitc.opaque<"42">}> : () -> !emitc.lvalue<i32>
+// CHECK: %[[VAL_3:.*]] = emitc.expression : i32 {
+// CHECK: %[[VAL_4:.*]] = load %[[VAL_2]] : <i32>
+// CHECK: yield %[[VAL_4]] : i32
+// CHECK: }
+// CHECK: %[[VAL_5:.*]] = emitc.expression : i1 {
+// CHECK: %[[VAL_6:.*]] = add %[[VAL_3]], %[[VAL_1]] : (i32, i32) -> i32
+// CHECK: %[[VAL_7:.*]] = cmp lt, %[[VAL_6]], %[[VAL_0]] : (i32, i32) -> i1
+// CHECK: yield %[[VAL_7]] : i1
+// CHECK: }
+// CHECK: return %[[VAL_5]] : i1
+// CHECK: }
+
+func.func @expression_with_load(%arg0: i32, %arg1: i32) -> i1 {
+ %0 = "emitc.variable"() <{value = #emitc.opaque<"42">}> : () -> !emitc.lvalue<i32>
+ %a = emitc.load %0 : !emitc.lvalue<i32>
+ %b = emitc.add %a, %arg1 : (i32, i32) -> i32
+ %c = emitc.cmp lt, %b, %arg0 :(i32, i32) -> i1
+ return %c : i1
+}
|
Can you please add some tests for the output of translation? Interesting test case could also be loading from an array index, and then either having the emitc.subscript also within the |
Thanks for addressing this.
On top of that a translation test with a combination of a load inside an expression and a |
20b3873
to
4d23b0d
Compare
Sure done.
Sure, done. If it's not what you've expected, let me know. |
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.
Looks good to me. Let's wait for @simon-camp to say whether the test for precedence is what he expected.
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.
LGTM, thanks.
I've just noticed one inconsistency in the handling of CExpression inlining. If you look at In general, As for the call, I'm not quite sure how to deal with it and maybe keep as is or disallow all together. Edit: This also applies to |
Follow the `call` and `call_opaque` operations, as well as `apply`, which already are marked as `CExpression` even though they have side effects. Even though `emitc.load` can be included inside the `emitc.expression`, the inlining and `--form-expression` pass won't actually inline them inside other expression due to it having a side effect, thus unless the user manually writes the `emitc.load` inside the `emitc.expression` it won't appear there. Also update the `hasSideEffects` to account for `LoadOp` instead of `VariableOp`. The `VariableOp` was used before the `LoadOp` was introduced, but at the present time, the `LoadOp` is what is being used to actually load and emit the instruction that does the loading.
@mgehre-amd @simon-camp I've updated PR to make a correct The loosening of what kind of load is considered a side effect I'll do separately. The same with e.g. |
I don't see theses changes, maybe you forgot to push your changes? |
Indeed, sorry. Will re-ping once I'll be able to push changes. |
4d23b0d
to
6b8d99d
Compare
@simon-camp should be pushed now. |
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.
Thanks.
I wonder if we should upgrade the CExpression trait to an interface, so that the ops themselves can override a method. Another option could be to use MLIR MemoryEffects instead.
I'll look into this for e.g. lowering the restrictions PR, but for this one, I think it's fine as is, since it was more of a bug fix. @mgehre-amd anything else needed from my side? |
ping |
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.
Sorry for the delay, this somehow slipped under my radar.
LGTM, thanks for handling this!
ping |
If you don't have write access, I am happy to merge this for you, it that is what you're requesting. |
Yes, I don't have write access, so I need someone to merge. |
Follow the
call
andcall_opaque
operations, as well asapply
, which already are marked asCExpression
even though they have side effects.Even though
emitc.load
can be included inside theemitc.expression
, the inlining and--form-expression
pass won't actually inline them inside other expression due to it having a side effect, thus unless the user manually writes theemitc.load
inside theemitc.expression
it won't appear there.--
It was brought #91475 (comment) and while there was some opposition due to
load
having a side effect,emitc
already allows all the rest operations that have it, so for consistency reasons, enabling it doesn't really hurt from my point of view. Especially given that--form-expression
doesn't allowit to really inline inside other expressions, which makes sense, since if the users want such behavior, they should explicitly opt-in.