Skip to content

Commit 56db65a

Browse files
committed
[CIR][Lowering] Lower structured do-while loops
Conditionally set the loop entry point depending on whether the loop is of the `do-while` kind or not. ghstack-source-id: 2603086 Pull Request resolved: #146
1 parent 0c65262 commit 56db65a

File tree

2 files changed

+66
-5
lines changed

2 files changed

+66
-5
lines changed

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ class CIRLoopOpLowering : public mlir::OpConversionPattern<mlir::cir::LoopOp> {
135135

136136
mlir::LogicalResult
137137
rewriteWhileLoop(mlir::cir::LoopOp loopOp, OpAdaptor adaptor,
138-
mlir::ConversionPatternRewriter &rewriter) const {
138+
mlir::ConversionPatternRewriter &rewriter,
139+
mlir::cir::LoopOpKind kind) const {
139140
auto *currentBlock = rewriter.getInsertionBlock();
140141
auto *continueBlock =
141142
rewriter.splitBlock(currentBlock, rewriter.getInsertionPoint());
@@ -158,9 +159,10 @@ class CIRLoopOpLowering : public mlir::OpConversionPattern<mlir::cir::LoopOp> {
158159
rewriter.inlineRegionBefore(condRegion, continueBlock);
159160
rewriter.inlineRegionBefore(bodyRegion, continueBlock);
160161

161-
// Set loop entry point to condition block.
162+
// Set loop entry point to condition or to body in do-while cases.
162163
rewriter.setInsertionPointToEnd(currentBlock);
163-
rewriter.create<mlir::cir::BrOp>(loopOp.getLoc(), &condFrontBlock);
164+
auto &entry = (kind != LoopKind::DoWhile ? condFrontBlock : bodyFrontBlock);
165+
rewriter.create<mlir::cir::BrOp>(loopOp.getLoc(), &entry);
164166

165167
// Set loop exit point to continue block.
166168
rewriter.setInsertionPoint(yieldToCont);
@@ -186,9 +188,8 @@ class CIRLoopOpLowering : public mlir::OpConversionPattern<mlir::cir::LoopOp> {
186188
case LoopKind::For:
187189
break;
188190
case LoopKind::While:
189-
return rewriteWhileLoop(loopOp, adaptor, rewriter);
190191
case LoopKind::DoWhile:
191-
llvm_unreachable("NYI");
192+
return rewriteWhileLoop(loopOp, adaptor, rewriter, loopOp.getKind());
192193
}
193194

194195
auto loc = loopOp.getLoc();

clang/test/CIR/Lowering/loop.cir

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,64 @@ module {
154154
// MLIR-NEXT: ^bb6: // pred: ^bb4
155155
// MLIR-NEXT: llvm.br ^bb7
156156

157+
// Test do-while cir.loop operation lowering.
158+
cir.func @testDoWhile(%arg0: !s32i) {
159+
%0 = cir.alloca !s32i, cir.ptr <!s32i>, ["i", init] {alignment = 4 : i64}
160+
cir.store %arg0, %0 : !s32i, cir.ptr <!s32i>
161+
cir.scope {
162+
cir.loop dowhile(cond : {
163+
%1 = cir.load %0 : cir.ptr <!s32i>, !s32i
164+
%2 = cir.const(#cir.int<10> : !s32i) : !s32i
165+
%3 = cir.cmp(lt, %1, %2) : !s32i, !s32i
166+
%4 = cir.cast(int_to_bool, %3 : !s32i), !cir.bool
167+
cir.brcond %4 ^bb1, ^bb2
168+
^bb1: // pred: ^bb0
169+
cir.yield continue
170+
^bb2: // pred: ^bb0
171+
cir.yield
172+
}, step : {
173+
cir.yield
174+
}) {
175+
%1 = cir.load %0 : cir.ptr <!s32i>, !s32i
176+
%2 = cir.unary(inc, %1) : !s32i, !s32i
177+
cir.store %2, %0 : !s32i, cir.ptr <!s32i>
178+
cir.yield
179+
}
180+
}
181+
cir.return
182+
}
183+
184+
// MLIR: llvm.func @testDoWhile(%arg0: i32) {
185+
// MLIR-NEXT: %0 = llvm.mlir.constant(1 : index) : i64
186+
// MLIR-NEXT: %1 = llvm.alloca %0 x i32 {alignment = 4 : i64} : (i64) -> !llvm.ptr<i32>
187+
// MLIR-NEXT: llvm.store %arg0, %1 : !llvm.ptr<i32>
188+
// MLIR-NEXT: llvm.br ^bb1
189+
// MLIR-NEXT: ^bb1:
190+
// MLIR-NEXT: llvm.br ^bb5
191+
// ============= Condition block =============
192+
// MLIR-NEXT: ^bb2:
193+
// MLIR-NEXT: %2 = llvm.load %1 : !llvm.ptr<i32>
194+
// MLIR-NEXT: %3 = llvm.mlir.constant(10 : i32) : i32
195+
// MLIR-NEXT: %4 = llvm.icmp "slt" %2, %3 : i32
196+
// MLIR-NEXT: %5 = llvm.zext %4 : i1 to i32
197+
// MLIR-NEXT: %6 = llvm.mlir.constant(0 : i32) : i32
198+
// MLIR-NEXT: %7 = llvm.icmp "ne" %5, %6 : i32
199+
// MLIR-NEXT: %8 = llvm.zext %7 : i1 to i8
200+
// MLIR-NEXT: %9 = llvm.trunc %8 : i8 to i1
201+
// MLIR-NEXT: llvm.cond_br %9, ^bb3, ^bb4
202+
// MLIR-NEXT: ^bb3:
203+
// MLIR-NEXT: llvm.br ^bb5
204+
// MLIR-NEXT: ^bb4:
205+
// MLIR-NEXT: llvm.br ^bb6
206+
// ============= Body block =============
207+
// MLIR-NEXT: ^bb5:
208+
// MLIR-NEXT: %10 = llvm.load %1 : !llvm.ptr<i32>
209+
// MLIR-NEXT: %11 = llvm.mlir.constant(1 : i32) : i32
210+
// MLIR-NEXT: %12 = llvm.add %10, %11 : i32
211+
// MLIR-NEXT: llvm.store %12, %1 : !llvm.ptr<i32>
212+
// MLIR-NEXT: llvm.br ^bb2
213+
// ============= Exit block =============
214+
// MLIR-NEXT: ^bb6:
215+
// MLIR-NEXT: llvm.br ^bb7
216+
157217
}

0 commit comments

Comments
 (0)