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

>From 91a6937c7b937daceef426c877703d4d0cfeae76 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Sat, 19 Apr 2025 14:22:45 +0200
Subject: [PATCH 1/4] [CIR] Upstream StackSave and StackRestoreOp

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td  | 42 +++++++++++++++++++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 18 ++++++++
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 20 +++++++++
 clang/test/CIR/IR/stack-save-restore.cir      | 23 ++++++++++
 .../test/CIR/Lowering/stack-save-restore.cir  | 19 +++++++++
 5 files changed, 122 insertions(+)
 create mode 100644 clang/test/CIR/IR/stack-save-restore.cir
 create mode 100644 clang/test/CIR/Lowering/stack-save-restore.cir

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 5ba4b33dc1a12..2b48aac97e7ef 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1419,6 +1419,48 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> 
{
     }]>];
 }
 
+//===----------------------------------------------------------------------===//
+// StackSave & StackRestoreOp
+//===----------------------------------------------------------------------===//
+
+def StackSaveOp : CIR_Op<"stack_save"> {
+  let summary = "remembers the current state of the function stack";
+  let description = [{
+    Remembers the current state of the function stack. Returns a pointer
+    that later can be passed into cir.stack_restore.
+    Useful for implementing language features like variable length arrays.
+
+    ```mlir
+    %0 = cir.stack_save : <!u8i>
+    ```
+  }];
+
+  let results = (outs CIR_PointerType:$result);
+  let assemblyFormat = "attr-dict `:` qualified(type($result))";
+}
+
+def StackRestoreOp : CIR_Op<"stack_restore"> {
+  let summary = "restores the state of the function stack";
+  let description = [{
+    Restore the state of the function stack to the state it was
+    in when the corresponding cir.stack_save executed.
+    Useful for implementing language features like variable length arrays.
+
+    ```mlir
+    %0 = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] 
{alignment = 8 : i64}
+    %1 = cir.stack_save : <!u8i>
+    cir.store %1, %0 : !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>
+    %2 = cir.load %0 : !cir.ptr<!cir.ptr<!u8i>>, !cir.ptr<!u8i>
+    cir.stack_restore %2 : !cir.ptr<!u8i>
+    ```
+  }];
+
+  let arguments = (ins CIR_PointerType:$ptr);
+  let assemblyFormat = "$ptr attr-dict `:` qualified(type($ptr))";
+
+  let llvmOp = "StackRestoreOp";
+}
+
 
//===----------------------------------------------------------------------===//
 // UnreachableOp
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 8c4a67258df3f..0673b1543d91e 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1467,6 +1467,8 @@ void ConvertCIRToLLVMPass::runOnOperation() {
                CIRToLLVMConstantOpLowering,
                CIRToLLVMFuncOpLowering,
                CIRToLLVMGetGlobalOpLowering,
+               CIRToLLVMStackSaveOpLowering,
+               CIRToLLVMStackRestoreOpLowering,
                CIRToLLVMTrapOpLowering,
                CIRToLLVMUnaryOpLowering
       // clang-format on
@@ -1512,6 +1514,22 @@ mlir::LogicalResult 
CIRToLLVMTrapOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
+mlir::LogicalResult CIRToLLVMStackSaveOpLowering::matchAndRewrite(
+    cir::StackSaveOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  const mlir::Type ptrTy = getTypeConverter()->convertType(op.getType());
+  rewriter.replaceOpWithNewOp<mlir::LLVM::StackSaveOp>(op, ptrTy);
+  return mlir::success();
+}
+
+mlir::LogicalResult CIRToLLVMStackRestoreOpLowering::matchAndRewrite(
+    cir::StackRestoreOp op, OpAdaptor adaptor,
+    mlir::ConversionPatternRewriter &rewriter) const {
+  rewriter.replaceOpWithNewOp<mlir::LLVM::StackRestoreOp>(
+      op, adaptor.getOperands().front());
+  return mlir::success();
+}
+
 std::unique_ptr<mlir::Pass> createConvertCIRToLLVMPass() {
   return std::make_unique<ConvertCIRToLLVMPass>();
 }
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
index 1de6c9c56b485..a7c2704e13fe6 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
@@ -242,6 +242,26 @@ class CIRToLLVMPtrStrideOpLowering
   matchAndRewrite(cir::PtrStrideOp op, OpAdaptor,
                   mlir::ConversionPatternRewriter &) const override;
 };
