https://github.com/HendrikHuebner updated https://github.com/llvm/llvm-project/pull/168051
From 047407bde1b792da1c927ffb64f71384e12669bb Mon Sep 17 00:00:00 2001 From: hhuebner <[email protected]> Date: Fri, 19 Dec 2025 22:23:57 +0100 Subject: [PATCH] Prefetch builtin --- clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 35 ++++++++++++++++++ .../test/CIR/CodeGen/X86/prefetchw-builtin.c | 36 +++++++++++++++++++ .../CIR/CodeGenBuiltins/X86/sse-builtins.c | 30 ++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 clang/test/CIR/CodeGen/X86/prefetchw-builtin.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index 1c87e945de846..5122284f87104 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -31,6 +31,11 @@ using namespace clang; using namespace clang::CIRGen; +/// Get integer from a mlir::Value that is an int constant or a constant op. +static int64_t getIntValueFromConstOp(mlir::Value val) { + return val.getDefiningOp<cir::ConstantOp>().getIntValue().getSExtValue(); +} + template <typename... Operands> static mlir::Value emitIntrinsicCallOp(CIRGenBuilderTy &builder, mlir::Location loc, const StringRef str, @@ -158,6 +163,33 @@ computeFullLaneShuffleMask(CIRGenFunction &cgf, const mlir::Value vec, outIndices.resize(numElts); } + +static mlir::Value emitPrefetch(CIRGenFunction &cgf, unsigned builtinID, + const CallExpr *e, + const SmallVector<mlir::Value> &ops) { + CIRGenBuilderTy &builder = cgf.getBuilder(); + mlir::Location location = cgf.getLoc(e->getExprLoc()); + mlir::Type voidTy = builder.getVoidTy(); + mlir::Value address = builder.createPtrBitcast(ops[0], voidTy); + bool isWrite{}; + int locality{}; + + assert(builtinID == X86::BI_mm_prefetch || builtinID == X86::BI_m_prefetchw || + builtinID == X86::BI_m_prefetch && "Expected prefetch builtin"); + + if (builtinID == X86::BI_mm_prefetch) { + int hint = getIntValueFromConstOp(ops[1]); + isWrite = (hint >> 2) & 0x1; + locality = hint & 0x3; + } else { + isWrite = (builtinID == X86::BI_m_prefetchw); + locality = 0x3; + } + + cir::PrefetchOp::create(builder, location, address, locality, isWrite); + return {}; +} + static mlir::Value emitX86CompressExpand(CIRGenBuilderTy &builder, mlir::Location loc, mlir::Value source, mlir::Value mask, @@ -558,6 +590,9 @@ CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) { return emitIntrinsicCallOp(builder, getLoc(expr->getExprLoc()), "x86.sse.sfence", voidTy); case X86::BI_mm_prefetch: + case X86::BI_m_prefetch: + case X86::BI_m_prefetchw: + return emitPrefetch(*this, builtinID, expr, ops); case X86::BI__rdtsc: case X86::BI__builtin_ia32_rdtscp: { cgm.errorNYI(expr->getSourceRange(), diff --git a/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c new file mode 100644 index 0000000000000..7d7ce348b8d88 --- /dev/null +++ b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c @@ -0,0 +1,36 @@ + +// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +sse -fclangir -emit-cir -o %t.cir -Wall -Werror +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +sse -fclangir -emit-llvm -o %t.ll -Wall -Werror +// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s + +// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +sse -fno-signed-char -fclangir -emit-cir -o %t.cir -Wall -Werror +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +sse -fclangir -emit-llvm -o %t.ll -Wall -Werror +// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s + +// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +sse -emit-llvm -o - -Wall -Werror | FileCheck %s -check-prefix=OGCG +// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-unknown-linux -target-feature +sse -emit-llvm -o - -Wall -Werror | FileCheck %s -check-prefix=OGCG + + +#include <x86intrin.h> + +void test_m_prefetch_w(void *p) { + // CIR-LABEL: test_m_prefetch_w + // LLVM-LABEL: test_m_prefetch_w + // OGCG-LABEL: test_m_prefetch_w + return _m_prefetchw(p); + // CIR: cir.prefetch write locality(3) %{{.*}} : !cir.ptr<!void> + // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1) + // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1) +} + +void test_m_prefetch(void *p) { + // CIR-LABEL: test_m_prefetch + // LLVM-LABEL: test_m_prefetch + // OGCG-LABEL: test_m_prefetch + return _m_prefetch(p); + // CIR: cir.prefetch read locality(3) %{{.*}} : !cir.ptr<!void> + // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1) + // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1) +} diff --git a/clang/test/CIR/CodeGenBuiltins/X86/sse-builtins.c b/clang/test/CIR/CodeGenBuiltins/X86/sse-builtins.c index db52021d1aa9f..9d01203aefc7a 100644 --- a/clang/test/CIR/CodeGenBuiltins/X86/sse-builtins.c +++ b/clang/test/CIR/CodeGenBuiltins/X86/sse-builtins.c @@ -56,6 +56,36 @@ void test_mm_sfence(void) { // OGCG: call void @llvm.x86.sse.sfence() } +void test_mm_prefetch(char const* p) { + // CIR-LABEL: test_mm_prefetch + // LLVM-LABEL: test_mm_prefetch + // OGCG-LABEL: test_mm_prefetch + _mm_prefetch(p, 0); + // CIR: cir.prefetch read locality(0) %{{.*}} : !cir.ptr<!void> + // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 0, i32 1) + // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 0, i32 1) +} + +void test_mm_prefetch_local(char const* p) { + // CIR-LABEL: test_mm_prefetch_local + // LLVM-LABEL: test_mm_prefetch_local + // OGCG-LABEL: test_mm_prefetch_local + _mm_prefetch(p, 3); + // CIR: cir.prefetch read locality(3) %{{.*}} : !cir.ptr<!void> + // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1) + // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 3, i32 1) +} + +void test_mm_prefetch_write(char const* p) { + // CIR-LABEL: test_mm_prefetch_write + // LLVM-LABEL: test_mm_prefetch_write + // OGCG-LABEL: test_mm_prefetch_write + _mm_prefetch(p, 7); + // CIR: cir.prefetch write locality(3) %{{.*}} : !cir.ptr<!void> + // LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1) + // OGCG: call void @llvm.prefetch.p0(ptr {{.*}}, i32 1, i32 3, i32 1) +} + __m128 test_mm_undefined_ps(void) { // CIR-LABEL: _mm_undefined_ps // CIR: %[[A:.*]] = cir.const #cir.zero : !cir.vector<2 x !cir.double> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
