diff --git a/clang/include/clang/Basic/BuiltinsAArch64.def b/clang/include/clang/Basic/BuiltinsAArch64.def index 12c7a371e0fbd..82a1ba3c82ad3 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/clang/include/clang/Basic/BuiltinsAArch64.def @@ -283,6 +283,8 @@ TARGET_HEADER_BUILTIN(_CountLeadingZeros64, "UiULLi", "nh", INTRIN_H, ALL_MS_LAN TARGET_HEADER_BUILTIN(_CountOneBits, "UiUNi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_CountOneBits64, "UiULLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(__prefetch, "vv*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef LANGBUILTIN #undef TARGET_BUILTIN diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 4a73403cb3b9a..6944ff8f6ca74 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -10834,6 +10834,15 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, return Result; } + if (BuiltinID == AArch64::BI__prefetch) { + Value *Address = EmitScalarExpr(E->getArg(0)); + Value *RW = llvm::ConstantInt::get(Int32Ty, 0); + Value *Locality = ConstantInt::get(Int32Ty, 3); + Value *Data = llvm::ConstantInt::get(Int32Ty, 1); + Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType()); + return Builder.CreateCall(F, {Address, RW, Locality, Data}); + } + // Handle MSVC intrinsics before argument evaluation to prevent double // evaluation. if (std::optional MsvcIntId = diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index 4678c527bfaab..9ebaea9fee942 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -586,6 +586,8 @@ unsigned int _CountLeadingZeros(unsigned long); unsigned int _CountLeadingZeros64(unsigned _int64); unsigned int _CountOneBits(unsigned long); unsigned int _CountOneBits64(unsigned __int64); + +void __cdecl __prefetch(void *); #endif /*----------------------------------------------------------------------------*\ diff --git a/clang/test/CodeGen/arm64-microsoft-intrinsics.c b/clang/test/CodeGen/arm64-microsoft-intrinsics.c index b15defb0894e9..44b2ee28fe568 100644 --- a/clang/test/CodeGen/arm64-microsoft-intrinsics.c +++ b/clang/test/CodeGen/arm64-microsoft-intrinsics.c @@ -402,6 +402,16 @@ unsigned int check_CountOneBits64(unsigned __int64 arg1) { // CHECK-MSCOMPAT: ret i32 %[[VAR2]] // CHECK-LINUX: error: call to undeclared function '_CountOneBits64' +void check__prefetch(void *arg1) { + return __prefetch(arg1); +} + +// CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca ptr, align 8 +// CHECK-MSCOMPAT: store ptr %[[ARG1]], ptr %[[ARG1]].addr, align 8 +// CHECK-MSCOMPAT: %[[VAR0:.*]] = load ptr, ptr %[[ARG1]].addr, align 8 +// CHECK-MSCOMPAT: call void @llvm.prefetch.p0(ptr %[[VAR0]], i32 0, i32 3, i32 1) +// CHECK-MSCOMPAT: ret void + // CHECK-MSCOMPAT: ![[MD2]] = !{!"x18"} // CHECK-MSCOMPAT: ![[MD3]] = !{!"sp"}