Skip to content

Conversation

@AmrDeveloper
Copy link
Member

Upstream moving the allocas from cir.try block to the surrounding cir.scope

Issue #154992

@llvmbot llvmbot added clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project labels Oct 21, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 21, 2025

@llvm/pr-subscribers-clangir

Author: Amr Hesham (AmrDeveloper)

Changes

Upstream moving the allocas from cir.try block to the surrounding cir.scope

Issue #154992


Full diff: https://github.com/llvm/llvm-project/pull/164488.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+5-1)
  • (modified) clang/test/CIR/CodeGen/try-catch.cpp (+47)
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

@llvmbot
Copy link
Member

llvmbot commented Oct 21, 2025

@llvm/pr-subscribers-clang

Author: Amr Hesham (AmrDeveloper)

Changes

Upstream moving the allocas from cir.try block to the surrounding cir.scope

Issue #154992


Full diff: https://github.com/llvm/llvm-project/pull/164488.diff

2 Files Affected:

  • (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+5-1)
  • (modified) clang/test/CIR/CodeGen/try-catch.cpp (+47)
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

Copy link
Member

@Lancern Lancern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@AmrDeveloper AmrDeveloper merged commit 71b21b5 into llvm:main Oct 23, 2025
13 checks passed
dvbuka pushed a commit to dvbuka/llvm-project that referenced this pull request Oct 27, 2025
)

Upstream moving the allocas from cir.try block to the surrounding
cir.scope

Issue llvm#154992
Lukacma pushed a commit to Lukacma/llvm-project that referenced this pull request Oct 29, 2025
)

Upstream moving the allocas from cir.try block to the surrounding
cir.scope

Issue llvm#154992
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
)

Upstream moving the allocas from cir.try block to the surrounding
cir.scope

Issue llvm#154992
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants