Skip to content

Commit 02269a6

Browse files
committed
Enable the implementation of __builtin_setjmp and __builtin_longjmp. Not all
LLVM backends support these yet. llvm-svn: 104867
1 parent dc53f1c commit 02269a6

File tree

2 files changed

+25
-15
lines changed

2 files changed

+25
-15
lines changed

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -557,30 +557,33 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
557557
else
558558
return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
559559
}
560-
#if 0
561-
// FIXME: Finish/enable when LLVM backend support stabilizes
562560
case Builtin::BI__builtin_setjmp: {
561+
// Buffer is a void**.
563562
Value *Buf = EmitScalarExpr(E->getArg(0));
564-
// Store the frame pointer to the buffer
565-
Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0);
563+
564+
// Store the frame pointer to the setjmp buffer.
566565
Value *FrameAddr =
567-
Builder.CreateCall(FrameAddrF,
568-
Constant::getNullValue(llvm::Type::getInt32Ty(VMContext)));
566+
Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
567+
ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0));
569568
Builder.CreateStore(FrameAddr, Buf);
570-
// Call the setjmp intrinsic
571-
Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp, 0, 0);
572-
const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
573-
Buf = Builder.CreateBitCast(Buf, DestType);
569+
570+
// Call LLVM's EH setjmp, which is lightweight.
571+
Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
572+
Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext));
574573
return RValue::get(Builder.CreateCall(F, Buf));
575574
}
576575
case Builtin::BI__builtin_longjmp: {
577-
Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp, 0, 0);
578576
Value *Buf = EmitScalarExpr(E->getArg(0));
579-
const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext);
580-
Buf = Builder.CreateBitCast(Buf, DestType);
581-
return RValue::get(Builder.CreateCall(F, Buf));
577+
Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext));
578+
579+
// Call LLVM's EH longjmp, which is lightweight.
580+
Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf);
581+
582+
// longjmp doesn't return; mark this as unreachable
583+
Value *V = Builder.CreateUnreachable();
584+
Builder.ClearInsertionPoint();
585+
return RValue::get(V);
582586
}
583-
#endif
584587
case Builtin::BI__sync_fetch_and_add:
585588
case Builtin::BI__sync_fetch_and_sub:
586589
case Builtin::BI__sync_fetch_and_or:

clang/test/CodeGen/builtins.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,10 @@ void test_float_builtins(float F, double D, long double LD) {
195195
// CHECK: and i1
196196
}
197197

198+
// CHECK: define void @test_builtin_longjmp
199+
void test_builtin_longjmp(void **buffer) {
200+
// CHECK: [[BITCAST:%.*]] = bitcast
201+
// CHECK-NEXT: call void @llvm.eh.sjlj.longjmp(i8* [[BITCAST]])
202+
__builtin_longjmp(buffer, 1);
203+
// CHECK-NEXT: unreachable
204+
}

0 commit comments

Comments
 (0)