[clang] [CIR] Move alloca from cir.try to the surrounding cir.scope (PR #164488)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 21 13:22:02 PDT 2025
https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/164488
Upstream moving the allocas from cir.try block to the surrounding cir.scope
Issue https://github.com/llvm/llvm-project/issues/154992
>From 3ec20d1c4e5ea0ab2bad7c1c928910a7c5164215 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Tue, 21 Oct 2025 22:20:12 +0200
Subject: [PATCH] [CIR] Move alloca from cir.try to the surrounding cir.scope
---
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 6 +++-
clang/test/CIR/CodeGen/try-catch.cpp | 47 ++++++++++++++++++++++++++++
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 52021fce1c675..3fee3b7683724 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -2064,7 +2064,11 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
// a surrounding cir.scope, make sure the alloca ends up in the surrounding
// scope instead. This is necessary in order to guarantee all SSA values are
// reachable during cleanups.
- assert(!cir::MissingFeatures::tryOp());
+ if (auto tryOp =
+ llvm::dyn_cast_if_present<cir::TryOp>(entryBlock->getParentOp())) {
+ if (auto scopeOp = llvm::dyn_cast<cir::ScopeOp>(tryOp->getParentOp()))
+ entryBlock = &scopeOp.getScopeRegion().front();
+ }
return emitAlloca(name, ty, loc, alignment,
builder.getBestAllocaInsertPoint(entryBlock), arraySize);
diff --git a/clang/test/CIR/CodeGen/try-catch.cpp b/clang/test/CIR/CodeGen/try-catch.cpp
index 5a503102d13df..1e4d2a63ada01 100644
--- a/clang/test/CIR/CodeGen/try-catch.cpp
+++ b/clang/test/CIR/CodeGen/try-catch.cpp
@@ -117,3 +117,50 @@ void try_catch_with_empty_catch_all_2() {
// OGCG: %[[RESULT:.*]] = add nsw i32 %[[TMP_A]], 1
// OGCG: store i32 %[[RESULT]], ptr %[[A_ADDR]], align 4
// OGCG: ret void
+
+void try_catch_with_alloca() {
+ try {
+ int a;
+ int b;
+ int c = a + b;
+ } catch (...) {
+ }
+}
+
+// CIR: cir.scope {
+// CIR: %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a"]
+// CIR: %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b"]
+// CIR: %[[C_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["c", init]
+// CIR: cir.try {
+// CIR: %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[RESULT:.*]] = cir.binop(add, %[[TMP_A]], %[[TMP_B]]) nsw : !s32i
+// CIR: cir.store{{.*}} %[[RESULT]], %[[C_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CIR: cir.yield
+// CIR: }
+// CIR: }
+
+// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: %[[B_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: %[[C_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: br label %[[LABEL_1:.*]]
+// LLVM: [[LABEL_1]]:
+// LLVM: br label %[[LABEL_2:.*]]
+// LLVM: [[LABEL_2]]:
+// LLVM: %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// LLVM: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4
+// LLVM: %[[RESULT:.*]] = add nsw i32 %[[TMP_A]], %[[TMP_B]]
+// LLVM: store i32 %[[RESULT]], ptr %[[C_ADDR]], align 4
+// LLVM: br label %[[LABEL_3:.*]]
+// LLVM: [[LABEL_3]]:
+// LLVM: br label %[[LABEL_4:.*]]
+// LLVM: [[LABEL_4]]:
+// LLVM: ret void
+
+// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[B_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[C_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// OGCG: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4
+// OGCG: %[[RESULT:.*]] = add nsw i32 %[[TMP_A]], %[[TMP_B]]
+// OGCG: store i32 %[[RESULT]], ptr %[[C_ADDR]], align 4
More information about the cfe-commits
mailing list