https://github.com/AmrDeveloper updated 
https://github.com/llvm/llvm-project/pull/154994

>From 0a0c6291aa24acbc4a758b141e0b1e56676d99fd Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Fri, 22 Aug 2025 15:34:47 +0200
Subject: [PATCH 1/3] [CIR] Upstream Re-Throw with no return

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      | 21 +++++++-
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 54 +++++++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenCXXABI.h          |  4 +-
 clang/lib/CIR/CodeGen/CIRGenException.cpp     | 41 ++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp    |  5 ++
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |  2 +
 clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 50 ++++++++++++++++-
 clang/lib/CIR/CodeGen/CMakeLists.txt          |  1 +
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       | 18 +++++++
 .../Dialect/Transforms/LoweringPrepare.cpp    | 24 ++++++++-
 clang/test/CIR/CodeGen/exceptions.cpp         | 19 +++++++
 11 files changed, 235 insertions(+), 4 deletions(-)
 create mode 100644 clang/lib/CIR/CodeGen/CIRGenException.cpp
 create mode 100644 clang/test/CIR/CodeGen/exceptions.cpp

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index d29e5687d2544..aba4615b2a7f4 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -19,7 +19,6 @@
 
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/BuiltinAttributes.h"
-#include "mlir/IR/BuiltinTypes.h"
 #include "mlir/IR/Location.h"
 #include "mlir/IR/Types.h"
 
@@ -313,6 +312,26 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
                         resOperands, attrs);
   }
 
+  cir::CallOp
+  createTryCallOp(mlir::Location loc,
+                  mlir::SymbolRefAttr callee = mlir::SymbolRefAttr(),
+                  mlir::Type returnType = cir::VoidType(),
+                  mlir::ValueRange operands = mlir::ValueRange(),
+                  cir::SideEffect sideEffect = cir::SideEffect::All) {
+    assert(!cir::MissingFeatures::opCallCallConv());
+    return createCallOp(loc, callee, returnType, operands);
+  }
+
+  cir::CallOp
+  createTryCallOp(mlir::Location loc, cir::FuncOp callee,
+                  mlir::ValueRange operands,
+                  cir::SideEffect sideEffect = cir::SideEffect::All) {
+    assert(!cir::MissingFeatures::opCallCallConv());
+    return createTryCallOp(loc, mlir::SymbolRefAttr::get(callee),
+                           callee.getFunctionType().getReturnType(), operands,
+                           sideEffect);
+  }
+
   
//===--------------------------------------------------------------------===//
   // Cast/Conversion Operators
   
//===--------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 8ab602000cc29..1a38e045dcf77 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3800,4 +3800,58 @@ def CIR_VAArgOp : CIR_Op<"va_arg"> {
   }];
 }
 
+//===----------------------------------------------------------------------===//
+// ThrowOp
+//===----------------------------------------------------------------------===//
+
+def CIR_ThrowOp : CIR_Op<"throw"> {
+  let summary = "(Re)Throws an exception";
+  let description = [{
+    Very similar to __cxa_throw:
+
+    ```
+    void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
+                     void (*dest) (void *));
+    ```
+
+    The absense of arguments for `cir.throw` means it rethrows.
+
+    For the no-rethrow version, it must have at least two operands, the RTTI
+    information, a pointer to the exception object (likely allocated via
+    `cir.cxa.allocate_exception`) and finally an optional dtor, which might
+    run as part of this operation.
+
+    Example:
+    ```mlir
+      // throw;
+      cir.throw
+
+      // if (b == 0)
+      //   throw "Division by zero condition!";
+      cir.if %cond {
+        %exception_addr = cir.alloc_exception 8 -> !cir.ptr<!void>
+        ...
+        cir.store %string_addr, %exception_addr : // Store string addr for 
"Division by zero condition!"
+        cir.throw %exception_addr : !cir.ptr<!cir.ptr<!u8i>>, @"typeinfo for 
char const*"
+    ```
+  }];
+
+  let arguments = (ins Optional<CIR_PointerType>:$exception_ptr,
+                       OptionalAttr<FlatSymbolRefAttr>:$type_info,
+                       OptionalAttr<FlatSymbolRefAttr>:$dtor);
+
+  let assemblyFormat = [{
+    ($exception_ptr^ `:` type($exception_ptr))?
+    (`,` $type_info^)?
+    (`,` $dtor^)?
+    attr-dict
+  }];
+
+  let extraClassDeclaration = [{
+    bool rethrows() { return getNumOperands() == 0; }
+  }];
+
+  let hasVerifier = 1;
+}
+
 #endif // CLANG_CIR_DIALECT_IR_CIROPS_TD
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h 
b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
index b5f2e1a067274..4ec6969aee7bf 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCXXABI.h
@@ -47,9 +47,11 @@ class CIRGenCXXABI {
   }
 
   /// Emit the ABI-specific prolog for the function
