[clang] [CIR] Implement PromotableRegionOpInterface for `cir.if`,`cir.scope` and `cir.ternary` (PR #215780)

Konstantinos Parasyris via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 11 07:01:17 PDT 2026


================
@@ -187,3 +187,87 @@ DeletionKind cir::CastOp::removeBlockingUses(
     const SmallPtrSetImpl<OpOperand *> &blockingUses, OpBuilder &builder) {
   return DeletionKind::Delete;
 }
+
+//===----------------------------------------------------------------------===//
+// Interfaces for IfOp
+//===----------------------------------------------------------------------===//
+
+bool cir::IfOp::isRegionPromotable(const MemorySlot &slot, Region *region,
+                                   bool hasValueStores) {
+  // A definition produced inside a region has to leave through a result, and
+  // cir.if has none. Parameters and enclosing locals have their alloca
+  // outside and are only read here; those promote. A variable declared inside
+  // the region (`if (c) { int x = 42; use(x); }`) has its initializing store
+  // inside after cir-hoist-allocas, which is hasValueStores, so it is refused.
+  return !hasValueStores;
+}
+
+void cir::IfOp::setupPromotion(
+    const MemorySlot &slot, Value reachingDef, bool hasValueStores,
+    llvm::SmallMapVector<Region *, Value, 2> &regionsToProcess) {
+  // Exactly one region executes, exactly once, entered from before the op, so
+  // both see the same reaching definition.
+  regionsToProcess.insert({&getThenRegion(), reachingDef});
+  regionsToProcess.insert({&getElseRegion(), reachingDef});
----------------
koparasy wrote:

NIT: I would prefer here to guard these with a `if (!getElseRegion().empty())`. It looks like that I am a minority. SCF is not doing that. So up to you. 

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


More information about the cfe-commits mailing list