Skip to content

Commit 00f4889

Browse files
yotto3stoyoyou11
andauthored
[CIR] Add EhLongjmpOp to CIR dialect (#1920)
PR for #1791 --------- Co-authored-by: yotto3s <[email protected]>
1 parent 0e5f373 commit 00f4889

File tree

7 files changed

+97
-2
lines changed

7 files changed

+97
-2
lines changed

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4835,6 +4835,26 @@ def CIR_EhSetjmpOp : CIR_Op<"eh.setjmp"> {
48354835
}];
48364836
}
48374837

4838+
def CIR_EhLongjmpOp : CIR_Op<"eh.longjmp"> {
4839+
let summary = "CIR longjmp operation";
4840+
let description = [{
4841+
Restore the environment (e.g., stack pointer, instruction pointer,
4842+
signal mask, and other registers) at the time of setjmp() call, by using
4843+
the information saved in `env` by setjmp().
4844+
4845+
Examples:
4846+
```mlir
4847+
cir.eh.longjmp %arg0 : !cir.ptr<!cir.void>
4848+
```
4849+
}];
4850+
4851+
let arguments = (ins CIR_PointerType:$env);
4852+
4853+
let assemblyFormat = [{
4854+
$env `:` qualified(type($env)) attr-dict
4855+
}];
4856+
}
4857+
48384858
//===----------------------------------------------------------------------===//
48394859
// CopyOp
48404860
//===----------------------------------------------------------------------===//

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1963,8 +1963,14 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
19631963
cir::EhSetjmpOp::create(builder, loc, castBuf, /*is_builtin=*/true);
19641964
return RValue::get(op);
19651965
}
1966-
case Builtin::BI__builtin_longjmp:
1967-
llvm_unreachable("BI__builtin_longjmp NYI");
1966+
case Builtin::BI__builtin_longjmp: {
1967+
mlir::Value buf = emitScalarExpr(E->getArg(0));
1968+
mlir::Location loc = getLoc(E->getExprLoc());
1969+
1970+
cir::EhLongjmpOp::create(builder, loc, buf);
1971+
builder.create<cir::UnreachableOp>(loc);
1972+
return RValue::get(nullptr);
1973+
}
19681974
case Builtin::BI__builtin_launder: {
19691975
const clang::Expr *arg = E->getArg(0);
19701976
clang::QualType argTy = arg->getType()->getPointeeType();

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4364,6 +4364,14 @@ mlir::LogicalResult CIRToLLVMEhSetjmpOpLowering::matchAndRewrite(
43644364
return mlir::success();
43654365
}
43664366

4367+
mlir::LogicalResult CIRToLLVMEhLongjmpOpLowering::matchAndRewrite(
4368+
cir::EhLongjmpOp op, OpAdaptor adaptor,
4369+
mlir::ConversionPatternRewriter &rewriter) const {
4370+
replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.eh.sjlj.longjmp",
4371+
/*resultTy=*/{}, adaptor.getOperands());
4372+
return mlir::success();
4373+
}
4374+
43674375
mlir::LogicalResult CIRToLLVMCatchParamOpLowering::matchAndRewrite(
43684376
cir::CatchParamOp op, OpAdaptor adaptor,
43694377
mlir::ConversionPatternRewriter &rewriter) const {
@@ -4704,6 +4712,7 @@ void populateCIRToLLVMConversionPatterns(
47044712
CIRToLLVMEhInflightOpLowering,
47054713
CIRToLLVMEhTypeIdOpLowering,
47064714
CIRToLLVMEhSetjmpOpLowering,
4715+
CIRToLLVMEhLongjmpOpLowering,
47074716
CIRToLLVMExpectOpLowering,
47084717
CIRToLLVMExtractMemberOpLowering,
47094718
CIRToLLVMFrameAddrOpLowering,

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,16 @@ class CIRToLLVMEhSetjmpOpLowering
12931293
mlir::ConversionPatternRewriter &) const override;
12941294
};
12951295

