================
@@ -462,6 +462,58 @@ def ReturnOp : CIR_Op<"return", [ParentOneOf<["FuncOp", 
"ScopeOp", "DoWhileOp",
   let hasVerifier = 1;
 }
 
+//===----------------------------------------------------------------------===//
+// IfOp
+//===----------------------------------------------------------------------===//
+
+def IfOp : CIR_Op<"if",
+     [DeclareOpInterfaceMethods<RegionBranchOpInterface>,
+     RecursivelySpeculatable, AutomaticAllocationScope, NoRegionArguments]>{
+
+  let summary = "the if-then-else operation";
+  let description = [{
+    The `cir.if` operation represents an if-then-else construct for
+    conditionally executing two regions of code. The operand is a `cir.bool`
+    type.
+
+    Examples:
+
+    ```mlir
+    cir.if %b  {
----------------
andykaylor wrote:

I'm guessing the reason for the difference is that the condition only needs to 
be executed once for if statements. Any operations needed to evaluate the 
condition will appear in the lexical scope enclosing the if operation, similar 
to how the init section of for loops are handled.

I think it would be good to change for consistency (and maybe also revisit the 
init section of for loops).

Consider:
```
if (int x = *p)
  n += x;
```
Gives us:
```
    cir.scope {
      %3 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
      %4 = cir.load deref %0 : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
      %5 = cir.load %4 : !cir.ptr<!s32i>, !s32i
      cir.store %5, %3 : !s32i, !cir.ptr<!s32i>
      %6 = cir.load %3 : !cir.ptr<!s32i>, !s32i
      %7 = cir.cast(int_to_bool, %6 : !s32i), !cir.bool
      cir.if %7 {
        %8 = cir.load %3 : !cir.ptr<!s32i>, !s32i
        %9 = cir.load %1 : !cir.ptr<!s32i>, !s32i
        %10 = cir.binop(add, %9, %8) nsw : !s32i
        cir.store %10, %1 : !s32i, !cir.ptr<!s32i>
      }
    }
```
But
```
while (int x = *p)
  n += x;
```
Gives us:
```
    cir.scope {
      %3 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
      cir.while {
        %4 = cir.load deref %0 : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
        %5 = cir.load %4 : !cir.ptr<!s32i>, !s32i
        cir.store %5, %3 : !s32i, !cir.ptr<!s32i>
        %6 = cir.load %3 : !cir.ptr<!s32i>, !s32i
        %7 = cir.cast(int_to_bool, %6 : !s32i), !cir.bool
        cir.condition(%7)
      } do {
        %4 = cir.load %3 : !cir.ptr<!s32i>, !s32i
        %5 = cir.load %1 : !cir.ptr<!s32i>, !s32i
        %6 = cir.binop(add, %5, %4) nsw : !s32i
        cir.store %6, %1 : !s32i, !cir.ptr<!s32i>
        cir.yield
      }
    }
```
Maybe the if representation should be:

```
    cir.scope {
      %3 = cir.alloca !s32i, !cir.ptr<!s32i>, ["x", init]
      cir.if {
        %4 = cir.load deref %0 : !cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
        %5 = cir.load %4 : !cir.ptr<!s32i>, !s32i
        cir.store %5, %3 : !s32i, !cir.ptr<!s32i>
        %6 = cir.load %3 : !cir.ptr<!s32i>, !s32i
        %7 = cir.cast(int_to_bool, %6 : !s32i), !cir.bool
        cir.condition(%7)
      } then {
        %8 = cir.load %3 : !cir.ptr<!s32i>, !s32i
        %9 = cir.load %1 : !cir.ptr<!s32i>, !s32i
        %10 = cir.binop(add, %9, %8) nsw : !s32i
        cir.store %10, %1 : !s32i, !cir.ptr<!s32i>
      }
    }
```

@bcardosolopes What do you think?

https://github.com/llvm/llvm-project/pull/134333
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to