-  virtual void emitInstanceFunctionProlog(SourceLocation Loc,
+  virtual void emitInstanceFunctionProlog(SourceLocation loc,
                                           CIRGenFunction &cgf) = 0;
 
+  virtual void emitRethrow(CIRGenFunction &cgf, bool isNoReturn) = 0;
+
   /// Get the type of the implicit "this" parameter used by a method. May 
return
   /// zero if no specific type is applicable, e.g. if the ABI expects the 
"this"
   /// parameter to point to some artificial offset in a complete object due to
diff --git a/clang/lib/CIR/CodeGen/CIRGenException.cpp 
b/clang/lib/CIR/CodeGen/CIRGenException.cpp
new file mode 100644
index 0000000000000..7fcb39a2b74c4
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenException.cpp
@@ -0,0 +1,41 @@
+//===--- CIRGenException.cpp - Emit CIR Code for C++ exceptions -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with C++ exception related code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenCXXABI.h"
+#include "CIRGenFunction.h"
+
+#include "clang/AST/StmtVisitor.h"
+
+using namespace clang;
+using namespace clang::CIRGen;
+
+void CIRGenFunction::emitCXXThrowExpr(const CXXThrowExpr *e) {
+  const llvm::Triple &triple = getTarget().getTriple();
+  if (cgm.getLangOpts().OpenMPIsTargetDevice &&
+      (triple.isNVPTX() || triple.isAMDGCN())) {
+    cgm.errorNYI("emitCXXThrowExpr OpenMP with NVPTX or AMDGCN Triples");
+    return;
+  }
+
+  if (const Expr *subExpr = e->getSubExpr()) {
+    QualType throwType = subExpr->getType();
+    if (throwType->isObjCObjectPointerType()) {
+      cgm.errorNYI("emitCXXThrowExpr ObjCObjectPointerType");
+      return;
+    } else {
+      cgm.errorNYI("emitCXXThrowExpr with subExpr");
+      return;
+    }
+  } else {
+    cgm.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true);
+  }
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 46934e7155adf..f0bebfeb19430 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -657,6 +657,11 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
     return cgf.emitCXXNewExpr(e);
   }
 
+  mlir::Value VisitCXXThrowExpr(const CXXThrowExpr *e) {
+    cgf.emitCXXThrowExpr(e);
+    return nullptr;
+  }
+
   /// Emit a conversion from the specified type to the specified destination
   /// type, both of which are CIR scalar types.
   /// TODO: do we need ScalarConversionOpts here? Should be done in another
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 064b3c15a310b..6829ad63895eb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -1140,6 +1140,8 @@ class CIRGenFunction : public CIRGenTypeCache {
 
   RValue emitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *expr);
 
+  void emitCXXThrowExpr(const CXXThrowExpr *e);
+
   void emitCtorPrologue(const clang::CXXConstructorDecl *ctor,
                         clang::CXXCtorType ctorType, FunctionArgList &args);
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp 
b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index aaf7dc767d888..1d98b801e90f8 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -56,6 +56,8 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
                           bool delegating, Address thisAddr,
                           QualType thisTy) override;
 
+  void emitRethrow(CIRGenFunction &cgf, bool isNoReturn) override;
+
   bool useThunkForDtorVariant(const CXXDestructorDecl *dtor,
                               CXXDtorType dt) const override {
     // Itanium does not emit any destructor variant as an inline thunk.
@@ -125,7 +127,7 @@ void 
CIRGenItaniumCXXABI::emitInstanceFunctionProlog(SourceLocation loc,
 // Find out how to cirgen the complete destructor and constructor
 namespace {
 enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
-}
+} // namespace
 
 static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm,
                                      const CXXMethodDecl *md) {
@@ -352,6 +354,52 @@ void CIRGenItaniumCXXABI::emitDestructorCall(
                             vttTy, nullptr);
 }
 
