https://github.com/HendrikHuebner updated https://github.com/llvm/llvm-project/pull/168051
From 67c3c53a0a2ea68492639cccd120eaba59e1678e Mon Sep 17 00:00:00 2001 From: hhuebner <[email protected]> Date: Tue, 25 Nov 2025 14:07:48 +0100 Subject: [PATCH 1/3] feedback --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 +- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 22 +++++------ clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 39 +++++++++++++++++++ .../test/CIR/CodeGen/X86/prefetchw-builtin.c | 35 +++++++++++++++++ clang/test/CIR/CodeGen/X86/sse-builtins.c | 28 +++++++++++++ 5 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 clang/test/CIR/CodeGen/X86/prefetchw-builtin.c diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index a19c4f951fff9..eb0ab81c26be0 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4431,7 +4431,7 @@ def CIR_PrefetchOp : CIR_Op<"prefetch"> { $locality is a temporal locality specifier ranging from (0) - no locality, to (3) - extremely local, keep in cache. If $locality is not present, the default value is 3. - + $isWrite specifies whether the prefetch is for a 'read' or 'write'. If $isWrite is not specified, it means that prefetch is prepared for 'read'. }]; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index d220fdf4dc8a7..f5c26b2d8507c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1258,10 +1258,11 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, // Now see if we can emit a target-specific builtin. if (mlir::Value v = emitTargetBuiltinExpr(builtinID, e, returnValue)) { + if (mlir::isa<cir::VoidType>(v.getType())) + return RValue::get(nullptr); + switch (evalKind) { case cir::TEK_Scalar: - if (mlir::isa<cir::VoidType>(v.getType())) - return RValue::get(nullptr); return RValue::get(v); case cir::TEK_Aggregate: cgm.errorNYI(e->getSourceRange(), "aggregate return value from builtin"); @@ -1272,9 +1273,6 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, llvm_unreachable("Bad evaluation kind in EmitBuiltinExpr"); } - cgm.errorNYI(e->getSourceRange(), - std::string("unimplemented builtin call: ") + - getContext().BuiltinInfo.getName(builtinID)); return getUndefRValue(e->getType()); } @@ -1303,9 +1301,7 @@ static mlir::Value emitTargetArchBuiltinExpr(CIRGenFunction *cgf, case llvm::Triple::aarch64_be: case llvm::Triple::bpfeb: case llvm::Triple::bpfel: - // These are actually NYI, but that will be reported by emitBuiltinExpr. - // At this point, we don't even know that the builtin is target-specific. - return nullptr; + break; case llvm::Triple::x86: case llvm::Triple::x86_64: @@ -1325,12 +1321,14 @@ static mlir::Value emitTargetArchBuiltinExpr(CIRGenFunction *cgf, case llvm::Triple::hexagon: case llvm::Triple::riscv32: case llvm::Triple::riscv64: - // These are actually NYI, but that will be reported by emitBuiltinExpr. - // At this point, we don't even know that the builtin is target-specific. - return {}; default: - return {}; + break; } + + cgf->cgm.errorNYI(e->getSourceRange(), + "target-specific builtin not implemented on this architecture: " + + cgf->getContext().BuiltinInfo.getName(builtinID)); + return {}; } mlir::Value diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index 978fee7dbec9d..40bccce010b85 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -16,10 +16,16 @@ #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/CIR/MissingFeatures.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" 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(CIRGenFunction &cgf, const CallExpr *e, const std::string &str, @@ -68,6 +74,33 @@ static mlir::Value emitVectorFCmp(CIRGenBuilderTy &builder, return bitCast; } +static mlir::Value emitPrefetch(CIRGenFunction &cgf, unsigned builtinID, + const CallExpr *e, + const llvm::SmallVector<mlir::Value> &ops) { + + assert(builtinID == X86::BI_mm_prefetch || builtinID == X86::BI_m_prefetchw || + builtinID == X86::BI_m_prefetch && "Expected prefetch builtin"); + CIRGenBuilderTy &builder = cgf.getBuilder(); + mlir::Location location = cgf.getLoc(e->getExprLoc()); + mlir::Type voidTy = builder.getVoidTy(); + mlir::Value addr = ops[0]; + mlir::Value address = builder.createPtrBitcast(addr, voidTy); + bool isWrite{}; + int locality{}; + + if (builtinID == X86::BI_mm_prefetch) { + int64_t 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 {}; +} + mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) { if (builtinID == Builtin::BI__builtin_cpu_is) { @@ -108,6 +141,9 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, switch (builtinID) { default: + cgm.errorNYI(expr->getSourceRange(), + std::string("unimplemented X86 builtin call: ") + + getContext().BuiltinInfo.getName(builtinID)); return {}; case X86::BI_mm_clflush: return emitIntrinsicCallOp(*this, expr, "x86.sse2.clflush", voidTy, ops[0]); @@ -120,6 +156,9 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, case X86::BI_mm_sfence: return emitIntrinsicCallOp(*this, expr, "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..78c6b26b5c2a6 --- /dev/null +++ b/clang/test/CIR/CodeGen/X86/prefetchw-builtin.c @@ -0,0 +1,35 @@ +// 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/CodeGen/X86/sse-builtins.c b/clang/test/CIR/CodeGen/X86/sse-builtins.c index c893859b297cc..543dd64cc5ad8 100644 --- a/clang/test/CIR/CodeGen/X86/sse-builtins.c +++ b/clang/test/CIR/CodeGen/X86/sse-builtins.c @@ -71,3 +71,31 @@ __m128 test_mm_undefined_ps(void) { // OGCG: ret <4 x float> zeroinitializer return _mm_undefined_ps(); } + +void test_mm_prefetch(char const* p) { + // CIR-LABEL: test_mm_prefetch + // LLVM-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 + _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) +} From c9229fa1a1a78b558abd85ba0f173fb0b12bbd3b Mon Sep 17 00:00:00 2001 From: hhuebner <[email protected]> Date: Tue, 25 Nov 2025 14:07:58 +0100 Subject: [PATCH 2/3] fmt --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 7 ++++--- clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index f5c26b2d8507c..40750b049d7d9 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1325,9 +1325,10 @@ static mlir::Value emitTargetArchBuiltinExpr(CIRGenFunction *cgf, break; } - cgf->cgm.errorNYI(e->getSourceRange(), - "target-specific builtin not implemented on this architecture: " + - cgf->getContext().BuiltinInfo.getName(builtinID)); + cgf->cgm.errorNYI( + e->getSourceRange(), + "target-specific builtin not implemented on this architecture: " + + cgf->getContext().BuiltinInfo.getName(builtinID)); return {}; } diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp index 40bccce010b85..febcfac822d6b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp @@ -13,10 +13,10 @@ #include "CIRGenFunction.h" #include "CIRGenModule.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/CIR/MissingFeatures.h" -#include "mlir/Dialect/LLVMIR/LLVMDialect.h" using namespace clang; using namespace clang::CIRGen; @@ -158,7 +158,7 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, case X86::BI_mm_prefetch: case X86::BI_m_prefetch: case X86::BI_m_prefetchw: - return emitPrefetch(*this, builtinID, expr, ops); + return emitPrefetch(*this, builtinID, expr, ops); case X86::BI__rdtsc: case X86::BI__builtin_ia32_rdtscp: { cgm.errorNYI(expr->getSourceRange(), From 8ed31b5729e0852ff35b4cc1b86b732acc46eb40 Mon Sep 17 00:00:00 2001 From: hhuebner <[email protected]> Date: Tue, 25 Nov 2025 14:11:17 +0100 Subject: [PATCH 3/3] fix --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 2 +- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index eb0ab81c26be0..a19c4f951fff9 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -4431,7 +4431,7 @@ def CIR_PrefetchOp : CIR_Op<"prefetch"> { $locality is a temporal locality specifier ranging from (0) - no locality, to (3) - extremely local, keep in cache. If $locality is not present, the default value is 3. - + $isWrite specifies whether the prefetch is for a 'read' or 'write'. If $isWrite is not specified, it means that prefetch is prepared for 'read'. }]; diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 40750b049d7d9..56006f40274ec 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1258,11 +1258,10 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, // Now see if we can emit a target-specific builtin. if (mlir::Value v = emitTargetBuiltinExpr(builtinID, e, returnValue)) { - if (mlir::isa<cir::VoidType>(v.getType())) - return RValue::get(nullptr); - switch (evalKind) { case cir::TEK_Scalar: + if (mlir::isa<cir::VoidType>(v.getType())) + return RValue::get(nullptr); return RValue::get(v); case cir::TEK_Aggregate: cgm.errorNYI(e->getSourceRange(), "aggregate return value from builtin"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
