[clang] [CIR] Upstream support for switch statements case kinds (PR #138003)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Thu May 1 10:36:59 PDT 2025


================
@@ -428,6 +429,52 @@ mlir::LogicalResult CIRGenFunction::emitBreakStmt(const clang::BreakStmt &s) {
   return mlir::success();
 }
 
+const CaseStmt *CIRGenFunction::foldCaseStmt(const clang::CaseStmt &s,
+                                             mlir::Type condType,
+                                             mlir::ArrayAttr &value,
+                                             cir::CaseOpKind &kind) {
+  const CaseStmt *caseStmt = &s;
+  const CaseStmt *lastCase = &s;
+  SmallVector<mlir::Attribute, 4> caseEltValueListAttr;
+
+  // Fold cascading cases whenever possible to simplify codegen a bit.
+  while (caseStmt) {
+    lastCase = caseStmt;
+
+    auto intVal = caseStmt->getLHS()->EvaluateKnownConstInt(getContext());
+
+    if (auto *rhs = caseStmt->getRHS()) {
+      auto endVal = rhs->EvaluateKnownConstInt(getContext());
+      SmallVector<mlir::Attribute, 4> rangeCaseAttr = {
+          cir::IntAttr::get(condType, intVal),
+          cir::IntAttr::get(condType, endVal)};
+      value = builder.getArrayAttr(rangeCaseAttr);
+      kind = cir::CaseOpKind::Range;
+
+      // We may not be able to fold rangaes. Due to we can't present range case
+      // with other trivial cases now.
+      return caseStmt;
+    }
+
+    caseEltValueListAttr.push_back(cir::IntAttr::get(condType, intVal));
+
+    caseStmt = dyn_cast_or_null<CaseStmt>(caseStmt->getSubStmt());
+
+    // Break early if we found ranges. We can't fold ranges due to the same
+    // reason above.
+    if (caseStmt && caseStmt->getRHS())
+      break;
+  }
+
+  if (!caseEltValueListAttr.empty()) {
+    value = builder.getArrayAttr(caseEltValueListAttr);
+    kind = caseEltValueListAttr.size() > 1 ? cir::CaseOpKind::Anyof
----------------
erichkeane wrote:

So IIRC, 'anyof' is only valid if the case statements themselves are empty, right?  Else they could contain a label for a GOTO, or be a duffs-device/etc.  So i think we're being overly aggressive about joining these up here.

That said, i find myself wondering if the FE should be doing this sort of joining at all, rather than as a very early 'normalization' opt-pass.

https://github.com/llvm/llvm-project/pull/138003


More information about the cfe-commits mailing list