Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -2841,6 +2841,18 @@ llvm::Value *Count = ConstantInt::get(IntTy, 0); llvm::Value *Args[] = {Buf, Count}; CS = EmitRuntimeCallOrInvoke(SetJmp3, Args); + } else if (getTarget().getTriple().getArch() == llvm::Triple::aarch64) { + llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; + // There is no _setjmp in the ARM64 libvcruntime.lib. + // _setjmp is promoted to _setjmpex by the Microsoft C++ compiler. + llvm::Constant *SetJmp = CGM.CreateRuntimeFunction( + llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), + "_setjmpex", 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); } else { llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; llvm::Constant *SetJmp = CGM.CreateRuntimeFunction( @@ -8484,7 +8496,7 @@ return EmitX86Select(CGF, Ops[4], Ternlog, PassThru); } -static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, +static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, llvm::Type *DstTy) { unsigned NumberOfElements = DstTy->getVectorNumElements(); Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements); Index: test/CodeGen/ms-setjmp.c =================================================================== --- test/CodeGen/ms-setjmp.c +++ test/CodeGen/ms-setjmp.c @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -fms-extensions -DDECLARE_SETJMP -triple i686-windows-msvc -emit-llvm %s -o - | FileCheck --check-prefix=I386 %s // RUN: %clang_cc1 -fms-extensions -DDECLARE_SETJMP -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck --check-prefix=X64 %s +// RUN: %clang_cc1 -fms-extensions -DDECLARE_SETJMP -triple aarch64-windows-msvc -emit-llvm %s -o - | FileCheck --check-prefix=AARCH64 %s // RUN: %clang_cc1 -fms-extensions -triple i686-windows-msvc -emit-llvm %s -o - | FileCheck --check-prefix=I386 %s // RUN: %clang_cc1 -fms-extensions -triple x86_64-windows-msvc -emit-llvm %s -o - | FileCheck --check-prefix=X64 %s +// RUN: %clang_cc1 -fms-extensions -triple aarch64-windows-msvc -emit-llvm %s -o - | FileCheck --check-prefix=AARCH64 %s typedef char jmp_buf[1]; #ifdef DECLARE_SETJMP @@ -21,6 +23,11 @@ // X64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0) // X64: %[[call:.*]] = call i32 @_setjmp(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]]) // X64-NEXT: ret i32 %[[call]] + + // AARCH64-LABEL: define dso_local i32 @test_setjmp + // AARCH64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0) + // AARCH64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]]) + // AARCH64-NEXT: ret i32 %[[call]] } int test_setjmpex() { @@ -29,4 +36,9 @@ // X64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0) // X64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]]) // X64-NEXT: ret i32 %[[call]] + + // AARCH64-LABEL: define dso_local i32 @test_setjmpex + // AARCH64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0) + // AARCH64: %[[call:.*]] = call i32 @_setjmpex(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @jb, i32 0, i32 0), i8* %[[addr]]) + // AARCH64-NEXT: ret i32 %[[call]] }