Skip to content

Commit a81bb77

Browse files
committed
switch support gnu range
1 parent f690ca9 commit a81bb77

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

+12-5
Original file line numberDiff line numberDiff line change
@@ -619,11 +619,21 @@ CIRGenFunction::foldCaseStmt(const clang::CaseStmt &S, mlir::Type condType,
619619
// Fold cascading cases whenever possible to simplify codegen a bit.
620620
while (caseStmt) {
621621
lastCase = caseStmt;
622-
auto intVal = caseStmt->getLHS()->EvaluateKnownConstInt(getContext());
623-
caseEltValueListAttr.push_back(mlir::cir::IntAttr::get(condType, intVal));
622+
623+
auto startVal = caseStmt->getLHS()->EvaluateKnownConstInt(getContext());
624+
auto endVal = startVal;
625+
if (auto *rhs = caseStmt->getRHS()) {
626+
endVal = rhs->EvaluateKnownConstInt(getContext());
627+
}
628+
for (auto intVal = startVal; intVal <= endVal; ++intVal) {
629+
caseEltValueListAttr.push_back(mlir::cir::IntAttr::get(condType, intVal));
630+
}
631+
624632
caseStmt = dyn_cast_or_null<CaseStmt>(caseStmt->getSubStmt());
625633
}
626634

635+
assert(!caseEltValueListAttr.empty() && "empty case value NYI");
636+
627637
auto *ctxt = builder.getContext();
628638

629639
auto caseAttr = mlir::cir::CaseAttr::get(
@@ -672,9 +682,6 @@ mlir::LogicalResult CIRGenFunction::buildCaseDefaultCascade(
672682
mlir::LogicalResult
673683
CIRGenFunction::buildCaseStmt(const CaseStmt &S, mlir::Type condType,
674684
SmallVector<mlir::Attribute, 4> &caseAttrs) {
675-
assert((!S.getRHS() || !S.caseStmtIsGNURange()) &&
676-
"case ranges not implemented");
677-
678685
auto *caseStmt = foldCaseStmt(S, condType, caseAttrs);
679686
return buildCaseDefaultCascade(caseStmt, condType, caseAttrs);
680687
}

clang/test/CIR/CodeGen/switch.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -327,3 +327,31 @@ void fallthrough(int x) {
327327
// CHECK-NEXT: }
328328
// CHECK-NEXT: ]
329329
// CHECK-NEXT: }
330+
331+
enum letter {
332+
A, B, C, D, E, F, G, H, I, J, L
333+
};
334+
335+
int gnurange(enum letter c) {
336+
switch (c) {
337+
case A ... C:
338+
case D:
339+
case E ... F:
340+
case L ... A:
341+
return 1;
342+
default:
343+
return 0;
344+
}
345+
}
346+
347+
// CHECK: cir.func @_Z8gnurange6letter
348+
// CHECK: cir.scope {
349+
// CHECK: cir.switch
350+
// CHECK-NEXT: case (anyof, [0, 1, 2, 3, 4, 5] : !s32i) {
351+
// CHECK: cir.return
352+
// CHECK-NEXT: },
353+
// CHECK-NEXT: case (default) {
354+
// CHECK: cir.return
355+
// CHECK-NEXT: }
356+
// CHECK-NEXT: ]
357+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)