From 02269a66b362f1345cc12176f7e2cbc5474d2f02 Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 27 May 2010 18:47:06 +0000 Subject: [PATCH] Enable the implementation of __builtin_setjmp and __builtin_longjmp. Not all LLVM backends support these yet. llvm-svn: 104867 --- clang/lib/CodeGen/CGBuiltin.cpp | 33 ++++++++++++++++++--------------- clang/test/CodeGen/builtins.c | 7 +++++++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index dd505c2ae88f..8c3478c3b0c7 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -557,30 +557,33 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, else return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); } -#if 0 - // FIXME: Finish/enable when LLVM backend support stabilizes case Builtin::BI__builtin_setjmp: { + // Buffer is a void**. Value *Buf = EmitScalarExpr(E->getArg(0)); - // Store the frame pointer to the buffer - Value *FrameAddrF = CGM.getIntrinsic(Intrinsic::frameaddress, 0, 0); + + // Store the frame pointer to the setjmp buffer. Value *FrameAddr = - Builder.CreateCall(FrameAddrF, - Constant::getNullValue(llvm::Type::getInt32Ty(VMContext))); + Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), + ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0)); Builder.CreateStore(FrameAddr, Buf); - // Call the setjmp intrinsic - Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp, 0, 0); - const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); - Buf = Builder.CreateBitCast(Buf, DestType); + + // Call LLVM's EH setjmp, which is lightweight. + Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); + Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext)); return RValue::get(Builder.CreateCall(F, Buf)); } case Builtin::BI__builtin_longjmp: { - Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp, 0, 0); Value *Buf = EmitScalarExpr(E->getArg(0)); - const llvm::Type *DestType = llvm::Type::getInt8PtrTy(VMContext); - Buf = Builder.CreateBitCast(Buf, DestType); - return RValue::get(Builder.CreateCall(F, Buf)); + Buf = Builder.CreateBitCast(Buf, llvm::Type::getInt8PtrTy(VMContext)); + + // Call LLVM's EH longjmp, which is lightweight. + Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); + + // longjmp doesn't return; mark this as unreachable + Value *V = Builder.CreateUnreachable(); + Builder.ClearInsertionPoint(); + return RValue::get(V); } -#endif case Builtin::BI__sync_fetch_and_add: case Builtin::BI__sync_fetch_and_sub: case Builtin::BI__sync_fetch_and_or: diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c index 8b6125806eff..2355fb43243b 100644 --- a/clang/test/CodeGen/builtins.c +++ b/clang/test/CodeGen/builtins.c @@ -195,3 +195,10 @@ void test_float_builtins(float F, double D, long double LD) { // CHECK: and i1 } +// CHECK: define void @test_builtin_longjmp +void test_builtin_longjmp(void **buffer) { + // CHECK: [[BITCAST:%.*]] = bitcast + // CHECK-NEXT: call void @llvm.eh.sjlj.longjmp(i8* [[BITCAST]]) + __builtin_longjmp(buffer, 1); + // CHECK-NEXT: unreachable +}