Author: Amr Hesham Date: 2025-04-22T21:07:57+02:00 New Revision: 80872d7a32cd335a7964df95e9fbcdee43eb1ad4
URL: https://github.com/llvm/llvm-project/commit/80872d7a32cd335a7964df95e9fbcdee43eb1ad4 DIFF: https://github.com/llvm/llvm-project/commit/80872d7a32cd335a7964df95e9fbcdee43eb1ad4.diff LOG: [CIR] Upstream StackSave and StackRestoreOp (#136426) This change adds support for StackSave and StackRestoreOp as a preliminary patch of VLA support Added: clang/test/CIR/IR/stack-save-restore.cir clang/test/CIR/Lowering/stack-save-restore.cir Modified: clang/include/clang/CIR/Dialect/IR/CIROps.td clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h Removed: ################################################################################ diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 81b447f31feca..a8fc2e755b269 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -1489,6 +1489,50 @@ def CallOp : CIR_CallOpBase<"call", [NoRegionArguments]> { }]>]; } +//===----------------------------------------------------------------------===// +// StackSaveOp & StackRestoreOp +//===----------------------------------------------------------------------===// + +def StackSaveOp : CIR_Op<"stacksave"> { + let summary = "remembers the current state of the function stack"; + let description = [{ + Saves current state of the function stack. Returns a pointer to an opaque object + that later can be passed into cir.stackrestore. + This is used during the lowering of variable length array allocas. + + This operation corresponds to LLVM intrinsic `stacksave`. + + ```mlir + %0 = cir.stacksave : <!u8i> + ``` + }]; + + let results = (outs CIR_PointerType:$result); + let assemblyFormat = "attr-dict `:` qualified(type($result))"; +} + +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.stacksave executed. + This is used during the lowering of variable length array allocas. + + 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.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.stackrestore %2 : !cir.ptr<!u8i> + ``` + }]; + + let arguments = (ins CIR_PointerType:$ptr); + let assemblyFormat = "$ptr attr-dict `:` qualified(type($ptr))"; +} + //===----------------------------------------------------------------------===// // UnreachableOp //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 07d57862eacc8..f25eaea05cf10 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1553,6 +1553,8 @@ void ConvertCIRToLLVMPass::runOnOperation() { CIRToLLVMGetGlobalOpLowering, CIRToLLVMSelectOpLowering, CIRToLLVMShiftOpLowering, + CIRToLLVMStackSaveOpLowering, + CIRToLLVMStackRestoreOpLowering, CIRToLLVMTrapOpLowering, CIRToLLVMUnaryOpLowering // clang-format on @@ -1598,6 +1600,21 @@ 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.getPtr()); + 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 acb872b200b55..91329523c3b0f 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -262,6 +262,27 @@ 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..f98889ac1083a --- /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.stacksave : !cir.ptr<!u8i> + cir.stackrestore %0 : !cir.ptr<!u8i> + cir.return + } +} + +//CHECK: module { + +//CHECK-NEXT: cir.func @stack_save_restore() { +//CHECK-NEXT: %0 = cir.stacksave : !cir.ptr<!u8i> +//CHECK-NEXT: cir.stackrestore %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..9e30081e3f477 --- /dev/null +++ b/clang/test/CIR/Lowering/stack-save-restore.cir @@ -0,0 +1,26 @@ +// 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> + +module { + cir.func @stack_save() { + %0 = cir.stacksave : !cir.ptr<!u8i> + cir.stackrestore %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: } + +// 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