From b691563d2c04c9ccda53cc2c5293e264c42e9d30 Mon Sep 17 00:00:00 2001 From: Jasmine Tang Date: Fri, 22 Aug 2025 11:53:21 -0700 Subject: [PATCH 1/7] Add dedicated CIR op for setjmp --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 20 +++++++++++++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 22 +++++++++++++++ .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h | 10 +++++++ clang/test/CIR/Lowering/setjmp-longjmp.cir | 28 +++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 clang/test/CIR/Lowering/setjmp-longjmp.cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index aacb945cd9f8..407502bc1189 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -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 //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 0a7b82ba447b..8d55b618eb57 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -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(op, returnType, fnName, + adaptor.getBuf()); + } + return mlir::success(); +} + mlir::LogicalResult CIRToLLVMCatchParamOpLowering::matchAndRewrite( cir::CatchParamOp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { @@ -4531,6 +4552,7 @@ void populateCIRToLLVMConversionPatterns( CIRToLLVMDerivedClassAddrOpLowering, CIRToLLVMEhInflightOpLowering, CIRToLLVMEhTypeIdOpLowering, + CIRToLLVMEhSjljSetjmpOpLowering, CIRToLLVMExpectOpLowering, CIRToLLVMExtractMemberOpLowering, CIRToLLVMFrameAddrOpLowering, diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index 01bc7c12be6e..f8e7a42833f8 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -1220,6 +1220,16 @@ class CIRToLLVMEhTypeIdOpLowering mlir::ConversionPatternRewriter &) const override; }; +class CIRToLLVMEhSjljSetjmpOpLowering + : public mlir::OpConversionPattern { +public: + using mlir::OpConversionPattern::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(cir::EhSetjmp op, OpAdaptor, + mlir::ConversionPatternRewriter &) const override; +}; + class CIRToLLVMCatchParamOpLowering : public mlir::OpConversionPattern { public: diff --git a/clang/test/CIR/Lowering/setjmp-longjmp.cir b/clang/test/CIR/Lowering/setjmp-longjmp.cir new file mode 100644 index 000000000000..30ced34ede96 --- /dev/null +++ b/clang/test/CIR/Lowering/setjmp-longjmp.cir @@ -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 +!p32 = !cir.ptr + +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: } +} + From 25d4a91ae72ba29a5138f6dffb04a26805702ae1 Mon Sep 17 00:00:00 2001 From: Jasmine Tang Date: Tue, 26 Aug 2025 11:40:05 -0700 Subject: [PATCH 2/7] Added prepare lowering test, add new docs --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 21 +++++--- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 4 +- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.h | 2 +- .../CIR/Transforms/setjmp-longjmp-lower.c | 54 +++++++++++++++++++ 4 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 clang/test/CIR/Transforms/setjmp-longjmp-lower.c diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 407502bc1189..6cd183d279b7 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4701,12 +4701,21 @@ 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()." + 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(). + + Examples: + ```mlir + // Specify setjmp is builtin + %0 = cir.eh.setjmp %arg0 : !p32, builtin -> !s32i + + // Specify setjmp is not builtin + %0 = cir.eh.setjmp %arg0 : !p32 -> !s32i + ``` }]; let arguments = (ins CIR_PointerType:$buf, UnitAttr:$builtin); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 8d55b618eb57..59b18861ee36 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -4288,7 +4288,7 @@ mlir::LogicalResult CIRToLLVMEhTypeIdOpLowering::matchAndRewrite( return mlir::success(); } -mlir::LogicalResult CIRToLLVMEhSjljSetjmpOpLowering::matchAndRewrite( +mlir::LogicalResult CIRToLLVMEhSetjmpOpLowering::matchAndRewrite( cir::EhSetjmp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { mlir::Type returnType = typeConverter->convertType(op.getType()); @@ -4552,7 +4552,7 @@ void populateCIRToLLVMConversionPatterns( CIRToLLVMDerivedClassAddrOpLowering, CIRToLLVMEhInflightOpLowering, CIRToLLVMEhTypeIdOpLowering, - CIRToLLVMEhSjljSetjmpOpLowering, + CIRToLLVMEhSetjmpOpLowering, CIRToLLVMExpectOpLowering, CIRToLLVMExtractMemberOpLowering, CIRToLLVMFrameAddrOpLowering, diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h index f8e7a42833f8..1d2747d416c7 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.h @@ -1220,7 +1220,7 @@ class CIRToLLVMEhTypeIdOpLowering mlir::ConversionPatternRewriter &) const override; }; -class CIRToLLVMEhSjljSetjmpOpLowering +class CIRToLLVMEhSetjmpOpLowering : public mlir::OpConversionPattern { public: using mlir::OpConversionPattern::OpConversionPattern; diff --git a/clang/test/CIR/Transforms/setjmp-longjmp-lower.c b/clang/test/CIR/Transforms/setjmp-longjmp-lower.c new file mode 100644 index 000000000000..3d647f35576d --- /dev/null +++ b/clang/test/CIR/Transforms/setjmp-longjmp-lower.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -mmlir --mlir-print-ir-before=cir-lowering-prepare %s -o - 2>&1 | FileCheck %s -check-prefix=BEFORE-LOWERING-PREPARE +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -mmlir --mlir-print-ir-after=cir-lowering-prepare %s -o - 2>&1 | FileCheck %s -check-prefix=AFTER-LOWERING-PREPARE +void test_setjmp(void *env) { + // BEFORE-LOWERING-PREPARE-LABEL: test_setjmp + // BEFORE-LOWERING-PREPARE-SAME: [[ENV:%.*]]: + // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%[0-9]+]] = cir.alloca !cir.ptr, !cir.ptr>, + // BEFORE-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] : !cir.ptr, !cir.ptr> + // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%[0-9]+]] = cir.load align(8) [[ENV_ALLOCA]] + // BEFORE-LOWERING-PREPARE-NEXT: [[CAST:%[0-9]+]] = cir.cast(bitcast, [[ENV_LOAD]] : !cir.ptr), !cir.ptr> + // BEFORE-LOWERING-PREPARE-NEXT: [[ZERO:%[0-9]+]] = cir.const #cir.int<0> + // BEFORE-LOWERING-PREPARE-NEXT: [[FA:%[0-9]+]] = cir.frame_address([[ZERO]]) + // BEFORE-LOWERING-PREPARE-NEXT: cir.store [[FA]], [[CAST]] : !cir.ptr, !cir.ptr> + // BEFORE-LOWERING-PREPARE-NEXT: [[SS:%[0-9]+]] = cir.stack_save + // BEFORE-LOWERING-PREPARE-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2> + // BEFORE-LOWERING-PREPARE-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr>, [[TWO]] : !s32i), + // BEFORE-LOWERING-PREPARE-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr, !cir.ptr> + // BEFORE-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.llvm.intrinsic "eh.sjlj.setjmp" [[CAST]] + + // AFTER-LOWERING-PREPARE-LABEL: test_setjmp + // AFTER-LOWERING-PREPARE-SAME: [[ENV:%.*]]: + // AFTER-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%[0-9]+]] = cir.alloca !cir.ptr, !cir.ptr>, + // AFTER-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] : !cir.ptr, !cir.ptr> + // AFTER-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%[0-9]+]] = cir.load align(8) [[ENV_ALLOCA]] + // AFTER-LOWERING-PREPARE-NEXT: [[CAST:%[0-9]+]] = cir.cast(bitcast, [[ENV_LOAD]] : !cir.ptr), !cir.ptr> + // AFTER-LOWERING-PREPARE-NEXT: [[ZERO:%[0-9]+]] = cir.const #cir.int<0> + // AFTER-LOWERING-PREPARE-NEXT: [[FA:%[0-9]+]] = cir.frame_address([[ZERO]]) + // AFTER-LOWERING-PREPARE-NEXT: cir.store [[FA]], [[CAST]] : !cir.ptr, !cir.ptr> + // AFTER-LOWERING-PREPARE-NEXT: [[SS:%[0-9]+]] = cir.stack_save + // AFTER-LOWERING-PREPARE-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2> + // AFTER-LOWERING-PREPARE-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr>, [[TWO]] : !s32i), + // AFTER-LOWERING-PREPARE-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr, !cir.ptr> + // AFTER-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.llvm.intrinsic "eh.sjlj.setjmp" [[CAST]] + __builtin_setjmp(env); +} + +extern int _setjmp(void *env); +void test_setjmp2(void *env) { + // BEFORE-LOWERING-PREPARE-LABEL: test_setjmp2 + // BEFORE-LOWERING-PREPARE-SAME: [[ENV:%.*]]: !cir.ptr + // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca + // BEFORE-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] + // BEFORE-LOWERING-PREPARE-NEXT: [[DEAD_GET_GLOBAL:%.*]] = cir.get_global @_setjmp + // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]] + // BEFORE-LOWERING-PREPARE-NEXT: cir.call @_setjmp([[ENV_LOAD]]) + + // AFTER-LOWERING-PREPARE-LABEL: test_setjmp2 + // AFTER-LOWERING-PREPARE-SAME: [[ENV:%.*]]: !cir.ptr + // AFTER-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca + // AFTER-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] + // AFTER-LOWERING-PREPARE-NEXT: [[DEAD_GET_GLOBAL:%.*]] = cir.get_global @_setjmp + // AFTER-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]] + // AFTER-LOWERING-PREPARE-NEXT: cir.call @_setjmp([[ENV_LOAD]]) + _setjmp (env); +} From c3723031f4846f3eb213508d6efcfb727cfc3b4a Mon Sep 17 00:00:00 2001 From: Jasmine Tang Date: Tue, 26 Aug 2025 13:35:10 -0700 Subject: [PATCH 3/7] Updated description for op, use better getter --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 14 ++++++-------- .../lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 6 +++--- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 6cd183d279b7..f4d431cbbda0 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4701,12 +4701,10 @@ 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(). + Saves call-site information (e.g., stack pointer, instruction + pointer, signal mask, and other registers) in memory at `env` for use by longjmp(). In this case, + setjmp() returns 0. When returned from a longjmp(), setjmp returns the + value passed into longjmp() Examples: ```mlir @@ -4718,10 +4716,10 @@ def CIR_EhSetjmp : CIR_Op<"eh.setjmp"> { ``` }]; - let arguments = (ins CIR_PointerType:$buf, UnitAttr:$builtin); + let arguments = (ins CIR_PointerType:$env, UnitAttr:$builtin); let results = (outs CIR_SInt32:$res); let assemblyFormat = [{ - $buf `:` type($buf) + $env `:` type($env) (`,` `builtin` $builtin^)? `->` type(results) attr-dict }]; diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 59b18861ee36..f086d9a7b2d3 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -4292,10 +4292,10 @@ mlir::LogicalResult CIRToLLVMEhSetjmpOpLowering::matchAndRewrite( cir::EhSetjmp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { mlir::Type returnType = typeConverter->convertType(op.getType()); - if (op.getBuiltinAttr()) { + if (op.getBuiltin()) { mlir::LLVM::CallIntrinsicOp newOp = createCallLLVMIntrinsicOp(rewriter, op.getLoc(), "llvm.eh.sjlj.setjmp", - returnType, adaptor.getBuf()); + returnType, adaptor.getEnv()); rewriter.replaceOp(op, newOp); } else { StringRef fnName = "_setjmp"; @@ -4304,7 +4304,7 @@ mlir::LogicalResult CIRToLLVMEhSetjmpOpLowering::matchAndRewrite( /*isVarArg=*/false); getOrCreateLLVMFuncOp(rewriter, op, fnName, fnType); rewriter.replaceOpWithNewOp(op, returnType, fnName, - adaptor.getBuf()); + adaptor.getEnv()); } return mlir::success(); } From 8dff477b2897f2a12229098c6260563224dbcf04 Mon Sep 17 00:00:00 2001 From: Jasmine Tang Date: Wed, 27 Aug 2025 12:02:03 -0700 Subject: [PATCH 4/7] Update description again. Replace codegen with eh.setjmp --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 17 ++++++++++------- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 9 +++------ clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c | 2 +- .../test/CIR/Transforms/setjmp-longjmp-lower.c | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index f4d431cbbda0..c2e10c9a1893 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4702,17 +4702,20 @@ def CIR_EhSetjmp : CIR_Op<"eh.setjmp"> { let summary = "CIR setjmp operation"; let description = [{ Saves call-site information (e.g., stack pointer, instruction - pointer, signal mask, and other registers) in memory at `env` for use by longjmp(). In this case, - setjmp() returns 0. When returned from a longjmp(), setjmp returns the - value passed into longjmp() + pointer, signal mask, and other registers) in memory at `env` for use by longjmp(). In this case, + setjmp() returns 0. Following a successful longjmp(), execution proceeds + from cir.eh.setjmp with the operation yielding a non-zero value. + + The presence of the `builtin` attribute refers to the setjmp() function; the lack of the attribute refers + to the _setjmp() function. Examples: ```mlir - // Specify setjmp is builtin - %0 = cir.eh.setjmp %arg0 : !p32, builtin -> !s32i + // Specify setjmp is builtin. + %0 = cir.eh.setjmp %arg0 : >, builtin -> !s32i - // Specify setjmp is not builtin - %0 = cir.eh.setjmp %arg0 : !p32 -> !s32i + // Specify setjmp is not builtin. + %0 = cir.eh.setjmp %arg0 : > -> !s32i ``` }]; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 0d97eb663fc6..e9e5e3277940 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1868,12 +1868,9 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, cir::PtrStrideOp stackSaveSlot = cir::PtrStrideOp::create( builder, loc, ppTy, castBuf, builder.getSInt32(2, loc)); cir::StoreOp::create(builder, loc, stacksave, stackSaveSlot); - mlir::Value setjmpCall = - cir::LLVMIntrinsicCallOp::create( - builder, loc, builder.getStringAttr("eh.sjlj.setjmp"), - builder.getSInt32Ty(), mlir::ValueRange{castBuf}) - .getResult(); - return RValue::get(setjmpCall); + cir::EhSetjmp op = + cir::EhSetjmp::create(builder, loc, castBuf, /*builtin = */ true); + return RValue::get(op); } case Builtin::BI__builtin_longjmp: llvm_unreachable("BI__builtin_longjmp NYI"); diff --git a/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c b/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c index fb3cf9637472..1bf58a1b9798 100644 --- a/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c +++ b/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c @@ -19,7 +19,7 @@ void test_setjmp(void *env) { // CIR-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2> // CIR-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr>, [[TWO]] : !s32i), // CIR-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr, !cir.ptr> - // CIR-NEXT: [[SJ:%[0-9]+]] = cir.llvm.intrinsic "eh.sjlj.setjmp" [[CAST]] + // CIR-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp [[CAST]] : >, builtin -> !s32i // LLVM-LABEL: test_setjmp diff --git a/clang/test/CIR/Transforms/setjmp-longjmp-lower.c b/clang/test/CIR/Transforms/setjmp-longjmp-lower.c index 3d647f35576d..34a1b76b13fe 100644 --- a/clang/test/CIR/Transforms/setjmp-longjmp-lower.c +++ b/clang/test/CIR/Transforms/setjmp-longjmp-lower.c @@ -14,7 +14,7 @@ void test_setjmp(void *env) { // BEFORE-LOWERING-PREPARE-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2> // BEFORE-LOWERING-PREPARE-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr>, [[TWO]] : !s32i), // BEFORE-LOWERING-PREPARE-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr, !cir.ptr> - // BEFORE-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.llvm.intrinsic "eh.sjlj.setjmp" [[CAST]] + // BEFORE-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp [[CAST]] : >, builtin -> !s32i // AFTER-LOWERING-PREPARE-LABEL: test_setjmp // AFTER-LOWERING-PREPARE-SAME: [[ENV:%.*]]: @@ -29,7 +29,7 @@ void test_setjmp(void *env) { // AFTER-LOWERING-PREPARE-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2> // AFTER-LOWERING-PREPARE-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr>, [[TWO]] : !s32i), // AFTER-LOWERING-PREPARE-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr, !cir.ptr> - // AFTER-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.llvm.intrinsic "eh.sjlj.setjmp" [[CAST]] + // AFTER-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp [[CAST]] : >, builtin -> !s32i __builtin_setjmp(env); } From 4b1377aaa49c035deea5359aa582ab0952092712 Mon Sep 17 00:00:00 2001 From: Jasmine Tang Date: Wed, 27 Aug 2025 14:32:57 -0700 Subject: [PATCH 5/7] Update _setjmp() codgen and test case --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 8 +++++++- clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c | 11 +++++------ clang/test/CIR/Transforms/setjmp-longjmp-lower.c | 16 ++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index e9e5e3277940..25998a864f83 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -2372,7 +2372,13 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, llvm_unreachable("NYI setjmp on aarch64"); llvm_unreachable("NYI setjmp on generic MSVCRT"); } - break; + Address buf = emitPointerWithAlignment(E->getArg(0)); + mlir::Location loc = getLoc(E->getExprLoc()); + cir::PointerType ppTy = builder.getPointerTo(builder.getVoidPtrTy()); + mlir::Value castBuf = builder.createBitcast(buf.getPointer(), ppTy); + cir::EhSetjmp op = + cir::EhSetjmp::create(builder, loc, castBuf, /*builtin = */ false); + return RValue::get(op); } // C++ std:: builtins. diff --git a/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c b/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c index 1bf58a1b9798..9bfdad5131fd 100644 --- a/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c +++ b/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c @@ -5,7 +5,6 @@ // RUN: %clang_cc1 -triple x86_64-unknown-linux -O2 -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG void test_setjmp(void *env) { - // CIR-LABEL: test_setjmp // CIR-SAME: [[ENV:%.*]]: // CIR-NEXT: [[ENV_ALLOCA:%[0-9]+]] = cir.alloca !cir.ptr, !cir.ptr>, @@ -44,14 +43,14 @@ void test_setjmp(void *env) { extern int _setjmp(void *env); void test_setjmp2(void *env) { - // CIR-LABEL: test_setjmp2 - // CIR-SAME: [[ENV:%.*]]: !cir.ptr - // CIR-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca + // CIR-SAME: [[ENV:%.*]]: + // CIR-NEXT: [[ENV_ALLOCA]] = cir.alloca // CIR-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] - // CIR-NEXT: [[DEAD_GET_GLOBAL:%.*]] = cir.get_global @_setjmp // CIR-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]] - // CIR-NEXT: cir.call @_setjmp([[ENV_LOAD]]) + // CIR-NEXT: [[CAST:%.*]] = cir.cast(bitcast, [[ENV_LOAD]] + // CIR-NEXT: cir.eh.setjmp [[CAST]] : > -> !s32i + // LLVM-LABEL: test_setjmp2 // LLVM-SAME: (ptr{{.*}}[[ENV:%.*]]) diff --git a/clang/test/CIR/Transforms/setjmp-longjmp-lower.c b/clang/test/CIR/Transforms/setjmp-longjmp-lower.c index 34a1b76b13fe..5c8e524ca76c 100644 --- a/clang/test/CIR/Transforms/setjmp-longjmp-lower.c +++ b/clang/test/CIR/Transforms/setjmp-longjmp-lower.c @@ -36,19 +36,19 @@ void test_setjmp(void *env) { extern int _setjmp(void *env); void test_setjmp2(void *env) { // BEFORE-LOWERING-PREPARE-LABEL: test_setjmp2 - // BEFORE-LOWERING-PREPARE-SAME: [[ENV:%.*]]: !cir.ptr - // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca + // BEFORE-LOWERING-PREPARE-SAME: [[ENV:%.*]]: + // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA]] = cir.alloca // BEFORE-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] - // BEFORE-LOWERING-PREPARE-NEXT: [[DEAD_GET_GLOBAL:%.*]] = cir.get_global @_setjmp // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]] - // BEFORE-LOWERING-PREPARE-NEXT: cir.call @_setjmp([[ENV_LOAD]]) + // BEFORE-LOWERING-PREPARE-NEXT: [[CAST:%.*]] = cir.cast(bitcast, [[ENV_LOAD]] + // BEFORE-LOWERING-PREPARE-NEXT: cir.eh.setjmp [[CAST]] : > -> !s32i // AFTER-LOWERING-PREPARE-LABEL: test_setjmp2 - // AFTER-LOWERING-PREPARE-SAME: [[ENV:%.*]]: !cir.ptr - // AFTER-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca + // AFTER-LOWERING-PREPARE-SAME: [[ENV:%.*]]: + // AFTER-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA]] = cir.alloca // AFTER-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] - // AFTER-LOWERING-PREPARE-NEXT: [[DEAD_GET_GLOBAL:%.*]] = cir.get_global @_setjmp // AFTER-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]] - // AFTER-LOWERING-PREPARE-NEXT: cir.call @_setjmp([[ENV_LOAD]]) + // AFTER-LOWERING-PREPARE-NEXT: [[CAST:%.*]] = cir.cast(bitcast, [[ENV_LOAD]] + // AFTER-LOWERING-PREPARE-NEXT: cir.eh.setjmp [[CAST]] : > -> !s32i _setjmp (env); } From faab72ce008892f3374aa7faddb777142264dea0 Mon Sep 17 00:00:00 2001 From: Jasmine Tang Date: Mon, 1 Sep 2025 21:44:32 -0700 Subject: [PATCH 6/7] Fix bug in unit test, address formatting from PR reviews --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 7 +++---- clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 9 +++++---- clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c | 4 ++-- clang/test/CIR/Lowering/setjmp-longjmp.cir | 4 ++-- clang/test/CIR/Transforms/setjmp-longjmp-lower.c | 12 ++++++------ 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index c2e10c9a1893..ba60f1723239 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4719,12 +4719,11 @@ def CIR_EhSetjmp : CIR_Op<"eh.setjmp"> { ``` }]; - let arguments = (ins CIR_PointerType:$env, UnitAttr:$builtin); + let arguments = (ins CIR_PointerType:$env, UnitAttr:$is_builtin); let results = (outs CIR_SInt32:$res); let assemblyFormat = [{ - $env `:` type($env) - (`,` `builtin` $builtin^)? - `->` type(results) attr-dict + (`builtin` $is_builtin^)? + $env `:` functional-type($env, results) attr-dict }]; } diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index f086d9a7b2d3..740a6e81e80d 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -4292,12 +4292,14 @@ mlir::LogicalResult CIRToLLVMEhSetjmpOpLowering::matchAndRewrite( cir::EhSetjmp op, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const { mlir::Type returnType = typeConverter->convertType(op.getType()); - if (op.getBuiltin()) { + if (op.getIsBuiltin()) { mlir::LLVM::CallIntrinsicOp newOp = createCallLLVMIntrinsicOp(rewriter, op.getLoc(), "llvm.eh.sjlj.setjmp", returnType, adaptor.getEnv()); rewriter.replaceOp(op, newOp); - } else { + return mlir::success(); + } + StringRef fnName = "_setjmp"; auto llvmPtrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext()); auto fnType = mlir::LLVM::LLVMFunctionType::get(returnType, llvmPtrTy, @@ -4305,8 +4307,7 @@ mlir::LogicalResult CIRToLLVMEhSetjmpOpLowering::matchAndRewrite( getOrCreateLLVMFuncOp(rewriter, op, fnName, fnType); rewriter.replaceOpWithNewOp(op, returnType, fnName, adaptor.getEnv()); - } - return mlir::success(); + return mlir::success(); } mlir::LogicalResult CIRToLLVMCatchParamOpLowering::matchAndRewrite( diff --git a/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c b/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c index 9bfdad5131fd..0e223a1b415e 100644 --- a/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c +++ b/clang/test/CIR/CodeGen/builtin-setjmp-longjmp.c @@ -18,7 +18,7 @@ void test_setjmp(void *env) { // CIR-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2> // CIR-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr>, [[TWO]] : !s32i), // CIR-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr, !cir.ptr> - // CIR-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp [[CAST]] : >, builtin -> !s32i + // CIR-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp builtin [[CAST]] : (!cir.ptr>) -> !s32i // LLVM-LABEL: test_setjmp @@ -49,7 +49,7 @@ void test_setjmp2(void *env) { // CIR-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] // CIR-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]] // CIR-NEXT: [[CAST:%.*]] = cir.cast(bitcast, [[ENV_LOAD]] - // CIR-NEXT: cir.eh.setjmp [[CAST]] : > -> !s32i + // CIR-NEXT: cir.eh.setjmp [[CAST]] : (!cir.ptr>) -> !s32i // LLVM-LABEL: test_setjmp2 diff --git a/clang/test/CIR/Lowering/setjmp-longjmp.cir b/clang/test/CIR/Lowering/setjmp-longjmp.cir index 30ced34ede96..627a573e5051 100644 --- a/clang/test/CIR/Lowering/setjmp-longjmp.cir +++ b/clang/test/CIR/Lowering/setjmp-longjmp.cir @@ -11,7 +11,7 @@ module { // 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 + %0 = cir.eh.setjmp builtin %arg0 : (!p32) -> !s32i cir.return %0 : !s32i } cir.func @test_setjmp_2(%arg0 : !p32) -> !s32i { @@ -20,7 +20,7 @@ module { // 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 + %0 = cir.eh.setjmp %arg0 : (!p32) -> !s32i cir.return %0 : !s32i } // MLIR: } diff --git a/clang/test/CIR/Transforms/setjmp-longjmp-lower.c b/clang/test/CIR/Transforms/setjmp-longjmp-lower.c index 5c8e524ca76c..57fb2f91b5fe 100644 --- a/clang/test/CIR/Transforms/setjmp-longjmp-lower.c +++ b/clang/test/CIR/Transforms/setjmp-longjmp-lower.c @@ -14,7 +14,7 @@ void test_setjmp(void *env) { // BEFORE-LOWERING-PREPARE-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2> // BEFORE-LOWERING-PREPARE-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr>, [[TWO]] : !s32i), // BEFORE-LOWERING-PREPARE-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr, !cir.ptr> - // BEFORE-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp [[CAST]] : >, builtin -> !s32i + // BEFORE-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp builtin [[CAST]] : (!cir.ptr>) -> !s32i // AFTER-LOWERING-PREPARE-LABEL: test_setjmp // AFTER-LOWERING-PREPARE-SAME: [[ENV:%.*]]: @@ -29,7 +29,7 @@ void test_setjmp(void *env) { // AFTER-LOWERING-PREPARE-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2> // AFTER-LOWERING-PREPARE-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr>, [[TWO]] : !s32i), // AFTER-LOWERING-PREPARE-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr, !cir.ptr> - // AFTER-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp [[CAST]] : >, builtin -> !s32i + // AFTER-LOWERING-PREPARE-NEXT: [[SJ:%[0-9]+]] = cir.eh.setjmp builtin [[CAST]] : (!cir.ptr>) -> !s32i __builtin_setjmp(env); } @@ -37,18 +37,18 @@ extern int _setjmp(void *env); void test_setjmp2(void *env) { // BEFORE-LOWERING-PREPARE-LABEL: test_setjmp2 // BEFORE-LOWERING-PREPARE-SAME: [[ENV:%.*]]: - // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA]] = cir.alloca + // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca // BEFORE-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] // BEFORE-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]] // BEFORE-LOWERING-PREPARE-NEXT: [[CAST:%.*]] = cir.cast(bitcast, [[ENV_LOAD]] - // BEFORE-LOWERING-PREPARE-NEXT: cir.eh.setjmp [[CAST]] : > -> !s32i + // BEFORE-LOWERING-PREPARE-NEXT: cir.eh.setjmp [[CAST]] : (!cir.ptr>) -> !s32i // AFTER-LOWERING-PREPARE-LABEL: test_setjmp2 // AFTER-LOWERING-PREPARE-SAME: [[ENV:%.*]]: - // AFTER-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA]] = cir.alloca + // AFTER-LOWERING-PREPARE-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca // AFTER-LOWERING-PREPARE-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] // AFTER-LOWERING-PREPARE-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]] // AFTER-LOWERING-PREPARE-NEXT: [[CAST:%.*]] = cir.cast(bitcast, [[ENV_LOAD]] - // AFTER-LOWERING-PREPARE-NEXT: cir.eh.setjmp [[CAST]] : > -> !s32i + // AFTER-LOWERING-PREPARE-NEXT: cir.eh.setjmp [[CAST]] : (!cir.ptr>) -> !s32i _setjmp (env); } From 14a63b2dd7da0e4804ed09420712740be4ca1bf7 Mon Sep 17 00:00:00 2001 From: Jasmine Tang Date: Wed, 3 Sep 2025 17:06:35 -0700 Subject: [PATCH 7/7] Resolve PR comments --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 9 +++++---- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index ba60f1723239..452c9e6fcbd3 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4712,19 +4712,20 @@ def CIR_EhSetjmp : CIR_Op<"eh.setjmp"> { Examples: ```mlir // Specify setjmp is builtin. - %0 = cir.eh.setjmp %arg0 : >, builtin -> !s32i + %0 = cir.eh.setjmp builtin %arg0 : (!cir.ptr) -> !s32i // Specify setjmp is not builtin. - %0 = cir.eh.setjmp %arg0 : > -> !s32i + %0 = cir.eh.setjmp %arg0 : (!cir.ptr) -> !s32i ``` }]; - let arguments = (ins CIR_PointerType:$env, UnitAttr:$is_builtin); + let results = (outs CIR_SInt32:$res); + let assemblyFormat = [{ (`builtin` $is_builtin^)? $env `:` functional-type($env, results) attr-dict - }]; + }]; } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 25998a864f83..2f4892636c7f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1869,7 +1869,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, builder, loc, ppTy, castBuf, builder.getSInt32(2, loc)); cir::StoreOp::create(builder, loc, stacksave, stackSaveSlot); cir::EhSetjmp op = - cir::EhSetjmp::create(builder, loc, castBuf, /*builtin = */ true); + cir::EhSetjmp::create(builder, loc, castBuf, /*is_builtin=*/true); return RValue::get(op); } case Builtin::BI__builtin_longjmp: