[Mlir-commits] [mlir] [mlir][emitc] Add 'emitc.while' and 'emitc.do' ops to the dialect (PR #143008)

Gil Rapaport llvmlistbot at llvm.org
Sat Jul 12 08:11:59 PDT 2025


================
@@ -1572,4 +1572,156 @@ def EmitC_SwitchOp : EmitC_Op<"switch", [RecursiveMemoryEffects,
   let hasVerifier = 1;
 }
 
+def EmitC_WhileOp : EmitC_Op<"while",
+      [HasOnlyGraphRegion, RecursiveMemoryEffects, NoRegionArguments, OpAsmOpInterface, NoTerminator]> {
+  let summary = "While operation";
+ let description = [{
+    The `emitc.while` operation represents a C/C++ while loop construct that
+    repeatedly executes a body region as long as a condition region evaluates to
+    true. The operation has two regions:
+    
+    1. A condition region that must yield a boolean value (i1) 
+    2. A body region that contains the loop body
+
+    The condition region is evaluated before each iteration. If it yields true,
+    the body region is executed. The loop terminates when the condition yields
+    false. The condition region must contain exactly one block that terminates
+    with an `emitc.yield` operation producing an i1 value.
+
+    Example:
+
+    ```mlir
+    emitc.func @foo(%arg0 : !emitc.ptr<i32>) {
+      %var = "emitc.variable"() <{value = 0 : i32}> : () -> !emitc.lvalue<i32>
+      %0 = emitc.literal "10" : i32
+      %1 = emitc.literal "1" : i32
+
+      emitc.while {
+        %var_load = load %var : <i32>
+        %res = emitc.cmp le, %var_load, %0 : (i32, i32) -> i1
+        emitc.yield %res : i1
+      } do {
+        emitc.verbatim "printf(\"%d\", *{});" args %arg0 : !emitc.ptr<i32>
+        %var_load = load %var : <i32>
+        %tmp_add = add %var_load, %1 : (i32, i32) -> i32
+        "emitc.assign"(%var, %tmp_add) : (!emitc.lvalue<i32>, i32) -> ()
+      }
+
+      return
+    }
+    ```
+
+    ```c++
+    // Code emitted for the operation above.
+    void foo(int32_t* v1) {
+      int32_t v2 = 0;
+      while (v2 <= 10) {
+        printf("%d", *v1);
+        int32_t v3 = v2;
+        int32_t v4 = v3 + 1;
+        v2 = v4;
+      }
+      return;
+    }
+    ```
+  }];
+
+  let arguments = (ins);
+  let results = (outs); 
+  let regions = (region MaxSizedRegion<1>:$conditionRegion,
----------------
aniragil wrote:

>Just to make it clear, to do you want to have it that way
>```
>emitc.while {
>    emitc.expression : i1 {
>    }
>}
>```
This loop doesn't seem to have a condition region. I meant to have a condition region as the patch suggests but let it hold a single `emitc.expression` whose value is then yielded, i.e.:
```
emitc.while {
    // Condition region
    %e = emitc.expression : i1 {
       %r = ... : i1
       yield %r : i1
    }
    yield %e : i1
} do {
   // Body region
}
```
Then  `CppEmitter::emitWhile()` can call `CppEmitter::emitExpression()` on the expression instead of replicating its code.
Using the dialect's operation that models expressions would capture the exact semantics in the IR, let `form-expressions` merge feeding expressions into the condition expression and simplify verification and translation code. 

https://github.com/llvm/llvm-project/pull/143008


More information about the Mlir-commits mailing list