Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -4698,6 +4698,26 @@ def CIR_EhTypeIdOp : CIR_Op<"eh.typeid",
}];
}

def CIR_EhSetjmp : CIR_Op<"eh.setjmp"> {
let summary = "CIR setjmp operation";
let description = [{
"Saves various information about the calling
environment (typically, the stack pointer, the instruction
pointer, possibly the values of other registers and the signal
mask) in the buffer env for later use by longjmp(). In this case,
setjmp() returns 0. When retuned from a longjmp(), setjmp returns the
value passed into longjmp()."
}];

let arguments = (ins CIR_PointerType:$buf, UnitAttr:$builtin);
let results = (outs CIR_SInt32:$res);
let assemblyFormat = [{
$buf `:` type($buf)
(`,` `builtin` $builtin^)?
`->` type(results) attr-dict
}];
}

//===----------------------------------------------------------------------===//
// CopyOp
//===----------------------------------------------------------------------===//
Expand Down
22 changes: 22 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4288,6 +4288,27 @@ mlir::LogicalResult CIRToLLVMEhTypeIdOpLowering::matchAndRewrite(
return mlir::success();
}

mlir::LogicalResult CIRToLLVMEhSjljSetjmpOpLowering::matchAndRewrite(
cir::EhSetjmp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
mlir::Type returnType = typeConverter->convertType(op.getType());
if (op.getBuiltinAttr()) {
mlir::LLVM::CallIntrinsicOp newOp =
createCallLLVMIntrinsicOp(rewriter, op.getLoc(), "llvm.eh.sjlj.setjmp",
returnType, adaptor.getBuf());
rewriter.replaceOp(op, newOp);
} else {
StringRef fnName = "_setjmp";
auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext());
auto fnType = mlir::LLVM::LLVMFunctionType::get(returnType, llvmPtrTy,
/*isVarArg=*/false);
getOrCreateLLVMFuncOp(rewriter, op, fnName, fnType);
rewriter.replaceOpWithNewOp<mlir::LLVM::CallOp>(op, returnType, fnName,
adaptor.getBuf());
}
return mlir::success();
}

mlir::LogicalResult CIRToLLVMCatchParamOpLowering::matchAndRewrite(
cir::CatchParamOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
Expand Down Expand Up @@ -4531,6 +4552,7 @@ void populateCIRToLLVMConversionPatterns(
CIRToLLVMDerivedClassAddrOpLowering,
CIRToLLVMEhInflightOpLowering,
CIRToLLVMEhTypeIdOpLowering,
CIRToLLVMEhSjljSetjmpOpLowering,
CIRToLLVMExpectOpLowering,
CIRToLLVMExtractMemberOpLowering,
CIRToLLVMFrameAddrOpLowering,
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,16 @@ class CIRToLLVMEhTypeIdOpLowering
mlir::ConversionPatternRewriter &) const override;
};

class CIRToLLVMEhSjljSetjmpOpLowering
: public mlir::OpConversionPattern<cir::EhSetjmp> {
public:
using mlir::OpConversionPattern<cir::EhSetjmp>::OpConversionPattern;

mlir::LogicalResult
matchAndRewrite(cir::EhSetjmp op, OpAdaptor,
mlir::ConversionPatternRewriter &) const override;
};

class CIRToLLVMCatchParamOpLowering
: public mlir::OpConversionPattern<cir::CatchParamOp> {
public:
Expand Down
28 changes: 28 additions & 0 deletions clang/test/CIR/Lowering/setjmp-longjmp.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// RUN: cir-opt %s -cir-to-llvm -o %t.ll
// RUN: FileCheck %s --input-file=%t.ll -check-prefix=MLIR
!s32i = !cir.int<s, 32>
!p32 = !cir.ptr<!s32i>

module {
// MLIR: module {
cir.func @test_setjmp(%arg0 : !p32) -> !s32i {

// MLIR: llvm.func @test_setjmp([[ARG0:%.*]]: !llvm.ptr) -> i32
// MLIR-NEXT: [[RET:%.*]] = llvm.call_intrinsic "llvm.eh.sjlj.setjmp"([[ARG0]]) : (!llvm.ptr) -> i32
// MLIR-NEXT: llvm.return [[RET:%.*]] : i32
// MLIR-NEXT: }
%0 = cir.eh.setjmp %arg0 : !p32, builtin -> !s32i
cir.return %0 : !s32i
}
cir.func @test_setjmp_2(%arg0 : !p32) -> !s32i {

// MLIR: llvm.func @test_setjmp_2([[ARG0:%.*]]: !llvm.ptr) -> i32
// MLIR-NEXT: [[RET:%.*]] = llvm.call @_setjmp([[ARG0]]) : (!llvm.ptr) -> i32
// MLIR-NEXT: llvm.return [[RET:%.*]] : i32
// MLIR-NEXT: }
%0 = cir.eh.setjmp %arg0 : !p32 -> !s32i
cir.return %0 : !s32i
}
// MLIR: }
}

Loading