diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index a898c66b6cd0..bda39e120307 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -442,7 +442,7 @@ def StoreOp : CIR_Op<"store", [ def ReturnOp : CIR_Op<"return", [ParentOneOf<["FuncOp", "ScopeOp", "IfOp", "SwitchOp", "DoWhileOp", - "WhileOp", "LoopOp"]>, + "WhileOp", "ForOp"]>, Terminator]> { let summary = "Return from function"; let description = [{ @@ -635,7 +635,7 @@ def ConditionOp : CIR_Op<"condition", [ //===----------------------------------------------------------------------===// def YieldOp : CIR_Op<"yield", [ReturnLike, Terminator, - ParentOneOf<["IfOp", "ScopeOp", "SwitchOp", "WhileOp", "LoopOp", "AwaitOp", + ParentOneOf<["IfOp", "ScopeOp", "SwitchOp", "WhileOp", "ForOp", "AwaitOp", "TernaryOp", "GlobalOp", "DoWhileOp"]>]> { let summary = "Represents the default branching behaviour of a region"; let description = [{ @@ -1159,106 +1159,6 @@ def BrCondOp : CIR_Op<"brcond", }]; } -//===----------------------------------------------------------------------===// -// LoopOp -//===----------------------------------------------------------------------===// - -def LoopOpKind_For : I32EnumAttrCase<"For", 1, "for">; - -def LoopOpKind : I32EnumAttr< - "LoopOpKind", - "Loop kind", - [LoopOpKind_For]> { - let cppNamespace = "::mlir::cir"; -} - -def LoopOp : CIR_Op<"loop", - [LoopOpInterface, - DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods, - RecursivelySpeculatable, NoRegionArguments]> { - let summary = "Loop"; - let description = [{ - `cir.loop` represents C/C++ loop forms. It defines 3 blocks: - - `cond`: region can contain multiple blocks, terminated by regular - `cir.yield` when control should yield back to the parent, and - `cir.continue` when execution continues to the next region. - The region destination depends on the loop form specified. - - `step`: region with one block, containing code to compute the - loop step, must be terminated with `cir.yield`. - - `body`: region for the loop's body, can contain an arbitrary - number of blocks. - - The loop form: `for`, `while` and `dowhile` must also be specified and - each implies the loop regions execution order. - - ```mlir - // while (true) { - // i = i + 1; - // } - cir.loop while(cond : { - cir.continue - }, step : { - cir.yield - }) { - %3 = cir.load %1 : cir.ptr , i32 - %4 = cir.const(1 : i32) : i32 - %5 = cir.binop(add, %3, %4) : i32 - cir.store %5, %1 : i32, cir.ptr - cir.yield - } - ``` - }]; - - let arguments = (ins Arg:$kind); - let regions = (region AnyRegion:$cond, AnyRegion:$body, - SizedRegion<1>:$step); - - let assemblyFormat = [{ - $kind - `(` - `cond` `:` $cond `,` - `step` `:` $step - `)` - $body - attr-dict - }]; - - let skipDefaultBuilders = 1; - let builders = [ - OpBuilder<(ins - "cir::LoopOpKind":$kind, - CArg<"function_ref", - "nullptr">:$condBuilder, - CArg<"function_ref", - "nullptr">:$bodyBuilder, - CArg<"function_ref", - "nullptr">:$stepBuilder - )> - ]; - - let hasVerifier = 1; - - let extraClassDeclaration = [{ - Region *maybeGetStep() { - if (getKind() == LoopOpKind::For) - return &getStep(); - return nullptr; - } - - llvm::SmallVector getRegionsInExecutionOrder() { - switch(getKind()) { - case LoopOpKind::For: - return llvm::SmallVector{&getCond(), &getBody(), &getStep()}; - case LoopOpKind::While: - return llvm::SmallVector{&getCond(), &getBody()}; - case LoopOpKind::DoWhile: - return llvm::SmallVector{&getBody(), &getCond()}; - } - } - }]; -} - //===----------------------------------------------------------------------===// // While & DoWhileOp //===----------------------------------------------------------------------===// @@ -1337,6 +1237,73 @@ def DoWhileOp : WhileOpBase<"do"> { }]; } +//===----------------------------------------------------------------------===// +// ForOp +//===----------------------------------------------------------------------===// + +def ForOp : CIR_Op<"for", [LoopOpInterface, NoRegionArguments]> { + let summary = "C/C++ for loop counterpart"; + let description = [{ + Represents a C/C++ for loop. It consists of three regions: + + - `cond`: single block region with the loop's condition. Should be + terminated with a `cir.condition` operation. + - `body`: contains the loop body and an arbitrary number of blocks. + - `step`: single block region with the loop's step. + + Example: + + ```mlir + cir.for cond { + cir.condition(%val) + } body { + cir.break + ^bb2: + cir.yield + } step { + cir.yield + } + ``` + }]; + + let regions = (region SizedRegion<1>:$cond, + MinSizedRegion<1>:$body, + SizedRegion<1>:$step); + let assemblyFormat = [{ + `:` `cond` $cond + `body` $body + `step` $step + attr-dict + }]; + + let builders = [ + OpBuilder<(ins "function_ref":$condBuilder, + "function_ref":$bodyBuilder, + "function_ref":$stepBuilder), [{ + OpBuilder::InsertionGuard guard($_builder); + + // Build condition region. + $_builder.createBlock($_state.addRegion()); + condBuilder($_builder, $_state.location); + + // Build body region. + $_builder.createBlock($_state.addRegion()); + bodyBuilder($_builder, $_state.location); + + // Build step region. + $_builder.createBlock($_state.addRegion()); + stepBuilder($_builder, $_state.location); + }]> + ]; + + let extraClassDeclaration = [{ + Region *maybeGetStep() { return &getStep(); } + llvm::SmallVector getRegionsInExecutionOrder() { + return llvm::SmallVector{&getCond(), &getBody(), &getStep()}; + } + }]; +} + //===----------------------------------------------------------------------===// // GlobalOp //===----------------------------------------------------------------------===// @@ -2684,7 +2651,7 @@ def AllocException : CIR_Op<"alloc_exception", [ def ThrowOp : CIR_Op<"throw", [ ParentOneOf<["FuncOp", "ScopeOp", "IfOp", "SwitchOp", - "DoWhileOp", "WhileOp", "LoopOp"]>, + "DoWhileOp", "WhileOp", "ForOp"]>, Terminator]> { let summary = "(Re)Throws an exception"; let description = [{ diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index cd0c881df0a8..e3f15227fb21 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -615,6 +615,15 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy { return create(loc, condBuilder, bodyBuilder); } + /// Create a for operation. + mlir::cir::ForOp createFor( + mlir::Location loc, + llvm::function_ref condBuilder, + llvm::function_ref bodyBuilder, + llvm::function_ref stepBuilder) { + return create(loc, condBuilder, bodyBuilder, stepBuilder); + } + mlir::cir::MemCpyOp createMemCpy(mlir::Location loc, mlir::Value dst, mlir::Value src, mlir::Value len) { return create(loc, dst, src, len); diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp index ec9b67d3aacb..6138fbc10ccd 100644 --- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp @@ -673,7 +673,7 @@ CIRGenFunction::buildDefaultStmt(const DefaultStmt &S, mlir::Type condType, mlir::LogicalResult CIRGenFunction::buildCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef ForAttrs) { - mlir::cir::LoopOp loopOp; + mlir::cir::ForOp forOp; // TODO(cir): pass in array of attributes. auto forStmtBuilder = [&]() -> mlir::LogicalResult { @@ -696,8 +696,8 @@ CIRGenFunction::buildCXXForRangeStmt(const CXXForRangeStmt &S, // sure we handle all cases. assert(!UnimplementedFeature::requiresCleanups()); - loopOp = builder.create( - getLoc(S.getSourceRange()), mlir::cir::LoopOpKind::For, + forOp = builder.createFor( + getLoc(S.getSourceRange()), /*condBuilder=*/ [&](mlir::OpBuilder &b, mlir::Location loc) { assert(!UnimplementedFeature::createProfileWeightsForLoop()); @@ -742,12 +742,12 @@ CIRGenFunction::buildCXXForRangeStmt(const CXXForRangeStmt &S, if (res.failed()) return res; - terminateBody(builder, loopOp.getBody(), getLoc(S.getEndLoc())); + terminateBody(builder, forOp.getBody(), getLoc(S.getEndLoc())); return mlir::success(); } mlir::LogicalResult CIRGenFunction::buildForStmt(const ForStmt &S) { - mlir::cir::LoopOp loopOp; + mlir::cir::ForOp forOp; // TODO: pass in array of attributes. auto forStmtBuilder = [&]() -> mlir::LogicalResult { @@ -763,8 +763,8 @@ mlir::LogicalResult CIRGenFunction::buildForStmt(const ForStmt &S) { // sure we handle all cases. assert(!UnimplementedFeature::requiresCleanups()); - loopOp = builder.create( - getLoc(S.getSourceRange()), mlir::cir::LoopOpKind::For, + forOp = builder.createFor( + getLoc(S.getSourceRange()), /*condBuilder=*/ [&](mlir::OpBuilder &b, mlir::Location loc) { assert(!UnimplementedFeature::createProfileWeightsForLoop()); @@ -821,7 +821,7 @@ mlir::LogicalResult CIRGenFunction::buildForStmt(const ForStmt &S) { if (res.failed()) return res; - terminateBody(builder, loopOp.getBody(), getLoc(S.getEndLoc())); + terminateBody(builder, forOp.getBody(), getLoc(S.getEndLoc())); return mlir::success(); } diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index b5a8bfd2f698..24e8300e674f 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1238,42 +1238,6 @@ void CatchOp::build( catchBuilder(builder, result.location, result); } -//===----------------------------------------------------------------------===// -// LoopOp -//===----------------------------------------------------------------------===// - -void LoopOp::build(OpBuilder &builder, OperationState &result, - cir::LoopOpKind kind, - function_ref condBuilder, - function_ref bodyBuilder, - function_ref stepBuilder) { - OpBuilder::InsertionGuard guard(builder); - ::mlir::cir::LoopOpKindAttr kindAttr = - cir::LoopOpKindAttr::get(builder.getContext(), kind); - result.addAttribute(getKindAttrName(result.name), kindAttr); - - Region *condRegion = result.addRegion(); - builder.createBlock(condRegion); - condBuilder(builder, result.location); - - Region *bodyRegion = result.addRegion(); - builder.createBlock(bodyRegion); - bodyBuilder(builder, result.location); - - Region *stepRegion = result.addRegion(); - builder.createBlock(stepRegion); - stepBuilder(builder, result.location); -} - -void LoopOp::getSuccessorRegions(mlir::RegionBranchPoint point, - SmallVectorImpl ®ions) { - LoopOpInterface::getLoopOpSuccessorRegions(*this, point, regions); -} - -llvm::SmallVector LoopOp::getLoopRegions() { return {&getBody()}; } - -LogicalResult LoopOp::verify() { return success(); } - //===----------------------------------------------------------------------===// // LoopOpInterface Methods //===----------------------------------------------------------------------===// @@ -1296,6 +1260,14 @@ void WhileOp::getSuccessorRegions( ::llvm::SmallVector WhileOp::getLoopRegions() { return {&getBody()}; } +void ForOp::getSuccessorRegions( + ::mlir::RegionBranchPoint point, + ::llvm::SmallVectorImpl<::mlir::RegionSuccessor> ®ions) { + LoopOpInterface::getLoopOpSuccessorRegions(*this, point, regions); +} + +::llvm::SmallVector ForOp::getLoopRegions() { return {&getBody()}; } + //===----------------------------------------------------------------------===// // GlobalOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp b/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp index ae5947a56944..f3e2d1e61274 100644 --- a/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp +++ b/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp @@ -38,6 +38,8 @@ void LoopOpInterface::getLoopOpSuccessorRegions( // Branching from step: go to condition. else if (op.maybeGetStep() == point.getRegionOrNull()) { regions.emplace_back(&op.getCond(), op.getCond().getArguments()); + } else { + llvm_unreachable("unexpected branch origin"); } } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index f7707ab28d53..71fc899b4b66 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -2264,7 +2264,6 @@ void ConvertCIRToLLVMPass::runOnOperation() { // ,ConstantOp // ,FuncOp // ,LoadOp - // ,LoopOp // ,ReturnOp // ,StoreOp // ,YieldOp diff --git a/clang/test/CIR/CodeGen/loop-scope.cpp b/clang/test/CIR/CodeGen/loop-scope.cpp index bd82f1d016eb..1f288c7d3229 100644 --- a/clang/test/CIR/CodeGen/loop-scope.cpp +++ b/clang/test/CIR/CodeGen/loop-scope.cpp @@ -15,15 +15,15 @@ void l0(void) { // CPPSCOPE-NEXT: %1 = cir.alloca !s32i, cir.ptr , ["j", init] {alignment = 4 : i64} // CPPSCOPE-NEXT: %2 = cir.const(#cir.int<0> : !s32i) : !s32i // CPPSCOPE-NEXT: cir.store %2, %0 : !s32i, cir.ptr -// CPPSCOPE-NEXT: cir.loop for(cond : { +// CPPSCOPE-NEXT: cir.for : cond { // CSCOPE: cir.func @l0() // CSCOPE-NEXT: cir.scope { // CSCOPE-NEXT: %0 = cir.alloca !s32i, cir.ptr , ["i", init] {alignment = 4 : i64} // CSCOPE-NEXT: %1 = cir.const(#cir.int<0> : !s32i) : !s32i // CSCOPE-NEXT: cir.store %1, %0 : !s32i, cir.ptr -// CSCOPE-NEXT: cir.loop for(cond : { +// CSCOPE-NEXT: cir.for : cond { -// CSCOPE: }) { +// CSCOPE: } body { // CSCOPE-NEXT: cir.scope { // CSCOPE-NEXT: %2 = cir.alloca !s32i, cir.ptr , ["j", init] {alignment = 4 : i64} diff --git a/clang/test/CIR/CodeGen/loop.cpp b/clang/test/CIR/CodeGen/loop.cpp index 2dd2dfa2445c..2a3ebb390082 100644 --- a/clang/test/CIR/CodeGen/loop.cpp +++ b/clang/test/CIR/CodeGen/loop.cpp @@ -7,7 +7,7 @@ void l0() { } // CHECK: cir.func @_Z2l0v -// CHECK: cir.loop for(cond : { +// CHECK: cir.for : cond { // CHECK: %[[#TRUE:]] = cir.const(#true) : !cir.bool // CHECK: cir.condition(%[[#TRUE]]) @@ -19,22 +19,22 @@ void l1() { } // CHECK: cir.func @_Z2l1v -// CHECK: cir.loop for(cond : { +// CHECK: cir.for : cond { // CHECK-NEXT: %4 = cir.load %2 : cir.ptr , !s32i // CHECK-NEXT: %5 = cir.const(#cir.int<10> : !s32i) : !s32i // CHECK-NEXT: %6 = cir.cmp(lt, %4, %5) : !s32i, !cir.bool // CHECK-NEXT: cir.condition(%6) -// CHECK-NEXT: }, step : { -// CHECK-NEXT: %4 = cir.load %2 : cir.ptr , !s32i +// CHECK-NEXT: } body { +// CHECK-NEXT: %4 = cir.load %0 : cir.ptr , !s32i // CHECK-NEXT: %5 = cir.const(#cir.int<1> : !s32i) : !s32i // CHECK-NEXT: %6 = cir.binop(add, %4, %5) : !s32i -// CHECK-NEXT: cir.store %6, %2 : !s32i, cir.ptr +// CHECK-NEXT: cir.store %6, %0 : !s32i, cir.ptr // CHECK-NEXT: cir.yield -// CHECK-NEXT: }) { -// CHECK-NEXT: %4 = cir.load %0 : cir.ptr , !s32i +// CHECK-NEXT: } step { +// CHECK-NEXT: %4 = cir.load %2 : cir.ptr , !s32i // CHECK-NEXT: %5 = cir.const(#cir.int<1> : !s32i) : !s32i // CHECK-NEXT: %6 = cir.binop(add, %4, %5) : !s32i -// CHECK-NEXT: cir.store %6, %0 : !s32i, cir.ptr +// CHECK-NEXT: cir.store %6, %2 : !s32i, cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } diff --git a/clang/test/CIR/CodeGen/rangefor.cpp b/clang/test/CIR/CodeGen/rangefor.cpp index 890136df7a88..722c21ea53f7 100644 --- a/clang/test/CIR/CodeGen/rangefor.cpp +++ b/clang/test/CIR/CodeGen/rangefor.cpp @@ -44,13 +44,10 @@ void init(unsigned numImages) { // CHECK: %10 = cir.load %4 : cir.ptr >, !cir.ptr // CHECK: %11 = cir.call @_ZNSt6vectorI6tripleE3endEv(%10) : (!cir.ptr) -> ![[VEC_IT]] // CHECK: cir.store %11, %6 : ![[VEC_IT]], cir.ptr -// CHECK: cir.loop for(cond : { +// CHECK: cir.for : cond { // CHECK: %12 = cir.call @_ZNK17__vector_iteratorI6triplePS0_RS0_EneERKS3_(%5, %6) : (!cir.ptr, !cir.ptr) -> !cir.bool // CHECK: cir.condition(%12) -// CHECK: }, step : { -// CHECK: %12 = cir.call @_ZN17__vector_iteratorI6triplePS0_RS0_EppEv(%5) : (!cir.ptr) -> !cir.ptr -// CHECK: cir.yield -// CHECK: }) { +// CHECK: } body { // CHECK: %12 = cir.call @_ZNK17__vector_iteratorI6triplePS0_RS0_EdeEv(%5) : (!cir.ptr) -> !cir.ptr // CHECK: cir.store %12, %7 : !cir.ptr, cir.ptr > // CHECK: cir.scope { @@ -66,6 +63,9 @@ void init(unsigned numImages) { // CHECK: %20 = cir.call @_ZN6tripleaSEOS_(%19, %13) : (!cir.ptr, !cir.ptr) -> !cir.ptr // CHECK: } // CHECK: cir.yield +// CHECK: } step { +// CHECK: %12 = cir.call @_ZN17__vector_iteratorI6triplePS0_RS0_EppEv(%5) : (!cir.ptr) -> !cir.ptr +// CHECK: cir.yield // CHECK: } // CHECK: } // CHECK: cir.return diff --git a/clang/test/CIR/IR/for.cir b/clang/test/CIR/IR/for.cir new file mode 100644 index 000000000000..62b82976cc68 --- /dev/null +++ b/clang/test/CIR/IR/for.cir @@ -0,0 +1,22 @@ +// RUN: cir-opt %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s + +cir.func @testPrintingParsing(%arg0 : !cir.bool) { + cir.for : cond { + cir.condition(%arg0) + } body { + cir.yield + } step { + cir.yield + } + cir.return +} + +// CHECK: @testPrintingParsing +// CHECK: cir.for : cond { +// CHECK: cir.condition(%arg0) +// CHECK: } body { +// CHECK: cir.yield +// CHECK: } step { +// CHECK: cir.yield +// CHECK: } diff --git a/clang/test/CIR/IR/invalid.cir b/clang/test/CIR/IR/invalid.cir index 5d02ee27ff53..09d4f36dd03a 100644 --- a/clang/test/CIR/IR/invalid.cir +++ b/clang/test/CIR/IR/invalid.cir @@ -817,3 +817,16 @@ cir.func @invalid_cond_region_terminator(%arg0 : !cir.bool) -> !cir.void { } cir.return } + +// ----- + +cir.func @invalidConditionTerminator (%arg0 : !cir.bool) -> !cir.void { + cir.for : cond { // expected-error {{op expected condition region to terminate with 'cir.condition'}} + cir.yield + } body { + cir.yield + } step { + cir.yield + } + cir.return +} diff --git a/clang/test/CIR/IR/loop.cir b/clang/test/CIR/IR/loop.cir deleted file mode 100644 index b163da45d34c..000000000000 --- a/clang/test/CIR/IR/loop.cir +++ /dev/null @@ -1,63 +0,0 @@ -// RUN: cir-opt %s | FileCheck %s -#false = #cir.bool : !cir.bool -#true = #cir.bool : !cir.bool -!u32i = !cir.int - -cir.func @l0() { - %0 = cir.alloca !u32i, cir.ptr , ["x", init] {alignment = 4 : i64} - %1 = cir.const(#cir.int<0> : !u32i) : !u32i - cir.store %1, %0 : !u32i, cir.ptr - cir.scope { - %2 = cir.alloca !u32i, cir.ptr , ["i", init] {alignment = 4 : i64} - %3 = cir.const(#cir.int<0> : !u32i) : !u32i - cir.store %3, %2 : !u32i, cir.ptr - cir.loop for(cond : { - %4 = cir.load %2 : cir.ptr , !u32i - %5 = cir.const(#cir.int<10> : !u32i) : !u32i - %6 = cir.cmp(lt, %4, %5) : !u32i, !cir.bool - cir.condition(%6) - }, step : { - %4 = cir.load %2 : cir.ptr , !u32i - %5 = cir.const(#cir.int<1> : !u32i) : !u32i - %6 = cir.binop(add, %4, %5) : !u32i - cir.store %6, %2 : !u32i, cir.ptr - cir.yield - }) { - %4 = cir.load %0 : cir.ptr , !u32i - %5 = cir.const(#cir.int<1> : !u32i) : !u32i - %6 = cir.binop(add, %4, %5) : !u32i - cir.store %6, %0 : !u32i, cir.ptr - %7 = cir.const(#true) : !cir.bool - cir.if %7 { - cir.break - } - cir.yield - } - } - - cir.return -} - -// CHECK: cir.func @l0 -// CHECK: cir.loop for(cond : { -// CHECK-NEXT: %4 = cir.load %2 : cir.ptr , !u32i -// CHECK-NEXT: %5 = cir.const(#cir.int<10> : !u32i) : !u32i -// CHECK-NEXT: %6 = cir.cmp(lt, %4, %5) : !u32i, !cir.bool -// CHECK-NEXT: cir.condition(%6) -// CHECK-NEXT: }, step : { -// CHECK-NEXT: %4 = cir.load %2 : cir.ptr , !u32i -// CHECK-NEXT: %5 = cir.const(#cir.int<1> : !u32i) : !u32i -// CHECK-NEXT: %6 = cir.binop(add, %4, %5) : !u32i -// CHECK-NEXT: cir.store %6, %2 : !u32i, cir.ptr -// CHECK-NEXT: cir.yield -// CHECK-NEXT: }) { -// CHECK-NEXT: %4 = cir.load %0 : cir.ptr , !u32i -// CHECK-NEXT: %5 = cir.const(#cir.int<1> : !u32i) : !u32i -// CHECK-NEXT: %6 = cir.binop(add, %4, %5) : !u32i -// CHECK-NEXT: cir.store %6, %0 : !u32i, cir.ptr -// CHECK-NEXT: %7 = cir.const(#true) : !cir.bool -// CHECK-NEXT: cir.if %7 { -// CHECK-NEXT: cir.break -// CHECK-NEXT: } -// CHECK-NEXT: cir.yield -// CHECK-NEXT: } diff --git a/clang/test/CIR/Lowering/dot.cir b/clang/test/CIR/Lowering/dot.cir index 4f588e1f05f9..401399f054a8 100644 --- a/clang/test/CIR/Lowering/dot.cir +++ b/clang/test/CIR/Lowering/dot.cir @@ -18,18 +18,13 @@ module { %8 = cir.alloca !s32i, cir.ptr , ["i", init] {alignment = 4 : i64} %9 = cir.const(#cir.int<0> : !s32i) : !s32i cir.store %9, %8 : !s32i, cir.ptr - cir.loop for(cond : { + cir.for : cond { %10 = cir.load %8 : cir.ptr , !s32i %11 = cir.load %2 : cir.ptr , !s32i %12 = cir.cmp(lt, %10, %11) : !s32i, !s32i %13 = cir.cast(int_to_bool, %12 : !s32i), !cir.bool cir.condition(%13) - }, step : { - %10 = cir.load %8 : cir.ptr , !s32i - %11 = cir.unary(inc, %10) : !s32i, !s32i - cir.store %11, %8 : !s32i, cir.ptr - cir.yield - }) { + } body { %10 = cir.load %0 : cir.ptr >, !cir.ptr %11 = cir.load %8 : cir.ptr , !s32i %12 = cir.ptr_stride(%10 : !cir.ptr, %11 : !s32i), !cir.ptr @@ -43,6 +38,11 @@ module { %20 = cir.binop(add, %19, %18) : f64 cir.store %20, %4 : f64, cir.ptr cir.yield + } step { + %10 = cir.load %8 : cir.ptr , !s32i + %11 = cir.unary(inc, %10) : !s32i, !s32i + cir.store %11, %8 : !s32i, cir.ptr + cir.yield } } %6 = cir.load %4 : cir.ptr , f64 diff --git a/clang/test/CIR/Lowering/loop.cir b/clang/test/CIR/Lowering/loop.cir index 86097c379169..d15479a76a0d 100644 --- a/clang/test/CIR/Lowering/loop.cir +++ b/clang/test/CIR/Lowering/loop.cir @@ -7,11 +7,11 @@ module { cir.func @testFor(%arg0 : !cir.bool) { - cir.loop for(cond : { + cir.for : cond { cir.condition(%arg0) - }, step : { + } body { cir.yield - }) { + } step { cir.yield } cir.return @@ -97,15 +97,15 @@ module { // break; // } cir.func @forWithBreakTerminatedScopeInBody(%arg0 : !cir.bool) { - cir.loop for(cond : { + cir.for : cond { cir.condition(%arg0) - }, step : { - cir.yield - }) { + } body { cir.scope { // FIXME(cir): Redundant scope emitted during C codegen. cir.break } cir.yield + } step { + cir.yield } cir.return } diff --git a/clang/test/CIR/Lowering/loops-with-break.cir b/clang/test/CIR/Lowering/loops-with-break.cir index 31a2bb99e0a9..ee5238c5748a 100644 --- a/clang/test/CIR/Lowering/loops-with-break.cir +++ b/clang/test/CIR/Lowering/loops-with-break.cir @@ -8,18 +8,13 @@ module { %0 = cir.alloca !s32i, cir.ptr , ["i", init] {alignment = 4 : i64} %1 = cir.const(#cir.int<1> : !s32i) : !s32i cir.store %1, %0 : !s32i, cir.ptr - cir.loop for(cond : { + cir.for : cond { %2 = cir.load %0 : cir.ptr , !s32i %3 = cir.const(#cir.int<10> : !s32i) : !s32i %4 = cir.cmp(lt, %2, %3) : !s32i, !s32i %5 = cir.cast(int_to_bool, %4 : !s32i), !cir.bool cir.condition(%5) - }, step : { - %2 = cir.load %0 : cir.ptr , !s32i - %3 = cir.unary(inc, %2) : !s32i, !s32i - cir.store %3, %0 : !s32i, cir.ptr - cir.yield - }) { + } body { cir.scope { cir.scope { %2 = cir.load %0 : cir.ptr , !s32i @@ -32,6 +27,11 @@ module { } } cir.yield + } step { + %2 = cir.load %0 : cir.ptr , !s32i + %3 = cir.unary(inc, %2) : !s32i, !s32i + cir.store %3, %0 : !s32i, cir.ptr + cir.yield } } cir.return @@ -70,35 +70,25 @@ module { %0 = cir.alloca !s32i, cir.ptr , ["i", init] {alignment = 4 : i64} %1 = cir.const(#cir.int<1> : !s32i) : !s32i cir.store %1, %0 : !s32i, cir.ptr - cir.loop for(cond : { + cir.for : cond { %2 = cir.load %0 : cir.ptr , !s32i %3 = cir.const(#cir.int<10> : !s32i) : !s32i %4 = cir.cmp(lt, %2, %3) : !s32i, !s32i %5 = cir.cast(int_to_bool, %4 : !s32i), !cir.bool cir.condition(%5) - }, step : { - %2 = cir.load %0 : cir.ptr , !s32i - %3 = cir.unary(inc, %2) : !s32i, !s32i - cir.store %3, %0 : !s32i, cir.ptr - cir.yield - }) { + } body { cir.scope { cir.scope { %2 = cir.alloca !s32i, cir.ptr , ["j", init] {alignment = 4 : i64} %3 = cir.const(#cir.int<1> : !s32i) : !s32i cir.store %3, %2 : !s32i, cir.ptr - cir.loop for(cond : { + cir.for : cond { %4 = cir.load %2 : cir.ptr , !s32i %5 = cir.const(#cir.int<10> : !s32i) : !s32i %6 = cir.cmp(lt, %4, %5) : !s32i, !s32i %7 = cir.cast(int_to_bool, %6 : !s32i), !cir.bool cir.condition(%7) - }, step : { - %4 = cir.load %2 : cir.ptr , !s32i - %5 = cir.unary(inc, %4) : !s32i, !s32i - cir.store %5, %2 : !s32i, cir.ptr - cir.yield - }) { + } body { cir.scope { cir.scope { %4 = cir.load %2 : cir.ptr , !s32i @@ -111,10 +101,20 @@ module { } } cir.yield + } step { + %4 = cir.load %2 : cir.ptr , !s32i + %5 = cir.unary(inc, %4) : !s32i, !s32i + cir.store %5, %2 : !s32i, cir.ptr + cir.yield } } } cir.yield + } step { + %2 = cir.load %0 : cir.ptr , !s32i + %3 = cir.unary(inc, %2) : !s32i, !s32i + cir.store %3, %0 : !s32i, cir.ptr + cir.yield } } cir.return diff --git a/clang/test/CIR/Lowering/loops-with-continue.cir b/clang/test/CIR/Lowering/loops-with-continue.cir index 3e5134b8abec..9cfd3635d740 100644 --- a/clang/test/CIR/Lowering/loops-with-continue.cir +++ b/clang/test/CIR/Lowering/loops-with-continue.cir @@ -8,18 +8,13 @@ module { %0 = cir.alloca !s32i, cir.ptr , ["i", init] {alignment = 4 : i64} %1 = cir.const(#cir.int<1> : !s32i) : !s32i cir.store %1, %0 : !s32i, cir.ptr - cir.loop for(cond : { + cir.for : cond { %2 = cir.load %0 : cir.ptr , !s32i %3 = cir.const(#cir.int<10> : !s32i) : !s32i %4 = cir.cmp(lt, %2, %3) : !s32i, !s32i %5 = cir.cast(int_to_bool, %4 : !s32i), !cir.bool cir.condition(%5) - }, step : { - %2 = cir.load %0 : cir.ptr , !s32i - %3 = cir.unary(inc, %2) : !s32i, !s32i - cir.store %3, %0 : !s32i, cir.ptr - cir.yield - }) { + } body { cir.scope { cir.scope { %2 = cir.load %0 : cir.ptr , !s32i @@ -32,6 +27,11 @@ module { } } cir.yield + } step { + %2 = cir.load %0 : cir.ptr , !s32i + %3 = cir.unary(inc, %2) : !s32i, !s32i + cir.store %3, %0 : !s32i, cir.ptr + cir.yield } } cir.return @@ -71,35 +71,25 @@ module { %0 = cir.alloca !s32i, cir.ptr , ["i", init] {alignment = 4 : i64} %1 = cir.const(#cir.int<1> : !s32i) : !s32i cir.store %1, %0 : !s32i, cir.ptr - cir.loop for(cond : { + cir.for : cond { %2 = cir.load %0 : cir.ptr , !s32i %3 = cir.const(#cir.int<10> : !s32i) : !s32i %4 = cir.cmp(lt, %2, %3) : !s32i, !s32i %5 = cir.cast(int_to_bool, %4 : !s32i), !cir.bool cir.condition(%5) - }, step : { - %2 = cir.load %0 : cir.ptr , !s32i - %3 = cir.unary(inc, %2) : !s32i, !s32i - cir.store %3, %0 : !s32i, cir.ptr - cir.yield - }) { + } body { cir.scope { cir.scope { %2 = cir.alloca !s32i, cir.ptr , ["j", init] {alignment = 4 : i64} %3 = cir.const(#cir.int<1> : !s32i) : !s32i cir.store %3, %2 : !s32i, cir.ptr - cir.loop for(cond : { + cir.for : cond { %4 = cir.load %2 : cir.ptr , !s32i %5 = cir.const(#cir.int<10> : !s32i) : !s32i %6 = cir.cmp(lt, %4, %5) : !s32i, !s32i %7 = cir.cast(int_to_bool, %6 : !s32i), !cir.bool cir.condition(%7) - }, step : { - %4 = cir.load %2 : cir.ptr , !s32i - %5 = cir.unary(inc, %4) : !s32i, !s32i - cir.store %5, %2 : !s32i, cir.ptr - cir.yield - }) { + } body { cir.scope { cir.scope { %4 = cir.load %2 : cir.ptr , !s32i @@ -112,10 +102,20 @@ module { } } cir.yield + } step { + %4 = cir.load %2 : cir.ptr , !s32i + %5 = cir.unary(inc, %4) : !s32i, !s32i + cir.store %5, %2 : !s32i, cir.ptr + cir.yield } } } cir.yield + } step { + %2 = cir.load %0 : cir.ptr , !s32i + %3 = cir.unary(inc, %2) : !s32i, !s32i + cir.store %3, %0 : !s32i, cir.ptr + cir.yield } } cir.return