1296+
class CIRToLLVMEhLongjmpOpLowering
1297+
: public mlir::OpConversionPattern<cir::EhLongjmpOp> {
1298+
public:
1299+
using mlir::OpConversionPattern<cir::EhLongjmpOp>::OpConversionPattern;
1300+
1301+
mlir::LogicalResult
1302+
matchAndRewrite(cir::EhLongjmpOp op, OpAdaptor,
1303+
mlir::ConversionPatternRewriter &) const override;
1304+
};
1305+
12961306
class CIRToLLVMCatchParamOpLowering
12971307
: public mlir::OpConversionPattern<cir::CatchParamOp> {
12981308
public:

clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,24 @@ void test_setjmp2(void *env) {
6161
// OGCG: call i32 @_setjmp(ptr noundef [[ENV]])
6262
_setjmp (env);
6363
}
64+
65+
void test_longjmp(void *env) {
66+
// CIR-LABEL: test_longjmp
67+
// CIR-SAME: [[ENV:%.*]]:
68+
// CIR-NEXT: [[ENV_ALLOCA:%[0-9]+]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>,
69+
// CIR-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
70+
// CIR-NEXT: [[ENV_LOAD:%[0-9]+]] = cir.load align(8) [[ENV_ALLOCA]]
71+
// CIR-NEXT: [[CAST:%[0-9]+]] = cir.cast bitcast [[ENV_LOAD]] : !cir.ptr<!void> -> !cir.ptr<!cir.ptr<!void>>
72+
// CIR-NEXT: cir.eh.longjmp [[CAST]] : !cir.ptr<!cir.ptr<!void>>
73+
// CIR-NEXT: cir.unreachable
74+
75+
76+
// LLVM-LABEL: test_longjmp
77+
// LLVM: @llvm.eh.sjlj.longjmp
78+
// LLVM-NEXT: unreachable
79+
80+
// OGCG-LABEL: test_longjmp
81+
// OGCG: @llvm.eh.sjlj.longjmp
82+
// OGCG-NEXT: unreachable
83+
__builtin_longjmp(env, 1);
84+
}

clang/test/CIR/Lowering/setjmp-longjmp.cir

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ module {
2323
%0 = cir.eh.setjmp %arg0 : (!p32) -> !s32i
2424
cir.return %0 : !s32i
2525
}
26+
cir.func @test_longjmp(%arg0 : !p32) {
27+
28+
// MLIR: llvm.func @test_longjmp([[ARG0:%.*]]: !llvm.ptr)
29+
// MLIR-NEXT: llvm.call_intrinsic "llvm.eh.sjlj.longjmp"([[ARG0]]) : (!llvm.ptr) -> ()
30+
// MLIR-NEXT: llvm.unreachable
31+
// MLIR-NEXT: }
32+
cir.eh.longjmp %arg0 : !p32
33+
cir.unreachable
34+
}
2635
// MLIR: }
2736
}
2837

clang/test/CIR/Transforms/setjmp-longjmp-lower.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,23 @@ void test_setjmp2(void *env) {
5252
// AFTER-LOWERING-PREPARE-NEXT: cir.eh.setjmp [[CAST]] : (!cir.ptr<!cir.ptr<!void>>) -> !s32i
5353
_setjmp (env);
5454
}
55+
void test_longjmp(void *env) {
56+
// BEFORE-LOWERING-PREPARE-LABEL: test_longjmp
57+
// BEFORE-LOWERING-PREPARE-SAME: [[ENV:%.*]]:
58+
// BEFORE-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca
59+
// BEFORE-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]]
60+
// BEFORE-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]]
61+
// BEFORE-LOWERING-PREPARE-NEXT: [[CAST:%.*]] = cir.cast bitcast [[ENV_LOAD]]
62+
// BEFORE-LOWERING-PREPARE-NEXT: cir.eh.longjmp [[CAST]] : !cir.ptr<!cir.ptr<!void>>
63+
// BEFORE-LOWERING-PREPARE-NEXT: cir.unreachable
64+
65+
// AFTER-LOWERING-PREPARE-LABEL: test_longjmp
66+
// AFTER-LOWERING-PREPARE-SAME: [[ENV:%.*]]:
67+
// AFTER-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca
68+
// AFTER-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]]
69+
// AFTER-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]]
70+
// AFTER-LOWERING-PREPARE-NEXT: [[CAST:%.*]] = cir.cast bitcast [[ENV_LOAD]]
71+
// AFTER-LOWERING-PREPARE-NEXT: cir.eh.longjmp [[CAST]] : !cir.ptr<!cir.ptr<!void>>
72+
// AFTER-LOWERING-PREPARE-NEXT: cir.unreachable
73+
__builtin_longjmp(env, 1);
74+
}

0 commit comments

Comments
 (0)