Skip to content

Commit c0fb3b0

Browse files
authored
[CIR][CIRGen][Builtin][X86] Lower mm_prefetch (#1675)
Couple of things I have questions about: 1. I duplicated function `getIntValueFromConstOp` from `CIRGenBuiltinAArch64.cpp`. I was wondering if that's correct or if there's a place where we can avoid that duplication. 2. For the tests related to `mm_prefetch` im not sure if it'd be correct to define them in a file eg: `sse-builtins.c` like it's currently done in the codegen lib. 3. I'm also aware we can emit a call for a `PreFetchOp` would that be required in this case? related: #1414, #1404 (A PR was previously opened but It was not resolved)
1 parent d039db9 commit c0fb3b0

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

clang/lib/CIR/CodeGen/CIRGenBuiltinX86.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ translateX86ToMsvcIntrin(unsigned BuiltinID) {
6666
llvm_unreachable("must return from switch");
6767
}
6868

69+
/// Get integer from a mlir::Value that is an int constant or a constant op.
70+
static int64_t getIntValueFromConstOp(mlir::Value val) {
71+
auto constOp = mlir::cast<cir::ConstantOp>(val.getDefiningOp());
72+
return (mlir::cast<cir::IntAttr>(constOp.getValue()))
73+
.getValue()
74+
.getSExtValue();
75+
}
76+
6977
mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID,
7078
const CallExpr *E) {
7179
if (BuiltinID == Builtin::BI__builtin_cpu_is)
@@ -96,7 +104,23 @@ mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned BuiltinID,
96104
default:
97105
return nullptr;
98106
case X86::BI_mm_prefetch: {
99-
llvm_unreachable("_mm_prefetch NYI");
107+
mlir::Value Address = builder.createPtrBitcast(Ops[0], VoidTy);
108+
109+
int64_t Hint = getIntValueFromConstOp(Ops[1]);
110+
mlir::Value RW = builder.create<cir::ConstantOp>(
111+
getLoc(E->getExprLoc()),
112+
cir::IntAttr::get(SInt32Ty, (Hint >> 2) & 0x1));
113+
mlir::Value Locality = builder.create<cir::ConstantOp>(
114+
getLoc(E->getExprLoc()), cir::IntAttr::get(SInt32Ty, Hint & 0x3));
115+
mlir::Value Data = builder.create<cir::ConstantOp>(
116+
getLoc(E->getExprLoc()), cir::IntAttr::get(SInt32Ty, 1));
117+
mlir::Type voidTy = cir::VoidType::get(&getMLIRContext());
118+
119+
return builder
120+
.create<cir::LLVMIntrinsicCallOp>(
121+
getLoc(E->getExprLoc()), builder.getStringAttr("prefetch"), voidTy,
122+
mlir::ValueRange{Address, RW, Locality, Data})
123+
.getResult();
100124
}
101125
case X86::BI_mm_clflush: {
102126
mlir::Type voidTy = cir::VoidType::get(&getMLIRContext());
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// 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
2+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
3+
// 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
4+
// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
5+
6+
// 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
7+
// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
8+
// 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
9+
// RUN: FileCheck --check-prefixes=LLVM --input-file=%t.ll %s
10+
11+
#include <immintrin.h>
12+
13+
14+
void test_mm_prefetch(char const* p) {
15+
// CIR-LABEL: test_mm_prefetch
16+
// LLVM-LABEL: test_mm_prefetch
17+
_mm_prefetch(p, 0);
18+
// CIR: cir.prefetch(%{{.*}} : !cir.ptr<!void>) locality(0) read
19+
// LLVM: call void @llvm.prefetch.p0(ptr {{.*}}, i32 0, i32 0, i32 1)
20+
}

0 commit comments

Comments
 (0)