+// The idea here is creating a separate block for the throw with an
+// `UnreachableOp` as the terminator. So, we branch from the current block
+// to the throw block and create a block for the remaining operations.
+static void insertThrowAndSplit(mlir::OpBuilder &builder, mlir::Location loc,
+                                mlir::Value exceptionPtr = {},
+                                mlir::FlatSymbolRefAttr typeInfo = {},
+                                mlir::FlatSymbolRefAttr dtor = {}) {
+  mlir::Block *currentBlock = builder.getInsertionBlock();
+  mlir::Region *region = currentBlock->getParent();
+
+  if (currentBlock->empty()) {
+    cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
+    cir::UnreachableOp::create(builder, loc);
+  } else {
+    mlir::Block *throwBlock = builder.createBlock(region);
+
+    cir::ThrowOp::create(builder, loc, exceptionPtr, typeInfo, dtor);
+    cir::UnreachableOp::create(builder, loc);
+
+    builder.setInsertionPointToEnd(currentBlock);
+    cir::BrOp::create(builder, loc, throwBlock);
+  }
+
+  (void)builder.createBlock(region);
+
+  // This will be erased during codegen, it acts as a placeholder for the
+  // operations to be inserted (if any)
+  cir::ScopeOp::create(builder, loc, /*scopeBuilder=*/
+                       [&](mlir::OpBuilder &b, mlir::Location loc) {
+                         b.create<cir::YieldOp>(loc);
+                       });
+}
+
+void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf, bool isNoReturn) {
+  // void __cxa_rethrow();
+
+  if (isNoReturn) {
+    CIRGenBuilderTy &builder = cgf.getBuilder();
+    assert(cgf.currSrcLoc && "expected source location");
+    mlir::Location loc = *cgf.currSrcLoc;
+    insertThrowAndSplit(builder, loc);
+  } else {
+    cgm.errorNYI("emitRethrow with isNoReturn false");
+  }
+}
+
 CIRGenCXXABI *clang::CIRGen::CreateCIRGenItaniumCXXABI(CIRGenModule &cgm) {
   switch (cgm.getASTContext().getCXXABIKind()) {
   case TargetCXXABI::GenericItanium:
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt 
b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 7366446a33c6e..6d7072ad18696 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -20,6 +20,7 @@ add_clang_library(clangCIR
   CIRGenBuiltin.cpp
   CIRGenDecl.cpp
   CIRGenDeclOpenACC.cpp
+  CIRGenException.cpp
   CIRGenExpr.cpp
   CIRGenExprAggregate.cpp
   CIRGenExprComplex.cpp
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 8c53939e89d01..3f5bf799d2c9f 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2650,6 +2650,24 @@ ParseResult cir::InlineAsmOp::parse(OpAsmParser &parser,
   return mlir::success();
 }
 
+//===----------------------------------------------------------------------===//
+// ThrowOp
+//===----------------------------------------------------------------------===//
+
+mlir::LogicalResult cir::ThrowOp::verify() {
+  // For the no-rethrow version, it must have at least the exception pointer.
+  if (rethrows())
+    return success();
+
+  if (getNumOperands() == 1) {
+    if (getTypeInfo())
+      return success();
+    return emitOpError() << "'type_info' symbol attribute missing";
+  }
+
+  return failure();
+}
+
 
//===----------------------------------------------------------------------===//
 // TableGen'd op method definitions
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp 
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index c15637d297cd1..cccfe9b444a31 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -32,6 +32,7 @@ struct LoweringPreparePass : public 
LoweringPrepareBase<LoweringPreparePass> {
   void lowerUnaryOp(cir::UnaryOp op);
   void lowerArrayDtor(cir::ArrayDtor op);
   void lowerArrayCtor(cir::ArrayCtor op);
+  void lowerThrowOp(ThrowOp op);
 
   cir::FuncOp buildRuntimeFunction(
       mlir::OpBuilder &builder, llvm::StringRef name, mlir::Location loc,
@@ -680,6 +681,24 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor 
op) {
                              true);
 }
 
+void LoweringPreparePass::lowerThrowOp(ThrowOp op) {
+  if (op.rethrows()) {
+    CIRBaseBuilderTy builder(getContext());
+    auto voidTy = cir::VoidType::get(builder.getContext());
+    auto fnType = cir::FuncType::get({}, voidTy);
+
+    builder.setInsertionPointToStart(&mlirModule.getBodyRegion().front());
+    FuncOp f =
+        buildRuntimeFunction(builder, "__cxa_rethrow", op.getLoc(), fnType);
+
+    builder.setInsertionPointAfter(op.getOperation());
+    cir::CallOp call = builder.createTryCallOp(op.getLoc(), f, {});
+
+    op->replaceAllUsesWith(call);
+    op->erase();
+  }
+}
+
 void LoweringPreparePass::runOnOp(mlir::Operation *op) {
   if (auto arrayCtor = dyn_cast<ArrayCtor>(op))
     lowerArrayCtor(arrayCtor);
@@ -693,6 +712,8 @@ void LoweringPreparePass::runOnOp(mlir::Operation *op) {
     lowerComplexMulOp(complexMul);
   else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op))
     lowerUnaryOp(unary);
+  else if (auto throwOp = mlir::dyn_cast<cir::ThrowOp>(op))
+    lowerThrowOp(throwOp);
 }
 
 void LoweringPreparePass::runOnOperation() {
@@ -704,7 +725,8 @@ void LoweringPreparePass::runOnOperation() {
 
   op->walk([&](mlir::Operation *op) {
     if (mlir::isa<cir::ArrayCtor, cir::ArrayDtor, cir::CastOp,
-                  cir::ComplexMulOp, cir::ComplexDivOp, cir::UnaryOp>(op))
+                  cir::ComplexMulOp, cir::ComplexDivOp, cir::UnaryOp,
+                  cir::ThrowOp>(op))
       opsToTransform.push_back(op);
   });
 
diff --git a/clang/test/CIR/CodeGen/exceptions.cpp 
b/clang/test/CIR/CodeGen/exceptions.cpp
new file mode 100644
index 0000000000000..a1a87bcb2f393
--- /dev/null
+++ b/clang/test/CIR/CodeGen/exceptions.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu 
-fcxx-exceptions -fexceptions -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu 
-fcxx-exceptions -fexceptions -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu 
-fcxx-exceptions -fexceptions -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+void foo() {
+  throw;
+}
+
+// CIR: cir.call @__cxa_rethrow() : () -> ()
+// CIR: cir.unreachable
+
+// LLVM: call void @__cxa_rethrow()
+// LLVM: unreachable
+
+// OGCG: call void @__cxa_rethrow()
+// OGCG: unreachable

>From 58d0ac57499ae1b24ade64d74c307b5634cd8b19 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Fri, 22 Aug 2025 20:46:26 +0200
Subject: [PATCH 2/3] Rename test file to throws to be alligned with incubator
 for now

---
 clang/test/CIR/CodeGen/{exceptions.cpp => throws.cpp} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename clang/test/CIR/CodeGen/{exceptions.cpp => throws.cpp} (100%)

diff --git a/clang/test/CIR/CodeGen/exceptions.cpp 
b/clang/test/CIR/CodeGen/throws.cpp
similarity index 100%
rename from clang/test/CIR/CodeGen/exceptions.cpp
rename to clang/test/CIR/CodeGen/throws.cpp

>From 9faf67852bbcc883c7b10fffbfa434a217f5c629 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Fri, 22 Aug 2025 23:53:41 +0200
Subject: [PATCH 3/3] Address code review comments

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      | 23 +++----
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  2 +-
 clang/include/clang/CIR/MissingFeatures.h     |  1 +
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp    |  2 +-
 clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp | 10 +--
 clang/lib/CIR/Dialect/IR/CIRDialect.cpp       |  2 +-
 .../Dialect/Transforms/LoweringPrepare.cpp    | 24 +------
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 45 ++++++++++--
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 10 +++
 clang/test/CIR/CodeGen/throws.cpp             | 68 ++++++++++++++++++-
 clang/test/CIR/IR/invalid-throw.cir           | 16 +++++
 clang/test/CIR/IR/throw.cir                   | 63 +++++++++++++++++
 12 files changed, 214 insertions(+), 52 deletions(-)
 create mode 100644 clang/test/CIR/IR/invalid-throw.cir
 create mode 100644 clang/test/CIR/IR/throw.cir

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index aba4615b2a7f4..96f55f5c66071 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -312,24 +312,23 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
                         resOperands, attrs);
   }
 
-  cir::CallOp
-  createTryCallOp(mlir::Location loc,
-                  mlir::SymbolRefAttr callee = mlir::SymbolRefAttr(),
-                  mlir::Type returnType = cir::VoidType(),
-                  mlir::ValueRange operands = mlir::ValueRange(),
-                  cir::SideEffect sideEffect = cir::SideEffect::All) {
+  cir::CallOp createTryCallOp(
+      mlir::Location loc, mlir::SymbolRefAttr callee = mlir::SymbolRefAttr(),
+      mlir::Type returnType = cir::VoidType(),
+      mlir::ValueRange operands = mlir::ValueRange(),
+      [[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) {
     assert(!cir::MissingFeatures::opCallCallConv());
+    assert(!cir::MissingFeatures::opCallSideEffect());
     return createCallOp(loc, callee, returnType, operands);
   }
 
-  cir::CallOp
-  createTryCallOp(mlir::Location loc, cir::FuncOp callee,
-                  mlir::ValueRange operands,
-                  cir::SideEffect sideEffect = cir::SideEffect::All) {
+  cir::CallOp createTryCallOp(
+      mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands,
+      [[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) {
     assert(!cir::MissingFeatures::opCallCallConv());
+    assert(!cir::MissingFeatures::opCallSideEffect());
     return createTryCallOp(loc, mlir::SymbolRefAttr::get(callee),
-                           callee.getFunctionType().getReturnType(), operands,
-                           sideEffect);
+                           callee.getFunctionType().getReturnType(), operands);
   }
 
   
//===--------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 1a38e045dcf77..49db97efb3702 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -3807,7 +3807,7 @@ def CIR_VAArgOp : CIR_Op<"va_arg"> {
 def CIR_ThrowOp : CIR_Op<"throw"> {
   let summary = "(Re)Throws an exception";
   let description = [{
-    Very similar to __cxa_throw:
+    It's equivalent __cxa_throw:
 
     ```
     void __cxa_throw(void *thrown_exception, std::type_info *tinfo,
diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index d7a2e49ec162a..e023d205df92e 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -93,6 +93,7 @@ struct MissingFeatures {
   static bool opCallReturn() { return false; }
   static bool opCallArgEvaluationOrder() { return false; }
   static bool opCallCallConv() { return false; }
+  static bool opCallSideEffect() { return false; }
   static bool opCallMustTail() { return false; }
   static bool opCallInAlloca() { return false; }
   static bool opCallAttrs() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index f0bebfeb19430..406d8398098b3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -659,7 +659,7 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
 
   mlir::Value VisitCXXThrowExpr(const CXXThrowExpr *e) {
     cgf.emitCXXThrowExpr(e);
-    return nullptr;
+    return {};
   }
 
   /// Emit a conversion from the specified type to the specified destination
diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp 
b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
index 1d98b801e90f8..c0f9148249f41 100644
--- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp
@@ -127,7 +127,7 @@ void 
CIRGenItaniumCXXABI::emitInstanceFunctionProlog(SourceLocation loc,
 // Find out how to cirgen the complete destructor and constructor
 namespace {
 enum class StructorCIRGen { Emit, RAUW, Alias, COMDAT };
-} // namespace
+}
 
 static StructorCIRGen getCIRGenToUse(CIRGenModule &cgm,
                                      const CXXMethodDecl *md) {
@@ -378,18 +378,10 @@ static void insertThrowAndSplit(mlir::OpBuilder &builder, 
mlir::Location loc,
   }
 
   (void)builder.createBlock(region);
-
-  // This will be erased during codegen, it acts as a placeholder for the
-  // operations to be inserted (if any)
-  cir::ScopeOp::create(builder, loc, /*scopeBuilder=*/
-                       [&](mlir::OpBuilder &b, mlir::Location loc) {
-                         b.create<cir::YieldOp>(loc);
-                       });
 }
 
 void CIRGenItaniumCXXABI::emitRethrow(CIRGenFunction &cgf, bool isNoReturn) {
   // void __cxa_rethrow();
-
   if (isNoReturn) {
     CIRGenBuilderTy &builder = cgf.getBuilder();
     assert(cgf.currSrcLoc && "expected source location");
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp 
b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
index 3f5bf799d2c9f..ee15618581cef 100644
--- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
+++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
@@ -2659,7 +2659,7 @@ mlir::LogicalResult cir::ThrowOp::verify() {
   if (rethrows())
     return success();
 
-  if (getNumOperands() == 1) {
+  if (getNumOperands() != 0) {
     if (getTypeInfo())
       return success();
     return emitOpError() << "'type_info' symbol attribute missing";
diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp 
b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
index cccfe9b444a31..c15637d297cd1 100644
--- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp
@@ -32,7 +32,6 @@ struct LoweringPreparePass : public 
LoweringPrepareBase<LoweringPreparePass> {
   void lowerUnaryOp(cir::UnaryOp op);
   void lowerArrayDtor(cir::ArrayDtor op);
   void lowerArrayCtor(cir::ArrayCtor op);
-  void lowerThrowOp(ThrowOp op);
 
   cir::FuncOp buildRuntimeFunction(
       mlir::OpBuilder &builder, llvm::StringRef name, mlir::Location loc,
@@ -681,24 +680,6 @@ void LoweringPreparePass::lowerArrayCtor(cir::ArrayCtor 
op) {
                              true);
 }
 
-void LoweringPreparePass::lowerThrowOp(ThrowOp op) {
-  if (op.rethrows()) {
-    CIRBaseBuilderTy builder(getContext());
-    auto voidTy = cir::VoidType::get(builder.getContext());
-    auto fnType = cir::FuncType::get({}, voidTy);
-
-    builder.setInsertionPointToStart(&mlirModule.getBodyRegion().front());
-    FuncOp f =
-        buildRuntimeFunction(builder, "__cxa_rethrow", op.getLoc(), fnType);
-
-    builder.setInsertionPointAfter(op.getOperation());
-    cir::CallOp call = builder.createTryCallOp(op.getLoc(), f, {});
-
-    op->replaceAllUsesWith(call);
-    op->erase();
-  }
-}
-
 void LoweringPreparePass::runOnOp(mlir::Operation *op) {
   if (auto arrayCtor = dyn_cast<ArrayCtor>(op))
     lowerArrayCtor(arrayCtor);
@@ -712,8 +693,6 @@ void LoweringPreparePass::runOnOp(mlir::Operation *op) {
     lowerComplexMulOp(complexMul);
   else if (auto unary = mlir::dyn_cast<cir::UnaryOp>(op))
     lowerUnaryOp(unary);
-  else if (auto throwOp = mlir::dyn_cast<cir::ThrowOp>(op))
-    lowerThrowOp(throwOp);
 }
 
 void LoweringPreparePass::runOnOperation() {
@@ -725,8 +704,7 @@ void LoweringPreparePass::runOnOperation() {
 
   op->walk([&](mlir::Operation *op) {
     if (mlir::isa<cir::ArrayCtor, cir::ArrayDtor, cir::CastOp,
-                  cir::ComplexMulOp, cir::ComplexDivOp, cir::UnaryOp,
-                  cir::ThrowOp>(op))
+                  cir::ComplexMulOp, cir::ComplexDivOp, cir::UnaryOp>(op))
       opsToTransform.push_back(op);
   });
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 9f0e4e6ecb8ce..fdae389d4edbf 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -2435,6 +2435,7 @@ void ConvertCIRToLLVMPass::runOnOperation() {
                CIRToLLVMStackRestoreOpLowering,
                CIRToLLVMStackSaveOpLowering,
                CIRToLLVMSwitchFlatOpLowering,
+               CIRToLLVMThrowOpLowering,
                CIRToLLVMTrapOpLowering,
                CIRToLLVMUnaryOpLowering,
                CIRToLLVMUnreachableOpLowering,
@@ -2514,6 +2515,42 @@ mlir::LogicalResult 
CIRToLLVMUnreachableOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+void createLLVMFuncOpIfNotExist(mlir::ConversionPatternRewriter &rewriter,
+                                mlir::Operation *srcOp, llvm::StringRef fnName,
+                                mlir::Type fnTy) {
+  auto modOp = srcOp->getParentOfType<mlir::ModuleOp>();
+  auto enclosingFnOp = srcOp->getParentOfType<mlir::LLVM::LLVMFuncOp>();
+  mlir::Operation *sourceSymbol =
+      mlir::SymbolTable::lookupSymbolIn(modOp, fnName);
+  if (!sourceSymbol) {
+    mlir::OpBuilder::InsertionGuard guard(rewriter);
+    rewriter.setInsertionPoint(enclosingFnOp);
+    rewriter.create<mlir::LLVM::LLVMFuncOp>(srcOp->getLoc(), fnName, fnTy);
+  }
+}
+
+mlir::LogicalResult CIRToLLVMThrowOpLowering::matchAndRewrite(
+    cir::ThrowOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  if (op.rethrows()) {
+    auto voidTy = mlir::LLVM::LLVMVoidType::get(getContext());
+    auto funcTy =
+        mlir::LLVM::LLVMFunctionType::get(getContext(), voidTy, {}, false);
+
+    auto mlirModule = op->getParentOfType<mlir::ModuleOp>();
+    rewriter.setInsertionPointToStart(&mlirModule.getBodyRegion().front());
+
+    const llvm::StringRef functionName = "__cxa_rethrow";
+    createLLVMFuncOpIfNotExist(rewriter, op, functionName, funcTy);
+
+    rewriter.setInsertionPointAfter(op.getOperation());
+    rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(
+        op, mlir::TypeRange{}, functionName, mlir::ValueRange{});
+  }
+
+  return mlir::success();
+}
+
 mlir::LogicalResult CIRToLLVMTrapOpLowering::matchAndRewrite(
     cir::TrapOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
@@ -3129,7 +3166,7 @@ mlir::LogicalResult 
CIRToLLVMInlineAsmOpLowering::matchAndRewrite(
 
   SmallVector<mlir::Value> llvmOperands;
   SmallVector<mlir::Value> cirOperands;
-  for (auto const&[llvmOp, cirOp] :
+  for (auto const &[llvmOp, cirOp] :
        zip(adaptor.getAsmOperands(), op.getAsmOperands())) {
     append_range(llvmOperands, llvmOp);
     append_range(cirOperands, cirOp);
@@ -3137,15 +3174,15 @@ mlir::LogicalResult 
CIRToLLVMInlineAsmOpLowering::matchAndRewrite(
 
   // so far we infer the llvm dialect element type attr from
   // CIR operand type.
-  for (auto const&[cirOpAttr, cirOp] : zip(op.getOperandAttrs(), cirOperands)) 
{    
+  for (auto const &[cirOpAttr, cirOp] :
+       zip(op.getOperandAttrs(), cirOperands)) {
     if (!cirOpAttr) {
       opAttrs.push_back(mlir::Attribute());
       continue;
     }
 
     llvm::SmallVector<mlir::NamedAttribute, 1> attrs;
-    cir::PointerType typ =
-        mlir::cast<cir::PointerType>(cirOp.getType());
+    cir::PointerType typ = mlir::cast<cir::PointerType>(cirOp.getType());
     mlir::TypeAttr typAttr = mlir::TypeAttr::get(convertTypeForMemory(
         *getTypeConverter(), dataLayout, typ.getPointee()));
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
index 7b109c5cef9d3..173607c6a3ad5 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
@@ -725,6 +725,16 @@ class CIRToLLVMInlineAsmOpLowering
                   mlir::ConversionPatternRewriter &) const override;
 };
 
+class CIRToLLVMThrowOpLowering
+    : public mlir::OpConversionPattern<cir::ThrowOp> {
+public:
+  using mlir::OpConversionPattern<cir::ThrowOp>::OpConversionPattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(cir::ThrowOp op, OpAdaptor,
+                  mlir::ConversionPatternRewriter &) const override;
+};
+
 class CIRToLLVMVAStartOpLowering
     : public mlir::OpConversionPattern<cir::VAStartOp> {
 public:
diff --git a/clang/test/CIR/CodeGen/throws.cpp 
b/clang/test/CIR/CodeGen/throws.cpp
index a1a87bcb2f393..0122f3088f0bf 100644
--- a/clang/test/CIR/CodeGen/throws.cpp
+++ b/clang/test/CIR/CodeGen/throws.cpp
@@ -9,7 +9,7 @@ void foo() {
   throw;
 }
 
-// CIR: cir.call @__cxa_rethrow() : () -> ()
+// CIR: cir.throw
 // CIR: cir.unreachable
 
 // LLVM: call void @__cxa_rethrow()
@@ -17,3 +17,69 @@ void foo() {
 
 // OGCG: call void @__cxa_rethrow()
 // OGCG: unreachable
+
+int foo1(int a, int b) {
+  if (b == 0)
+    throw;
+  return a / b;
+}
+
+// CIR:  %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
+// CIR:  %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+// CIR:  %[[RES_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
+// CIR:  cir.store %{{.*}}, %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CIR:  cir.store %{{.*}}, %[[B_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CIR:  cir.scope {
+// CIR:    %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR:    %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
+// CIR:    %[[IS_B_ZERO:.*]] = cir.cmp(eq, %[[TMP_B]], %[[CONST_0]]) : !s32i, 
!cir.bool
+// CIR:    cir.if %[[IS_B_ZERO]] {
+// CIR:      cir.throw
+// CIR:      cir.unreachable
+// CIR:    }
+// CIR:  }
+// CIR:  %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  %[[DIV_A_B:.*]] = cir.binop(div, %[[TMP_A:.*]], %[[TMP_B:.*]]) : !s32i
+// CIR:  cir.store %[[DIV_A_B]], %[[RES_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CIR:  %[[RESULT:.*]] = cir.load %[[RES_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CIR:  cir.return %[[RESULT]] : !s32i
+
+// LLVM: %[[A_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: %[[B_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: %[[RES_ADDR:.*]] = alloca i32, i64 1, align 4
+// LLVM: store i32 %{{.*}}, ptr %[[A_ADDR]], align 4
+// LLVM: store i32 %{{.*}}, ptr %[[B_ADDR]], align 4
+// LLVM: br label %[[CHECK_COND:.*]]
+// LLVM: [[CHECK_COND]]:
+// LLVM:  %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4
+// LLVM:  %[[IS_B_ZERO:.*]] = icmp eq i32 %[[TMP_B]], 0
+// LLVM:  br i1 %[[IS_B_ZERO]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+// LLVM: [[IF_THEN]]:
+// LLVM:  call void @__cxa_rethrow()
+// LLVM:  unreachable
+// LLVM: [[IF_ELSE]]:
+// LLVM:  br label %[[IF_END:.*]]
+// LLVM: [[IF_END]]:
+// LLVM:  %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// LLVM:  %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4
+// LLVM:  %[[DIV_A_B:.*]] = sdiv i32 %[[TMP_A]], %[[TMP_B]]
+// LLVM:  store i32 %[[DIV_A_B]], ptr %[[RES_ADDR]], align 4
+// LLVM:  %[[RESULT:.*]] = load i32, ptr %[[RES_ADDR]], align 4
+// LLVM:  ret i32 %[[RESULT]]
+
+// OGCG: %[[A_ADDR:.*]] = alloca i32, align 4
+// OGCG: %[[B_ADDR:.*]] = alloca i32, align 4
+// OGCG: store i32 %{{.*}}, ptr %[[A_ADDR]], align 4
+// OGCG: store i32 %{{.*}}, ptr %[[B_ADDR]], align 4
+// OGCG: %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4
+// OGCG: %[[IS_B_ZERO:.*]] = icmp eq i32 %[[TMP_B]], 0
+// OGCG: br i1 %[[IS_B_ZERO]], label %[[IF_THEN:.*]], label %[[IF_END:.*]]
+// OGCG: [[IF_THEN]]:
+// OGCG:  call void @__cxa_rethrow()
+// OGCG:  unreachable
+// OGCG: [[IF_END]]:
+// OGCG:  %[[TMP_A:.*]] = load i32, ptr %[[A_ADDR]], align 4
+// OGCG:  %[[TMP_B:.*]] = load i32, ptr %[[B_ADDR]], align 4
+// OGCG:  %[[DIV_A_B:.*]] = sdiv i32 %[[TMP_A]], %[[TMP_B]]
+// OGCG:  ret i32 %[[DIV_A_B]]
diff --git a/clang/test/CIR/IR/invalid-throw.cir 
b/clang/test/CIR/IR/invalid-throw.cir
new file mode 100644
index 0000000000000..53582a11b285e
--- /dev/null
+++ b/clang/test/CIR/IR/invalid-throw.cir
@@ -0,0 +1,16 @@
+// RUN: cir-opt %s -verify-diagnostics -split-input-file
+
+!s32i = !cir.int<s, 32>
+
+module {
+
+cir.func dso_local @throw_without_type_info() {
+    %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a"]
+    // expected-error @below {{'cir.throw' op 'type_info' symbol attribute 
missing}}
+    cir.throw %0 : !cir.ptr<!s32i>
+    cir.unreachable
+  ^bb1:
+    cir.return
+}
+
+}
diff --git a/clang/test/CIR/IR/throw.cir b/clang/test/CIR/IR/throw.cir
new file mode 100644
index 0000000000000..8b24b481057b1
--- /dev/null
+++ b/clang/test/CIR/IR/throw.cir
@@ -0,0 +1,63 @@
+// RUN: cir-opt %s | FileCheck %s
+
+!s32i = !cir.int<s, 32>
+
+module  {
+
+cir.func @throw_with_no_return() {
+  cir.throw
+  cir.unreachable
+}
+
+// CHECK: cir.func @throw_with_no_return() {
+// CHECK:  cir.throw
+// CHECK:  cir.unreachable
+// CHECK: }
+
+cir.func @throw_with_no_return_2(%arg0: !s32i, %arg1: !s32i) -> !s32i {
+  %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
+  %1 = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+  %2 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
+  cir.store %arg0, %0 : !s32i, !cir.ptr<!s32i>
+  cir.store %arg1, %1 : !s32i, !cir.ptr<!s32i>
+  cir.scope {
+    %7 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+    %8 = cir.const #cir.int<0> : !s32i
+    %9 = cir.cmp(eq, %7, %8) : !s32i, !cir.bool
+    cir.if %9 {
+      cir.throw
+      cir.unreachable
+    }
+  }
+  %3 = cir.load align(4) %0 : !cir.ptr<!s32i>, !s32i
+  %4 = cir.load align(4) %1 : !cir.ptr<!s32i>, !s32i
+  %5 = cir.binop(div, %3, %4) : !s32i
+  cir.store %5, %2 : !s32i, !cir.ptr<!s32i>
+  %6 = cir.load %2 : !cir.ptr<!s32i>, !s32i
+  cir.return %6 : !s32i
+}
+
+// CHECK: cir.func @throw_with_no_return_2(%[[ARG_0:.*]]: !s32i, 
%[[ARG_1:.*]]: !s32i) -> !s32i {
+// CHECK:  %[[A_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["a", init]
+// CHECK:  %[[B_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["b", init]
+// CHECK:  %[[RES_ADDR:.*]] = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"]
+// CHECK:  cir.store %[[ARG_0]], %[[A_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CHECK:  cir.store %[[ARG_1]], %[[B_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CHECK:  cir.scope {
+// CHECK:    %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, 
!s32i
+// CHECK:    %[[CONST_0:.*]] = cir.const #cir.int<0> : !s32i
+// CHECK:    %[[IS_B_ZERO:.*]] = cir.cmp(eq, %[[TMP_B]], %[[CONST_0]]) : 
!s32i, !cir.bool
+// CHECK:    cir.if %[[IS_B_ZERO]] {
+// CHECK:      cir.throw
+// CHECK:      cir.unreachable
+// CHECK:    }
+// CHECK:  }
+// CHECK:  %[[TMP_A:.*]] = cir.load{{.*}} %[[A_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CHECK:  %[[TMP_B:.*]] = cir.load{{.*}} %[[B_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CHECK:  %[[DIV_A_B:.*]] = cir.binop(div, %[[TMP_A:.*]], %[[TMP_B:.*]]) : 
!s32i
+// CHECK:  cir.store %[[DIV_A_B]], %[[RES_ADDR]] : !s32i, !cir.ptr<!s32i>
+// CHECK:  %[[RESULT:.*]] = cir.load %[[RES_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CHECK:  cir.return %[[RESULT]] : !s32i
+// CHECK: }
+
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to