+
+class CIRToLLVMStackSaveOpLowering
+    : public mlir::OpConversionPattern<cir::StackSaveOp> {
+public:
+  using mlir::OpConversionPattern<cir::StackSaveOp>::OpConversionPattern;
+  mlir::LogicalResult
+  matchAndRewrite(cir::StackSaveOp op, OpAdaptor,
+                  mlir::ConversionPatternRewriter &) const override;
+};
+
+class CIRToLLVMStackRestoreOpLowering
+    : public mlir::OpConversionPattern<cir::StackRestoreOp> {
+public:
+  using OpConversionPattern<cir::StackRestoreOp>::OpConversionPattern;
+
+  mlir::LogicalResult
+  matchAndRewrite(cir::StackRestoreOp op, OpAdaptor adaptor,
+                  mlir::ConversionPatternRewriter &rewriter) const override;
+};
+
 } // namespace direct
 } // namespace cir
 
diff --git a/clang/test/CIR/IR/stack-save-restore.cir 
b/clang/test/CIR/IR/stack-save-restore.cir
new file mode 100644
index 0000000000000..f6027258786df
--- /dev/null
+++ b/clang/test/CIR/IR/stack-save-restore.cir
@@ -0,0 +1,23 @@
+// Test the CIR operations can parse and print correctly (roundtrip)
+
+// RUN: cir-opt %s | cir-opt | FileCheck %s
+
+!u8i = !cir.int<u, 8>
+
+module  {
+  cir.func @stack_save_restore() {
+    %0 = cir.stack_save : !cir.ptr<!u8i>
+    cir.stack_restore %0 : !cir.ptr<!u8i>
+    cir.return
+  }
+}
+
+//CHECK: module  {
+
+//CHECK-NEXT: cir.func @stack_save_restore() {
+//CHECK-NEXT:   %0 = cir.stack_save : !cir.ptr<!u8i>
+//CHECK-NEXT:   cir.stack_restore %0 : !cir.ptr<!u8i>
+//CHECK-NEXT:   cir.return
+//CHECK-NEXT: }
+
+//CHECK-NEXT: }
diff --git a/clang/test/CIR/Lowering/stack-save-restore.cir 
b/clang/test/CIR/Lowering/stack-save-restore.cir
new file mode 100644
index 0000000000000..ad9dee66b53f5
--- /dev/null
+++ b/clang/test/CIR/Lowering/stack-save-restore.cir
@@ -0,0 +1,19 @@
+// RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s -check-prefix=MLIR
+
+!u8i = !cir.int<u, 8>
+
+module  {
+  cir.func @stack_save() {
+    %0 = cir.stack_save : !cir.ptr<!u8i>
+    cir.stack_restore %0 : !cir.ptr<!u8i>
+    cir.return
+  }
+}
+
+//      MLIR: module {
+// MLIR-NEXT:  llvm.func @stack_save
+// MLIR-NEXT:    %0 = llvm.intr.stacksave : !llvm.ptr
+// MLIR-NEXT:    llvm.intr.stackrestore %0 : !llvm.ptr
+// MLIR-NEXT:    llvm.return
+// MLIR-NEXT:  }
+// MLIR-NEXT: }

