Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -711,8 +711,12 @@ } 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)); + if (CGF.getTarget().getTriple().getArch() == llvm::Triple::aarch64) { + Arg1 = CGF.Builder.CreateCall(CGF.CGM.getIntrinsic(Intrinsic::sponentry)); + CGF.CurFn->addFnAttr("no-frame-pointer-elim", "true"); + } else + Arg1 = CGF.Builder.CreateCall(CGF.CGM.getIntrinsic(Intrinsic::frameaddress), + llvm::ConstantInt::get(CGF.Int32Ty, 0)); } // Mark the call site and declaration with ReturnsTwice. Index: test/CodeGen/ms-setjmp.c =================================================================== --- test/CodeGen/ms-setjmp.c +++ test/CodeGen/ms-setjmp.c @@ -25,7 +25,7 @@ // X64-NEXT: ret i32 %[[call]] // AARCH64-LABEL: define dso_local i32 @test_setjmp - // AARCH64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0) + // AARCH64: %[[addr:.*]] = call i8* @llvm.sponentry() // 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]] } @@ -38,7 +38,8 @@ // X64-NEXT: ret i32 %[[call]] // AARCH64-LABEL: define dso_local i32 @test_setjmpex - // AARCH64: %[[addr:.*]] = call i8* @llvm.frameaddress(i32 0) + // AARCH64: %[[addr:.*]] = call i8* @llvm.sponentry() // 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]] + // AARCH64: "no-frame-pointer-elim"="true" }