Skip to content

Commit 5b631e9

Browse files
yotto3stoyoyou11
authored andcommitted
[CIR] Add EhLongjmpOp to CIR dialect (#1920)
PR for #1791 --------- Co-authored-by: yotto3s <[email protected]>
1 parent 1b8211d commit 5b631e9

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
@@ -4832,6 +4832,26 @@ def CIR_EhSetjmpOp : CIR_Op<"eh.setjmp"> {
48324832
}];
48334833
}
48344834

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

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
@@ -4533,6 +4533,14 @@ mlir::LogicalResult CIRToLLVMEhSetjmpOpLowering::matchAndRewrite(
45334533
return mlir::success();
45344534
}
45354535

4536+
mlir::LogicalResult CIRToLLVMEhLongjmpOpLowering::matchAndRewrite(
4537+
cir::EhLongjmpOp op, OpAdaptor adaptor,
4538+
mlir::ConversionPatternRewriter &rewriter) const {
4539+
replaceOpWithCallLLVMIntrinsicOp(rewriter, op, "llvm.eh.sjlj.longjmp",
4540+
/*resultTy=*/{}, adaptor.getOperands());
4541+
return mlir::success();
4542+
}
4543+
45364544
mlir::LogicalResult CIRToLLVMCatchParamOpLowering::matchAndRewrite(
45374545
cir::CatchParamOp op, OpAdaptor adaptor,
45384546
mlir::ConversionPatternRewriter &rewriter) const {
@@ -4873,6 +4881,7 @@ void populateCIRToLLVMConversionPatterns(
48734881
CIRToLLVMEhInflightOpLowering,
48744882
CIRToLLVMEhTypeIdOpLowering,
48754883
CIRToLLVMEhSetjmpOpLowering,
4884+
CIRToLLVMEhLongjmpOpLowering,
48764885
CIRToLLVMExpectOpLowering,
48774886
CIRToLLVMExtractMemberOpLowering,
48784887
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)