Skip to content

Commit ff4c1fd

Browse files
authored
[CIR] Add builtin_setjmp codegen support (#1842)
1 parent 2326b31 commit ff4c1fd

File tree

2 files changed

+105
-4
lines changed

2 files changed

+105
-4
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1844,8 +1844,37 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
18441844
llvm_unreachable("BI__builtin_unwind_init NYI");
18451845
case Builtin::BI__builtin_extend_pointer:
18461846
llvm_unreachable("BI__builtin_extend_pointer NYI");
1847-
case Builtin::BI__builtin_setjmp:
1848-
llvm_unreachable("BI__builtin_setjmp NYI");
1847+
case Builtin::BI__builtin_setjmp: {
1848+
Address buf = emitPointerWithAlignment(E->getArg(0));
1849+
mlir::Location loc = getLoc(E->getExprLoc());
1850+
1851+
cir::PointerType ppTy = builder.getPointerTo(builder.getVoidPtrTy());
1852+
mlir::Value castBuf = builder.createBitcast(buf.getPointer(), ppTy);
1853+
1854+
assert(!cir::MissingFeatures::emitCheckedInBoundsGEP());
1855+
if (getTarget().getTriple().isSystemZ()) {
1856+
llvm_unreachable("SYSTEMZ NYI");
1857+
}
1858+
1859+
mlir::Value frameaddress =
1860+
cir::FrameAddrOp::create(builder, loc, builder.getVoidPtrTy(),
1861+
mlir::ValueRange{builder.getUInt32(0, loc)})
1862+
.getResult();
1863+
1864+
cir::StoreOp::create(builder, loc, frameaddress, castBuf);
1865+
mlir::Value stacksave =
1866+
cir::StackSaveOp::create(builder, loc, builder.getVoidPtrTy())
1867+
.getResult();
1868+
cir::PtrStrideOp stackSaveSlot = cir::PtrStrideOp::create(
1869+
builder, loc, ppTy, castBuf, builder.getSInt32(2, loc));
1870+
cir::StoreOp::create(builder, loc, stacksave, stackSaveSlot);
1871+
mlir::Value setjmpCall =
1872+
cir::LLVMIntrinsicCallOp::create(
1873+
builder, loc, builder.getStringAttr("eh.sjlj.setjmp"),
1874+
builder.getSInt32Ty(), mlir::ValueRange{castBuf})
1875+
.getResult();
1876+
return RValue::get(setjmpCall);
1877+
}
18491878
case Builtin::BI__builtin_longjmp:
18501879
llvm_unreachable("BI__builtin_longjmp NYI");
18511880
case Builtin::BI__builtin_launder: {
@@ -2337,9 +2366,17 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
23372366
case Builtin::BI_setjmpex:
23382367
llvm_unreachable("BI_setjmpex NYI");
23392368
break;
2340-
case Builtin::BI_setjmp:
2341-
llvm_unreachable("BI_setjmp NYI");
2369+
case Builtin::BI_setjmp: {
2370+
if (getTarget().getTriple().isOSMSVCRT() && E->getNumArgs() == 1 &&
2371+
E->getArg(0)->getType()->isPointerType()) {
2372+
if (getTarget().getTriple().getArch() == llvm::Triple::x86)
2373+
llvm_unreachable("NYI setjmp on x86");
2374+
else if (getTarget().getTriple().getArch() == llvm::Triple::aarch64)
2375+
llvm_unreachable("NYI setjmp on aarch64");
2376+
llvm_unreachable("NYI setjmp on generic MSVCRT");
2377+
}
23422378
break;
2379+
}
23432380

23442381
// C++ std:: builtins.
23452382
case Builtin::BImove:
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux -O2 -fclangir -emit-cir %s -o %t.cir
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// RUN: %clang_cc1 -triple x86_64-unknown-linux -O2 -fclangir -emit-llvm %s -o %t.ll
4+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
5+
// RUN: %clang_cc1 -triple x86_64-unknown-linux -O2 -emit-llvm %s -o %t.ll
6+
// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
7+
void test_setjmp(void *env) {
8+
9+
// CIR-LABEL: test_setjmp
10+
// CIR-SAME: [[ENV:%.*]]:
11+
// CIR-NEXT: [[ENV_ALLOCA:%[0-9]+]] = cir.alloca !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>,
12+
// CIR-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
13+
// CIR-NEXT: [[ENV_LOAD:%[0-9]+]] = cir.load align(8) [[ENV_ALLOCA]]
14+
// CIR-NEXT: [[CAST:%[0-9]+]] = cir.cast(bitcast, [[ENV_LOAD]] : !cir.ptr<!void>), !cir.ptr<!cir.ptr<!void>>
15+
// CIR-NEXT: [[ZERO:%[0-9]+]] = cir.const #cir.int<0>
16+
// CIR-NEXT: [[FA:%[0-9]+]] = cir.frame_address([[ZERO]])
17+
// CIR-NEXT: cir.store [[FA]], [[CAST]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
18+
// CIR-NEXT: [[SS:%[0-9]+]] = cir.stack_save
19+
// CIR-NEXT: [[TWO:%[0-9]+]] = cir.const #cir.int<2>
20+
// CIR-NEXT: [[GEP:%[0-9]+]] = cir.ptr_stride([[CAST]] : !cir.ptr<!cir.ptr<!void>>, [[TWO]] : !s32i),
21+
// CIR-NEXT: cir.store [[SS]], [[GEP]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
22+
// CIR-NEXT: [[SJ:%[0-9]+]] = cir.llvm.intrinsic "eh.sjlj.setjmp" [[CAST]]
23+
24+
25+
// LLVM-LABEL: test_setjmp
26+
// LLVM-SAME: (ptr{{.*}}[[ENV:%.*]])
27+
// LLVM-NEXT: [[FA:%[0-9]+]] = {{.*}}@llvm.frameaddress.p0(i32 0)
28+
// LLVM-NEXT: store ptr [[FA]], ptr [[ENV]]
29+
// LLVM-NEXT: [[SS:%[0-9]+]] = {{.*}}@llvm.stacksave.p0()
30+
// LLVM-NEXT: [[GEP:%[0-9]+]] = getelementptr i8, ptr [[ENV]], i64 16
31+
// LLVM-NEXT: store ptr [[SS]], ptr [[GEP]]
32+
// LLVM-NEXT: @llvm.eh.sjlj.setjmp(ptr{{.*}}[[ENV]])
33+
34+
// OGCG-LABEL: test_setjmp
35+
// OGCG-SAME: (ptr{{.*}}[[ENV:%.*]])
36+
// OGCG: [[FA:%.*]] = {{.*}}@llvm.frameaddress.p0(i32 0)
37+
// OGCG-NEXT: store ptr [[FA]], ptr [[ENV]]
38+
// OGCG-NEXT: [[SS:%.*]] = {{.*}}@llvm.stacksave.p0()
39+
// OGCG-NEXT: [[GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[ENV]], i64 16
40+
// OGCG-NEXT: store ptr [[SS]], ptr [[GEP]]
41+
// OGCG-NEXT: @llvm.eh.sjlj.setjmp(ptr{{.*}}[[ENV]])
42+
__builtin_setjmp(env);
43+
}
44+
45+
extern int _setjmp(void *env);
46+
void test_setjmp2(void *env) {
47+
48+
// CIR-LABEL: test_setjmp2
49+
// CIR-SAME: [[ENV:%.*]]: !cir.ptr<!void>
50+
// CIR-NEXT: [[ENV_ALLOCA:%.*]] = cir.alloca
51+
// CIR-NEXT: cir.store [[ENV]], [[ENV_ALLOCA]]
52+
// CIR-NEXT: [[DEAD_GET_GLOBAL:%.*]] = cir.get_global @_setjmp
53+
// CIR-NEXT: [[ENV_LOAD:%.*]] = cir.load align(8) [[ENV_ALLOCA]]
54+
// CIR-NEXT: cir.call @_setjmp([[ENV_LOAD]])
55+
56+
// LLVM-LABEL: test_setjmp2
57+
// LLVM-SAME: (ptr{{.*}}[[ENV:%.*]])
58+
// LLVM-NEXT: call i32 @_setjmp(ptr [[ENV]])
59+
//
60+
// OGCG-LABEL: test_setjmp2
61+
// OGCG-SAME: (ptr{{.*}}[[ENV:%.*]])
62+
// OGCG: call i32 @_setjmp(ptr noundef [[ENV]])
63+
_setjmp (env);
64+
}

0 commit comments

Comments
 (0)