From d250cc8385318b61cea79e24495d15fb5b7e6654 Mon Sep 17 00:00:00 2001 From: David Rivera Date: Tue, 10 Jun 2025 15:44:08 -0400 Subject: [PATCH] [CIR][CIRGen][Builtin][X86] Lower prefetch --- clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 26 +++++++++++++++++++++- clang/test/CIR/CodeGen/X86/builtins-x86.c | 8 +++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index 96469248535b..9287c65439d2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -65,6 +65,14 @@ translateX86ToMsvcIntrin(unsigned BuiltinID) { llvm_unreachable("must return from switch"); } +/// Get integer from a mlir::Value that is an int constant or a constant op. +static int64_t getIntValueFromConstOp(mlir::Value val) { + auto constOp = mlir::cast(val.getDefiningOp()); + return (mlir::cast(constOp.getValue())) + .getValue() + .getSExtValue(); +} + mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (BuiltinID == Builtin::BI__builtin_cpu_is) @@ -95,7 +103,23 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID, default: return nullptr; case X86::BI_mm_prefetch: { - llvm_unreachable("_mm_prefetch NYI"); + mlir::Value Address = builder.createPtrBitcast(Ops[0], VoidTy); + + int64_t Hint = getIntValueFromConstOp(Ops[1]); + mlir::Value RW = builder.create( + getLoc(E->getExprLoc()), + cir::IntAttr::get(SInt32Ty, (Hint >> 2) & 0x1)); + mlir::Value Locality = builder.create( + getLoc(E->getExprLoc()), cir::IntAttr::get(SInt32Ty, Hint & 0x3)); + mlir::Value Data = builder.create( + getLoc(E->getExprLoc()), cir::IntAttr::get(SInt32Ty, 1)); + mlir::Type voidTy = cir::VoidType::get(&getMLIRContext()); + + return builder + .create( + getLoc(E->getExprLoc()), builder.getStringAttr("prefetch"), voidTy, + mlir::ValueRange{Address, RW, Locality, Data}) + .getResult(); } case X86::BI_mm_clflush: { mlir::Type voidTy = cir::VoidType::get(&getMLIRContext()); diff --git a/clang/test/CIR/CodeGen/X86/builtins-x86.c b/clang/test/CIR/CodeGen/X86/builtins-x86.c index eeebec717bcd..9c7260adb7a5 100644 --- a/clang/test/CIR/CodeGen/X86/builtins-x86.c +++ b/clang/test/CIR/CodeGen/X86/builtins-x86.c @@ -6,6 +6,14 @@ // This test mimics clang/test/CodeGen/builtins-x86.c, which eventually // CIR shall be able to support fully. +void test_mm_prefetch(char const* p) { + // CIR-LABEL: test_mm_prefetch + // LLVM-LABEL: test_mm_prefetch + _mm_prefetch(p, 0); + // CIR: {{%.*}} = cir.llvm.intrinsic "prefetch" {{%.*}} : (!cir.ptr, !s32i, !s32i, !s32i) -> !void + // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 0, i32 1) +} + void test_mm_clflush(const void* tmp_vCp) { // CIR-LABEL: test_mm_clflush // LLVM-LABEL: test_mm_clflush