-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[CIR] Add X86 prefetch builtins #168051
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[CIR] Add X86 prefetch builtins #168051
Changes from all commits
02cf87c
84f845d
fd266d4
30e6801
e8d557f
fd000c8
34a531d
58af624
8e56a36
e8c7671
13d5276
2efbd35
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,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(CIRGenFunction &cgf, const CallExpr *e, | ||
| const std::string &str, | ||
|
|
@@ -33,6 +38,32 @@ static mlir::Value emitIntrinsicCallOp(CIRGenFunction &cgf, const CallExpr *e, | |
| .getResult(); | ||
| } | ||
|
|
||
| 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 {}; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here I'm not sure if this is correct: Can I somehow convert the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I requested this change from the incubator because I thought we should be using CIR-specific operations when we have them, and in this case the CIR operation is exactly equivalent to the LLVM intrinsic. I see that our handling of
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You'd have to add a result to the operation. Incubator has support for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just returning
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is going to work because we return
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I replaced the return type of the caller with |
||
| } | ||
|
|
||
| // OG has unordered comparison as a form of optimization in addition to | ||
| // ordered comparison, while CIR doesn't. | ||
| // | ||
|
|
@@ -68,8 +99,8 @@ static mlir::Value emitVectorFCmp(CIRGenBuilderTy &builder, | |
| return bitCast; | ||
| } | ||
|
|
||
| mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, | ||
| const CallExpr *expr) { | ||
| std::optional<mlir::Value> | ||
| CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr) { | ||
| if (builtinID == Builtin::BI__builtin_cpu_is) { | ||
| cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_is"); | ||
| return {}; | ||
|
|
@@ -120,6 +151,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: | ||
| case X86::BI__builtin_ia32_lzcnt_u16: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.