Skip to content

Commit 72b42af

Browse files
authored
[CIR][CodeGen] Handling multiple stmt followed after a switch case (#878)
Close #876 We've already considered the case that there are random stmt after a switch case: ``` for (auto *c : compoundStmt->body()) { if (auto *switchCase = dyn_cast<SwitchCase>(c)) { res = buildSwitchCase(*switchCase, condType, caseAttrs); } else if (lastCaseBlock) { // This means it's a random stmt following up a case, just // emit it as part of previous known case. mlir::OpBuilder::InsertionGuard guardCase(builder); builder.setInsertionPointToEnd(lastCaseBlock); res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c)); } else { llvm_unreachable("statement doesn't belong to any case region, NYI"); } lastCaseBlock = builder.getBlock(); if (res.failed()) break; } ``` However, maybe this is an oversight, in the branch of ` if (lastCaseBlock)`, the insertion point will be updated automatically when the RAII object `guardCase` destroys, then we can assign the correct value for `lastCaseBlock` later. So we will see the weird code pattern in the issue side. BTW, I found the codes in CIRGenStmt.cpp are far more less similar with the ones other code gen places. Is this intentional? And what is the motivation and guide lines here?
1 parent 5fd96c6 commit 72b42af

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -996,18 +996,18 @@ mlir::LogicalResult CIRGenFunction::buildSwitchBody(
996996
for (auto *c : compoundStmt->body()) {
997997
if (auto *switchCase = dyn_cast<SwitchCase>(c)) {
998998
res = buildSwitchCase(*switchCase, condType, caseAttrs);
999+
lastCaseBlock = builder.getBlock();
9991000
} else if (lastCaseBlock) {
10001001
// This means it's a random stmt following up a case, just
10011002
// emit it as part of previous known case.
10021003
mlir::OpBuilder::InsertionGuard guardCase(builder);
10031004
builder.setInsertionPointToEnd(lastCaseBlock);
10041005
res = buildStmt(c, /*useCurrentScope=*/!isa<CompoundStmt>(c));
1006+
lastCaseBlock = builder.getBlock();
10051007
} else {
10061008
llvm_unreachable("statement doesn't belong to any case region, NYI");
10071009
}
10081010

1009-
lastCaseBlock = builder.getBlock();
1010-
10111011
if (res.failed())
10121012
break;
10131013
}

clang/test/CIR/CodeGen/goto.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,25 @@ void foo() {
288288
// NOFLAT: cir.scope {
289289
// NOFLAT: cir.label "label"
290290
// NOFLAT: %0 = cir.alloca !ty_S, !cir.ptr<!ty_S>, ["agg.tmp0"]
291+
292+
extern "C" void action1();
293+
extern "C" void action2();
294+
extern "C" void multiple_non_case(int v) {
295+
switch (v) {
296+
default:
297+
action1();
298+
l2:
299+
action2();
300+
break;
301+
}
302+
}
303+
304+
// NOFLAT: cir.func @multiple_non_case
305+
// NOFLAT: cir.switch
306+
// NOFLAT: case (default)
307+
// NOFLAT: cir.call @action1()
308+
// NOFLAT: cir.br ^[[BB1:[a-zA-Z0-9]+]]
309+
// NOFLAT: ^[[BB1]]:
310+
// NOFLAT: cir.label
311+
// NOFLAT: cir.call @action2()
312+
// NOFLAT: cir.break

0 commit comments

Comments
 (0)