>From 015a2a94eae37a4138557ea6e2457c8cf394ba0c Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Mon, 21 Apr 2025 12:21:50 +0200
Subject: [PATCH 2/4] Address code review comments

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td        | 6 ++++--
 clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 3 +--
 clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h   | 1 +
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 2b48aac97e7ef..eaad0386852c4 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1430,6 +1430,8 @@ def StackSaveOp : CIR_Op<"stack_save"> {
     that later can be passed into cir.stack_restore.
     Useful for implementing language features like variable length arrays.
 
+    This operation is correspond to LLVM intrinsic `stacksave`.
+
     ```mlir
     %0 = cir.stack_save : <!u8i>
     ```
@@ -1446,6 +1448,8 @@ def StackRestoreOp : CIR_Op<"stack_restore"> {
     in when the corresponding cir.stack_save executed.
     Useful for implementing language features like variable length arrays.
 
+    This operation is correspond to LLVM intrinsic `stackrestore`.
+
     ```mlir
     %0 = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] 
{alignment = 8 : i64}
     %1 = cir.stack_save : <!u8i>
@@ -1457,8 +1461,6 @@ def StackRestoreOp : CIR_Op<"stack_restore"> {
 
   let arguments = (ins CIR_PointerType:$ptr);
   let assemblyFormat = "$ptr attr-dict `:` qualified(type($ptr))";
-
-  let llvmOp = "StackRestoreOp";
 }
 
 
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 0673b1543d91e..e0b00865f9a80 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1525,8 +1525,7 @@ mlir::LogicalResult 
CIRToLLVMStackSaveOpLowering::matchAndRewrite(
 mlir::LogicalResult CIRToLLVMStackRestoreOpLowering::matchAndRewrite(
     cir::StackRestoreOp op, OpAdaptor adaptor,
     mlir::ConversionPatternRewriter &rewriter) const {
-  rewriter.replaceOpWithNewOp<mlir::LLVM::StackRestoreOp>(
-      op, adaptor.getOperands().front());
+  rewriter.replaceOpWithNewOp<mlir::LLVM::StackRestoreOp>(op, 
adaptor.getPtr());
   return mlir::success();
 }
 
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
index a7c2704e13fe6..37c73502608e7 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
@@ -247,6 +247,7 @@ class CIRToLLVMStackSaveOpLowering
     : public mlir::OpConversionPattern<cir::StackSaveOp> {
 public:
   using mlir::OpConversionPattern<cir::StackSaveOp>::OpConversionPattern;
+
   mlir::LogicalResult
   matchAndRewrite(cir::StackSaveOp op, OpAdaptor,
                   mlir::ConversionPatternRewriter &) const override;

>From 88ffbd9e27fc19543e87cfae47a276d9f1945508 Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Mon, 21 Apr 2025 20:16:13 +0200
Subject: [PATCH 3/4] Update stack operations names

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td   | 18 +++++++++---------
 clang/test/CIR/IR/stack-save-restore.cir       |  8 ++++----
 clang/test/CIR/Lowering/stack-save-restore.cir |  4 ++--
 3 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index eaad0386852c4..a0aa31d82d973 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1423,17 +1423,17 @@ def CallOp : CIR_CallOpBase<"call", 
[NoRegionArguments]> {
 // StackSave & StackRestoreOp
 
//===----------------------------------------------------------------------===//
 
-def StackSaveOp : CIR_Op<"stack_save"> {
+def StackSaveOp : CIR_Op<"stacksave"> {
   let summary = "remembers the current state of the function stack";
   let description = [{
     Remembers the current state of the function stack. Returns a pointer
-    that later can be passed into cir.stack_restore.
+    that later can be passed into cir.stackrestore.
     Useful for implementing language features like variable length arrays.
 
-    This operation is correspond to LLVM intrinsic `stacksave`.
+    This operation corresponds to LLVM intrinsic `stacksave`.
 
     ```mlir
-    %0 = cir.stack_save : <!u8i>
+    %0 = cir.stacksave : <!u8i>
     ```
   }];
 
@@ -1441,21 +1441,21 @@ def StackSaveOp : CIR_Op<"stack_save"> {
   let assemblyFormat = "attr-dict `:` qualified(type($result))";
 }
 
-def StackRestoreOp : CIR_Op<"stack_restore"> {
+def StackRestoreOp : CIR_Op<"stackrestore"> {
   let summary = "restores the state of the function stack";
   let description = [{
     Restore the state of the function stack to the state it was
-    in when the corresponding cir.stack_save executed.
+    in when the corresponding cir.stacksave executed.
     Useful for implementing language features like variable length arrays.
 
-    This operation is correspond to LLVM intrinsic `stackrestore`.
+    This operation corresponds to LLVM intrinsic `stackrestore`.
 
     ```mlir
     %0 = cir.alloca !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>, ["saved_stack"] 
{alignment = 8 : i64}
-    %1 = cir.stack_save : <!u8i>
+    %1 = cir.stacksave : <!u8i>
     cir.store %1, %0 : !cir.ptr<!u8i>, !cir.ptr<!cir.ptr<!u8i>>
     %2 = cir.load %0 : !cir.ptr<!cir.ptr<!u8i>>, !cir.ptr<!u8i>
-    cir.stack_restore %2 : !cir.ptr<!u8i>
+    cir.stackrestore %2 : !cir.ptr<!u8i>
     ```
   }];
 
diff --git a/clang/test/CIR/IR/stack-save-restore.cir 
b/clang/test/CIR/IR/stack-save-restore.cir
index f6027258786df..f98889ac1083a 100644
--- a/clang/test/CIR/IR/stack-save-restore.cir
+++ b/clang/test/CIR/IR/stack-save-restore.cir
@@ -6,8 +6,8 @@
 
 module  {
   cir.func @stack_save_restore() {
-    %0 = cir.stack_save : !cir.ptr<!u8i>
-    cir.stack_restore %0 : !cir.ptr<!u8i>
+    %0 = cir.stacksave : !cir.ptr<!u8i>
+    cir.stackrestore %0 : !cir.ptr<!u8i>
     cir.return
   }
 }
@@ -15,8 +15,8 @@ module  {
 //CHECK: module  {
 
 //CHECK-NEXT: cir.func @stack_save_restore() {
-//CHECK-NEXT:   %0 = cir.stack_save : !cir.ptr<!u8i>
-//CHECK-NEXT:   cir.stack_restore %0 : !cir.ptr<!u8i>
+//CHECK-NEXT:   %0 = cir.stacksave : !cir.ptr<!u8i>
+//CHECK-NEXT:   cir.stackrestore %0 : !cir.ptr<!u8i>
 //CHECK-NEXT:   cir.return
 //CHECK-NEXT: }
 
diff --git a/clang/test/CIR/Lowering/stack-save-restore.cir 
b/clang/test/CIR/Lowering/stack-save-restore.cir
index ad9dee66b53f5..10c04918d2650 100644
--- a/clang/test/CIR/Lowering/stack-save-restore.cir
+++ b/clang/test/CIR/Lowering/stack-save-restore.cir
@@ -4,8 +4,8 @@
 
 module  {
   cir.func @stack_save() {
-    %0 = cir.stack_save : !cir.ptr<!u8i>
-    cir.stack_restore %0 : !cir.ptr<!u8i>
+    %0 = cir.stacksave : !cir.ptr<!u8i>
+    cir.stackrestore %0 : !cir.ptr<!u8i>
     cir.return
   }
 }

>From bb865d2b1ec562b544ab5667c9e9fe0a43b88c0a Mon Sep 17 00:00:00 2001
From: AmrDeveloper <am...@programmer.net>
Date: Mon, 21 Apr 2025 21:51:56 +0200
Subject: [PATCH 4/4] Add run line for lower to LLVM IR

---
 clang/include/clang/CIR/Dialect/IR/CIROps.td   | 8 ++++----
 clang/test/CIR/Lowering/stack-save-restore.cir | 7 +++++++
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index a0aa31d82d973..ffbe583fed2d3 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1420,15 +1420,15 @@ def CallOp : CIR_CallOpBase<"call", 
[NoRegionArguments]> {
 }
 
 
//===----------------------------------------------------------------------===//
-// StackSave & StackRestoreOp
+// StackSaveOp & StackRestoreOp
 
//===----------------------------------------------------------------------===//
 
 def StackSaveOp : CIR_Op<"stacksave"> {
   let summary = "remembers the current state of the function stack";
   let description = [{
-    Remembers the current state of the function stack. Returns a pointer
+    Saves current state of the function stack. Returns a pointer to an opaque 
object
     that later can be passed into cir.stackrestore.
-    Useful for implementing language features like variable length arrays.
+    This is used during the lowering of variable length array allocas.
 
     This operation corresponds to LLVM intrinsic `stacksave`.
 
@@ -1446,7 +1446,7 @@ def StackRestoreOp : CIR_Op<"stackrestore"> {
   let description = [{
     Restore the state of the function stack to the state it was
     in when the corresponding cir.stacksave executed.
-    Useful for implementing language features like variable length arrays.
+    This is used during the lowering of variable length array allocas.
 
     This operation corresponds to LLVM intrinsic `stackrestore`.
 
diff --git a/clang/test/CIR/Lowering/stack-save-restore.cir 
b/clang/test/CIR/Lowering/stack-save-restore.cir
index 10c04918d2650..9e30081e3f477 100644
--- a/clang/test/CIR/Lowering/stack-save-restore.cir
+++ b/clang/test/CIR/Lowering/stack-save-restore.cir
@@ -1,4 +1,5 @@
 // RUN: cir-opt %s -cir-to-llvm -o - | FileCheck %s -check-prefix=MLIR
+// RUN: cir-opt %s -cir-to-llvm -o - | mlir-translate -mlir-to-llvmir | 
FileCheck %s -check-prefix=LLVM
 
 !u8i = !cir.int<u, 8>
 
@@ -17,3 +18,9 @@ module  {
 // MLIR-NEXT:    llvm.return
 // MLIR-NEXT:  }
 // MLIR-NEXT: }
+
+// LLVM: define void @stack_save() {
+// LLVM:  %1 = call ptr @llvm.stacksave.p0()
+// LLVM:  call void @llvm.stackrestore.p0(ptr %1)
+// LLVM:  ret void
+// LLVM: }

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

Reply via email to