diff options
| author | Reid Kleckner <rnk@google.com> | 2018-06-06 18:39:47 +0000 | 
|---|---|---|
| committer | Reid Kleckner <rnk@google.com> | 2018-06-06 18:39:47 +0000 | 
| commit | 11c99ed05f7a5046c924126c1abcf9334a172bbc (patch) | |
| tree | d055a1f2d21b4c59e1b7b7eb812129e03106654e /clang/lib/CodeGen | |
| parent | 9e46c6da69454d0877015c07f7fc4e9b42bb07e1 (diff) | |
| download | bcm5719-llvm-11c99ed05f7a5046c924126c1abcf9334a172bbc.tar.gz bcm5719-llvm-11c99ed05f7a5046c924126c1abcf9334a172bbc.zip | |
[MS][ARM64]: Promote _setjmp to_setjmpex as there is no _setjmp in the ARM64 libvcruntime.lib
Factor out the common setjmp call emission code.
Based on a patch by Chris January
Differential Revision: https://reviews.llvm.org/D47784
llvm-svn: 334112
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 104 | 
1 files changed, 55 insertions, 49 deletions
| diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 5829396b0fe..a09fa7aae5e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -643,6 +643,52 @@ static RValue EmitBitTestIntrinsic(CodeGenFunction &CGF, unsigned BuiltinID,        ShiftedByte, llvm::ConstantInt::get(CGF.Int8Ty, 1), "bittest.res"));  } +namespace { +enum class MSVCSetJmpKind { +  _setjmpex, +  _setjmp3, +  _setjmp +}; +} + +/// MSVC handles setjmp a bit differently on different platforms. On every +/// architecture except 32-bit x86, the frame address is passed. On x86, extra +/// parameters can be passed as variadic arguments, but we always pass none. +static RValue EmitMSVCRTSetJmp(CodeGenFunction &CGF, MSVCSetJmpKind SJKind, +                               const CallExpr *E) { +  llvm::Value *Arg1 = nullptr; +  llvm::Type *Arg1Ty = nullptr; +  StringRef Name; +  bool IsVarArg = false; +  if (SJKind == MSVCSetJmpKind::_setjmp3) { +    Name = "_setjmp3"; +    Arg1Ty = CGF.Int32Ty; +    Arg1 = llvm::ConstantInt::get(CGF.IntTy, 0); +    IsVarArg = true; +  } else { +    Name = SJKind == MSVCSetJmpKind::_setjmp ? "_setjmp" : "_setjmpex"; +    Arg1Ty = CGF.Int8PtrTy; +    Arg1 = CGF.Builder.CreateCall(CGF.CGM.getIntrinsic(Intrinsic::frameaddress), +                                  llvm::ConstantInt::get(CGF.Int32Ty, 0)); +  } + +  // Mark the call site and declaration with ReturnsTwice. +  llvm::Type *ArgTypes[2] = {CGF.Int8PtrTy, Arg1Ty}; +  llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( +      CGF.getLLVMContext(), llvm::AttributeList::FunctionIndex, +      llvm::Attribute::ReturnsTwice); +  llvm::Constant *SetJmpFn = CGF.CGM.CreateRuntimeFunction( +      llvm::FunctionType::get(CGF.IntTy, ArgTypes, IsVarArg), Name, +      ReturnsTwiceAttr, /*Local=*/true); + +  llvm::Value *Buf = CGF.Builder.CreateBitOrPointerCast( +      CGF.EmitScalarExpr(E->getArg(0)), CGF.Int8PtrTy); +  llvm::Value *Args[] = {Buf, Arg1}; +  llvm::CallSite CS = CGF.EmitRuntimeCallOrInvoke(SetJmpFn, Args); +  CS.setAttributes(ReturnsTwiceAttr); +  return RValue::get(CS.getInstruction()); +} +  // Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we  // handle them here.  enum class CodeGenFunction::MSVCIntrin { @@ -2957,59 +3003,19 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,    case Builtin::BI__abnormal_termination:    case Builtin::BI_abnormal_termination:      return RValue::get(EmitSEHAbnormalTermination()); -  case Builtin::BI_setjmpex: { -    if (getTarget().getTriple().isOSMSVCRT()) { -      llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; -      llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( -          getLLVMContext(), llvm::AttributeList::FunctionIndex, -          llvm::Attribute::ReturnsTwice); -      llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction( -          llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), -          "_setjmpex", ReturnsTwiceAttr, /*Local=*/true); -      llvm::Value *Buf = Builder.CreateBitOrPointerCast( -          EmitScalarExpr(E->getArg(0)), Int8PtrTy); -      llvm::Value *FrameAddr = -          Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), -                             ConstantInt::get(Int32Ty, 0)); -      llvm::Value *Args[] = {Buf, FrameAddr}; -      llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args); -      CS.setAttributes(ReturnsTwiceAttr); -      return RValue::get(CS.getInstruction()); -    } +  case Builtin::BI_setjmpex: +    if (getTarget().getTriple().isOSMSVCRT()) +      return EmitMSVCRTSetJmp(*this, MSVCSetJmpKind::_setjmpex, E);      break; -  } -  case Builtin::BI_setjmp: { +  case Builtin::BI_setjmp:      if (getTarget().getTriple().isOSMSVCRT()) { -      llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( -          getLLVMContext(), llvm::AttributeList::FunctionIndex, -          llvm::Attribute::ReturnsTwice); -      llvm::Value *Buf = Builder.CreateBitOrPointerCast( -          EmitScalarExpr(E->getArg(0)), Int8PtrTy); -      llvm::CallSite CS; -      if (getTarget().getTriple().getArch() == llvm::Triple::x86) { -        llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy}; -        llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction( -            llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true), -            "_setjmp3", ReturnsTwiceAttr, /*Local=*/true); -        llvm::Value *Count = ConstantInt::get(IntTy, 0); -        llvm::Value *Args[] = {Buf, Count}; -        CS = EmitRuntimeCallOrInvoke(SetJmp3, Args); -      } else { -        llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; -        llvm::Constant *SetJmp = CGM.CreateRuntimeFunction( -            llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), -            "_setjmp", ReturnsTwiceAttr, /*Local=*/true); -        llvm::Value *FrameAddr = -            Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), -                               ConstantInt::get(Int32Ty, 0)); -        llvm::Value *Args[] = {Buf, FrameAddr}; -        CS = EmitRuntimeCallOrInvoke(SetJmp, Args); -      } -      CS.setAttributes(ReturnsTwiceAttr); -      return RValue::get(CS.getInstruction()); +      if (getTarget().getTriple().getArch() == llvm::Triple::x86) +        return EmitMSVCRTSetJmp(*this, MSVCSetJmpKind::_setjmp3, E); +      else if (getTarget().getTriple().getArch() == llvm::Triple::aarch64) +        return EmitMSVCRTSetJmp(*this, MSVCSetJmpKind::_setjmpex, E); +      return EmitMSVCRTSetJmp(*this, MSVCSetJmpKind::_setjmp, E);      }      break; -  }    case Builtin::BI__GetExceptionInfo: {      if (llvm::GlobalVariable *GV = | 

