================ @@ -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