[clang] [CIR] Handle proper hoisting of const variables with InvariantGroupOp (PR #175037)

Andy Kaylor via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 8 14:29:36 PST 2026


================
@@ -33,6 +33,141 @@ struct HoistAllocasPass : public impl::HoistAllocasBase<HoistAllocasPass> {
   void runOnOperation() override;
 };
 
+static bool isOpInLoop(mlir::Operation *op) {
+  return op->getParentOfType<cir::LoopOpInterface>();
+}
+
+static bool hasStoreToAllocaInWhileCond(cir::AllocaOp alloca) {
+  // This function determines whether the given alloca operation represents
+  // a variable defined as a while loop's condition.
+  //
+  // Specifically, C/C++ allows the condition of a while loop be a variable
+  // declaration:
+  //
+  //   while (const int x = foo()) { /* body... */ }
+  //
+  // CIRGen would emit the following CIR for the above code:
+  //
+  //   cir.scope {
+  //     %x.slot = cir.alloca !s32i [init, const]
+  //     cir.while {
+  //       %0 = cir.call @foo()
+  //       cir.store %0, %x
+  //       %1 = cir.load %x
+  //       %2 = cir.cast int_to_bool %1
+  //       cir.condition(%2)
+  //     } do {
+  //       // loop body goes here.
+  //     }
+  //   }
+  //
+  // Note that %x.slot is emitted outside the cir.while operation. Ideally, the
+  // cir.while operation should cover this cir.alloca operation, but currently
----------------
andykaylor wrote:

Is this really what we "ideally" would want? I understand that the alloca is logically part of the while loop, but it is the way it is because we need the scope where the alloca appears to dominate the entire loop. I don't think this is just a matter of "we just did it that way". I think it has to be this way.

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


More information about the cfe-commits mailing list